]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for-3.2' into for-3.3
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 28 Nov 2011 22:13:14 +0000 (22:13 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 28 Nov 2011 22:13:14 +0000 (22:13 +0000)
218 files changed:
Documentation/devicetree/bindings/sound/tegra20-das.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/board-mackerel.c
arch/sh/boards/mach-se/7724/setup.c
drivers/base/regmap/internal.h
drivers/base/regmap/regcache.c
drivers/base/regmap/regmap.c
include/linux/regmap.h
include/sound/sh_fsi.h
include/sound/soc-dapm.h
include/sound/soc.h
include/sound/sta32x.h [new file with mode: 0644]
sound/soc/Kconfig
sound/soc/atmel/atmel-pcm.c
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/au1x/ac97c.c
sound/soc/au1x/db1000.c
sound/soc/au1x/db1200.c
sound/soc/au1x/dbdma2.c
sound/soc/au1x/dma.c
sound/soc/au1x/i2sc.c
sound/soc/au1x/psc-ac97.c
sound/soc/au1x/psc-i2s.c
sound/soc/blackfin/bf5xx-ac97-pcm.c
sound/soc/blackfin/bf5xx-ac97.c
sound/soc/blackfin/bf5xx-i2s-pcm.c
sound/soc/blackfin/bf5xx-i2s.c
sound/soc/blackfin/bf5xx-tdm-pcm.c
sound/soc/blackfin/bf5xx-tdm.c
sound/soc/blackfin/bfin-eval-adau1373.c
sound/soc/blackfin/bfin-eval-adau1701.c
sound/soc/blackfin/bfin-eval-adav80x.c
sound/soc/codecs/88pm860x-codec.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ac97.c
sound/soc/codecs/ad1836.c
sound/soc/codecs/ad193x.c
sound/soc/codecs/ad193x.h
sound/soc/codecs/ad1980.c
sound/soc/codecs/ad73311.c
sound/soc/codecs/ads117x.c
sound/soc/codecs/ak4104.c
sound/soc/codecs/ak4535.c
sound/soc/codecs/ak4641.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/ak4671.c
sound/soc/codecs/alc5623.c
sound/soc/codecs/alc5632.c [new file with mode: 0644]
sound/soc/codecs/alc5632.h [new file with mode: 0644]
sound/soc/codecs/cq93vc.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/cs4271.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/cs42l73.c [new file with mode: 0644]
sound/soc/codecs/cs42l73.h [new file with mode: 0644]
sound/soc/codecs/cx20442.c
sound/soc/codecs/da7210.c
sound/soc/codecs/dfbmcs320.c
sound/soc/codecs/dmic.c
sound/soc/codecs/jz4740.c
sound/soc/codecs/max98088.c
sound/soc/codecs/max98095.c
sound/soc/codecs/max9850.c
sound/soc/codecs/pcm3008.c
sound/soc/codecs/rt5631.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sn95031.c
sound/soc/codecs/spdif_transciever.c
sound/soc/codecs/ssm2602.c
sound/soc/codecs/sta32x.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic32x4.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320dac33.c
sound/soc/codecs/twl4030.c
sound/soc/codecs/twl6040.c
sound/soc/codecs/uda134x.c
sound/soc/codecs/uda1380.c
sound/soc/codecs/wl1273.c
sound/soc/codecs/wm1250-ev1.c
sound/soc/codecs/wm2000.c
sound/soc/codecs/wm5100-tables.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm5100.h
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8400.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8523.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8711.c
sound/soc/codecs/wm8727.c
sound/soc/codecs/wm8728.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8737.c
sound/soc/codecs/wm8741.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8770.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8782.c
sound/soc/codecs/wm8804.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8940.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8958-dsp2.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8961.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8971.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm8978.c
sound/soc/codecs/wm8983.c
sound/soc/codecs/wm8985.c
sound/soc/codecs/wm8988.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm8991.c
sound/soc/codecs/wm8993.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8995.c
sound/soc/codecs/wm8996.c
sound/soc/codecs/wm9081.c
sound/soc/codecs/wm9705.c
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/codecs/wm_hubs.c
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-pcm.c
sound/soc/davinci/davinci-vcif.c
sound/soc/ep93xx/edb93xx.c
sound/soc/ep93xx/ep93xx-ac97.c
sound/soc/ep93xx/ep93xx-i2s.c
sound/soc/ep93xx/ep93xx-pcm.c
sound/soc/ep93xx/simone.c
sound/soc/ep93xx/snappercl15.c
sound/soc/fsl/fsl_dma.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/mpc5200_psc_ac97.c
sound/soc/fsl/mpc5200_psc_i2s.c
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-pcm-fiq.c
sound/soc/imx/imx-ssi.c
sound/soc/jz4740/jz4740-i2s.c
sound/soc/jz4740/jz4740-pcm.c
sound/soc/kirkwood/kirkwood-dma.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/mid-x86/mfld_machine.c
sound/soc/mid-x86/sst_platform.c
sound/soc/mxs/mxs-pcm.c
sound/soc/mxs/mxs-saif.c
sound/soc/mxs/mxs-sgtl5000.c
sound/soc/nuc900/nuc900-ac97.c
sound/soc/nuc900/nuc900-pcm.c
sound/soc/omap/Kconfig
sound/soc/omap/Makefile
sound/soc/omap/ams-delta.c
sound/soc/omap/omap-dmic.c [new file with mode: 0644]
sound/soc/omap/omap-dmic.h [new file with mode: 0644]
sound/soc/omap/omap-hdmi.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcpdm.c
sound/soc/omap/omap-pcm.c
sound/soc/omap/omap4-hdmi-card.c
sound/soc/omap/sdp4430.c
sound/soc/pxa/hx4700.c
sound/soc/pxa/mioa701_wm9713.c
sound/soc/pxa/palm27x.c
sound/soc/pxa/pxa-ssp.c
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/s6000/s6000-i2s.c
sound/soc/s6000/s6000-pcm.c
sound/soc/samsung/Kconfig
sound/soc/samsung/Makefile
sound/soc/samsung/ac97.c
sound/soc/samsung/dma.c
sound/soc/samsung/i2s.c
sound/soc/samsung/idma.c
sound/soc/samsung/littlemill.c [new file with mode: 0644]
sound/soc/samsung/lowland.c [new file with mode: 0644]
sound/soc/samsung/pcm.c
sound/soc/samsung/s3c2412-i2s.c
sound/soc/samsung/s3c24xx-i2s.c
sound/soc/samsung/s3c24xx_simtec_hermes.c
sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
sound/soc/samsung/s3c24xx_uda134x.c
sound/soc/samsung/smdk_wm8580pcm.c
sound/soc/samsung/spdif.c
sound/soc/samsung/speyside.c
sound/soc/samsung/speyside_wm8962.c
sound/soc/sh/dma-sh7760.c
sound/soc/sh/fsi-ak4642.c
sound/soc/sh/fsi-hdmi.c
sound/soc/sh/fsi.c
sound/soc/sh/hac.c
sound/soc/sh/siu_dai.c
sound/soc/sh/ssi.c
sound/soc/soc-cache.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-pcm.c
sound/soc/tegra/tegra_das.c
sound/soc/tegra/tegra_i2s.c
sound/soc/tegra/tegra_i2s.h
sound/soc/tegra/tegra_pcm.c
sound/soc/tegra/tegra_spdif.c
sound/soc/tegra/tegra_wm8903.c
sound/soc/tegra/trimslice.c
sound/soc/txx9/txx9aclc-ac97.c
sound/soc/txx9/txx9aclc.c

diff --git a/Documentation/devicetree/bindings/sound/tegra20-das.txt b/Documentation/devicetree/bindings/sound/tegra20-das.txt
new file mode 100644 (file)
index 0000000..6de3a7e
--- /dev/null
@@ -0,0 +1,12 @@
+NVIDIA Tegra 20 DAS (Digital Audio Switch) controller
+
+Required properties:
+- compatible : "nvidia,tegra20-das"
+- reg : Should contain DAS registers location and length
+
+Example:
+
+das@70000c00 {
+       compatible = "nvidia,tegra20-das";
+       reg = <0x70000c00 0x80>;
+};
index e8552782b440af99ed14a6e851e3db5ed47d05fd..2c1b2cb85399ffad456156f82110f898c889d1a5 100644 (file)
@@ -37,4 +37,5 @@ simtek
 sirf   SiRF Technology, Inc.
 stericsson     ST-Ericsson
 ti     Texas Instruments
+wlf    Wolfson Microelectronics
 xlnx   Xilinx
index a3aa0f6df964d19e3ae60877f2d012c2a70b5343..ade98c2d9e8131993b7dade3fa71219031a0f599 100644 (file)
@@ -762,9 +762,22 @@ static struct platform_device fsi_device = {
        },
 };
 
+static struct fsi_ak4642_info fsi2_ak4643_info = {
+       .name           = "AK4643",
+       .card           = "FSI2A-AK4643",
+       .cpu_dai        = "fsia-dai",
+       .codec          = "ak4642-codec.0-0013",
+       .platform       = "sh_fsi2",
+       .id             = FSI_PORT_A,
+};
+
 static struct platform_device fsi_ak4643_device = {
-       .name           = "sh_fsi2_a_ak4643",
+       .name   = "fsi-ak4642-audio",
+       .dev    = {
+               .platform_data  = &fsi_info,
+       },
 };
+
 static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
        .icb[0] = {
                .marker_icb     = 30,
index 9c5e598e0e3d69f1aa5c36d29f7a416f301b38fe..a2908d49a6df56df9cf5cde31dd140ded06b4bdf 100644 (file)
@@ -990,8 +990,20 @@ static struct platform_device fsi_device = {
        },
 };
 
+static struct fsi_ak4642_info fsi2_ak4643_info = {
+       .name           = "AK4643",
+       .card           = "FSI2A-AK4643",
+       .cpu_dai        = "fsia-dai",
+       .codec          = "ak4642-codec.0-0013",
+       .platform       = "sh_fsi2",
+       .id             = FSI_PORT_A,
+};
+
 static struct platform_device fsi_ak4643_device = {
-       .name           = "sh_fsi2_a_ak4643",
+       .name   = "fsi-ak4642-audio",
+       .dev    = {
+               .platform_data  = &fsi2_ak4643_info,
+       },
 };
 
 /*
index b747c0ab9264ac3ed5d1894b8c67f471c7bc852d..b49723b21912c8b9b825eb6c5b197dbb8b675efd 100644 (file)
@@ -315,8 +315,20 @@ static struct platform_device fsi_device = {
        },
 };
 
+static struct fsi_ak4642_info fsi_ak4642_info = {
+       .name           = "AK4642",
+       .card           = "FSIA-AK4642",
+       .cpu_dai        = "fsia-dai",
+       .codec          = "ak4642-codec.0-0012",
+       .platform       = "sh_fsi.0",
+       .id             = FSI_PORT_A,
+};
+
 static struct platform_device fsi_ak4642_device = {
-       .name           = "sh_fsi_a_ak4642",
+       .name   = "fsi-ak4642-audio",
+       .dev    = {
+               .platform_data  = &fsi_ak4642_info,
+       },
 };
 
 /* KEYSC in SoC (Needs SW33-2 set to ON) */
index 348ff02eb93e02a66887b59995900335f7214fc0..6483e0bda0cfb97a48489f13a30e55c36c893e47 100644 (file)
@@ -74,6 +74,7 @@ struct regmap {
        struct reg_default *reg_defaults;
        const void *reg_defaults_raw;
        void *cache;
+       bool cache_dirty;
 };
 
 struct regcache_ops {
index 666f6f5011dc85339287f9b982f991e22081626b..6ab9f0384d82c3fa82f6c575d45dac31d4b305ca 100644 (file)
@@ -241,6 +241,8 @@ int regcache_sync(struct regmap *map)
                map->cache_ops->name);
        name = map->cache_ops->name;
        trace_regcache_sync(map->dev, name, "start");
+       if (!map->cache_dirty)
+               goto out;
        if (map->cache_ops->sync) {
                ret = map->cache_ops->sync(map);
        } else {
@@ -290,6 +292,23 @@ void regcache_cache_only(struct regmap *map, bool enable)
 }
 EXPORT_SYMBOL_GPL(regcache_cache_only);
 
+/**
+ * regcache_mark_dirty: Mark the register cache as dirty
+ *
+ * @map: map to mark
+ *
+ * Mark the register cache as dirty, for example due to the device
+ * having been powered down for suspend.  If the cache is not marked
+ * as dirty then the cache sync will be suppressed.
+ */
+void regcache_mark_dirty(struct regmap *map)
+{
+       mutex_lock(&map->lock);
+       map->cache_dirty = true;
+       mutex_unlock(&map->lock);
+}
+EXPORT_SYMBOL_GPL(regcache_mark_dirty);
+
 /**
  * regcache_cache_bypass: Put a register map into cache bypass mode
  *
index bf441db1ee90af507ac3597e6a32dd1a3cbfec10..3aca18dbf367389c4e35cac5c38b47d943ee24e4 100644 (file)
@@ -306,8 +306,10 @@ int _regmap_write(struct regmap *map, unsigned int reg,
                ret = regcache_write(map, reg, val);
                if (ret != 0)
                        return ret;
-               if (map->cache_only)
+               if (map->cache_only) {
+                       map->cache_dirty = true;
                        return 0;
+               }
        }
 
        trace_regmap_reg_write(map->dev, reg, val);
index 690276a642cf75dd5dbfcd1d620b8a94880714fc..32043a9749e68def3b7486eeb5ef15232d6d299e 100644 (file)
@@ -143,5 +143,6 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
 int regcache_sync(struct regmap *map);
 void regcache_cache_only(struct regmap *map, bool enable);
 void regcache_cache_bypass(struct regmap *map, bool enable);
+void regcache_mark_dirty(struct regmap *map);
 
 #endif
index 9a155f9d0a12a627f968821d25f890cb71efc403..9b1aacaa82fedd0fcb63365fae33237627c496c9 100644 (file)
@@ -78,4 +78,16 @@ struct sh_fsi_platform_info {
        int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
 };
 
+/*
+ * for fsi-ak4642
+ */
+struct fsi_ak4642_info {
+       const char *name;
+       const char *card;
+       const char *cpu_dai;
+       const char *codec;
+       const char *platform;
+       int id;
+};
+
 #endif /* __SOUND_FSI_H */
index 17a4c17f19f5ff672030d448bb84ea5b3d8a354a..0c159a7d211e78b8d3b765dbb174ce8384cb71f8 100644 (file)
@@ -380,6 +380,7 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
                                  const char *pin);
 int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
                                const char *pin);
+void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);
 
 /* Mostly internal - should not normally be used */
 void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason);
index 11cfb5953e06eb82c22f52319aa2c4ea31d7f99a..737a4f4b18ff725c52b1e3c6587dab3b3e90c69f 100644 (file)
@@ -266,7 +266,6 @@ enum snd_soc_control_type {
 
 enum snd_soc_compress_type {
        SND_SOC_FLAT_COMPRESSION = 1,
-       SND_SOC_LZO_COMPRESSION,
        SND_SOC_RBTREE_COMPRESSION
 };
 
@@ -718,6 +717,9 @@ struct snd_soc_dai_link {
        /* Symmetry requirements */
        unsigned int symmetric_rates:1;
 
+       /* pmdown_time is ignored at stop */
+       unsigned int ignore_pmdown_time:1;
+
        /* codec/machine specific init - e.g. add machine controls */
        int (*init)(struct snd_soc_pcm_runtime *rtd);
 
@@ -813,6 +815,7 @@ struct snd_soc_card {
        int num_dapm_widgets;
        const struct snd_soc_dapm_route *dapm_routes;
        int num_dapm_routes;
+       bool fully_routed;
 
        struct work_struct deferred_resume_work;
 
@@ -840,7 +843,7 @@ struct snd_soc_card {
 };
 
 /* SoC machine DAI configuration, glues a codec and cpu DAI together */
-struct snd_soc_pcm_runtime  {
+struct snd_soc_pcm_runtime {
        struct device dev;
        struct snd_soc_card *card;
        struct snd_soc_dai_link *dai_link;
diff --git a/include/sound/sta32x.h b/include/sound/sta32x.h
new file mode 100644 (file)
index 0000000..8d93b03
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Platform data for ST STA32x ASoC codec driver.
+ *
+ * Copyright: 2011 Raumfeld GmbH
+ * Author: Johannes Stezenbach <js@sig21.net>
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#ifndef __LINUX_SND__STA32X_H
+#define __LINUX_SND__STA32X_H
+
+#define STA32X_OCFG_2CH                0
+#define STA32X_OCFG_2_1CH      1
+#define STA32X_OCFG_1CH                3
+
+#define STA32X_OM_CH1          0
+#define STA32X_OM_CH2          1
+#define STA32X_OM_CH3          2
+
+#define STA32X_THERMAL_ADJUSTMENT_ENABLE       1
+#define STA32X_THERMAL_RECOVERY_ENABLE         2
+
+struct sta32x_platform_data {
+       int output_conf;
+       int ch1_output_mapping;
+       int ch2_output_mapping;
+       int ch3_output_mapping;
+       int thermal_conf;
+       int needs_esd_watchdog;
+};
+
+#endif /* __LINUX_SND__STA32X_H */
index 1381db853ef0f8b5d875c6ba220de0f90476add5..35e662d270e6141338669051a784c06a3fe9fbea 100644 (file)
@@ -22,21 +22,6 @@ menuconfig SND_SOC
 
 if SND_SOC
 
-config SND_SOC_CACHE_LZO
-       bool "Support LZO compression for register caches"
-       select LZO_COMPRESS
-       select LZO_DECOMPRESS
-       ---help---
-          Select this to enable LZO compression for register caches.
-          This will allow machine or CODEC drivers to compress register
-          caches in memory, reducing the memory consumption at the
-          expense of performance.  If this is not present and is used
-          the system will fall back to uncompressed caches.
-
-          Usually it is safe to disable this option, where cache
-          compression in used the rbtree option will typically perform
-          better.
-
 config SND_SOC_AC97_BUS
        bool
 
index f81d4c3f8956efa24d4becf3952b6242554a0866..60de05525c06f0d6d676ae2d062acfa890762655 100644 (file)
@@ -495,17 +495,7 @@ static struct platform_driver atmel_pcm_driver = {
        .remove = __devexit_p(atmel_soc_platform_remove),
 };
 
-static int __init snd_atmel_pcm_init(void)
-{
-       return platform_driver_register(&atmel_pcm_driver);
-}
-module_init(snd_atmel_pcm_init);
-
-static void __exit snd_atmel_pcm_exit(void)
-{
-       platform_driver_unregister(&atmel_pcm_driver);
-}
-module_exit(snd_atmel_pcm_exit);
+module_platform_driver(atmel_pcm_driver);
 
 MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
 MODULE_DESCRIPTION("Atmel PCM module");
index 71225090c49fc424a7ea1f6c0f2b5168e79480ba..354341ec0f42f1129adbaaf310366af46b866229 100644 (file)
@@ -719,7 +719,7 @@ static int atmel_ssc_remove(struct snd_soc_dai *dai)
 #define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_LE |\
                          SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
+static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
        .startup        = atmel_ssc_startup,
        .shutdown       = atmel_ssc_shutdown,
        .prepare        = atmel_ssc_prepare,
@@ -859,17 +859,7 @@ int atmel_ssc_set_audio(int ssc_id)
 }
 EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
 
-static int __init snd_atmel_ssc_init(void)
-{
-       return platform_driver_register(&asoc_ssc_driver);
-}
-module_init(snd_atmel_ssc_init);
-
-static void __exit snd_atmel_ssc_exit(void)
-{
-       platform_driver_unregister(&asoc_ssc_driver);
-}
-module_exit(snd_atmel_ssc_exit);
+module_platform_driver(asoc_ssc_driver);
 
 /* Module information */
 MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
index 726bd651a105970053a726cdee18012ea96a508b..7771934b93e29af95448143c32cc9a9b933e0ea5 100644 (file)
@@ -195,7 +195,7 @@ static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops alchemy_ac97c_ops = {
+static const struct snd_soc_dai_ops alchemy_ac97c_ops = {
        .startup                = alchemy_ac97c_startup,
 };
 
index 127477a5e0c775ad8778eaf0fba722f161ce8697..094a20723bc6dba62ff60233a72afaa588fba9c1 100644 (file)
@@ -57,18 +57,7 @@ static struct platform_driver db1000_audio_driver = {
        .remove         = __devexit_p(db1000_audio_remove),
 };
 
-static int __init db1000_audio_load(void)
-{
-       return platform_driver_register(&db1000_audio_driver);
-}
-
-static void __exit db1000_audio_unload(void)
-{
-       platform_driver_unregister(&db1000_audio_driver);
-}
-
-module_init(db1000_audio_load);
-module_exit(db1000_audio_unload);
+module_platform_driver(db1000_audio_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio");
index 289312c14b99bf62d13355e7ae5e585bf297991f..80733331733fb103ef37d112b73bbb87310b1a2b 100644 (file)
@@ -133,18 +133,7 @@ static struct platform_driver db1200_audio_driver = {
        .remove         = __devexit_p(db1200_audio_remove),
 };
 
-static int __init db1200_audio_load(void)
-{
-       return platform_driver_register(&db1200_audio_driver);
-}
-
-static void __exit db1200_audio_unload(void)
-{
-       platform_driver_unregister(&db1200_audio_driver);
-}
-
-module_init(db1200_audio_load);
-module_exit(db1200_audio_unload);
+module_platform_driver(db1200_audio_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("DB1200 ASoC audio support");
index d7d04e26eee504524f7952c86825b44c5d7a4fa7..09699de9b33760813fcbae541d271ad3fa2a5342 100644 (file)
@@ -384,18 +384,7 @@ static struct platform_driver au1xpsc_pcm_driver = {
        .remove         = __devexit_p(au1xpsc_pcm_drvremove),
 };
 
-static int __init au1xpsc_audio_dbdma_load(void)
-{
-       return platform_driver_register(&au1xpsc_pcm_driver);
-}
-
-static void __exit au1xpsc_audio_dbdma_unload(void)
-{
-       platform_driver_unregister(&au1xpsc_pcm_driver);
-}
-
-module_init(au1xpsc_audio_dbdma_load);
-module_exit(au1xpsc_audio_dbdma_unload);
+module_platform_driver(au1xpsc_pcm_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
index 177f7137a9c80e358aa4c6913cfafce00585e11d..dc4dae48aed951b41b1af0554baed69d6824c7f9 100644 (file)
@@ -359,18 +359,7 @@ static struct platform_driver alchemy_pcmdma_driver = {
        .remove         = __devexit_p(alchemy_pcm_drvremove),
 };
 
-static int __init alchemy_pcmdma_load(void)
-{
-       return platform_driver_register(&alchemy_pcmdma_driver);
-}
-
-static void __exit alchemy_pcmdma_unload(void)
-{
-       platform_driver_unregister(&alchemy_pcmdma_driver);
-}
-
-module_init(alchemy_pcmdma_load);
-module_exit(alchemy_pcmdma_unload);
+module_platform_driver(alchemy_pcmdma_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver");
index 6bcf48f5884c169b0a5d61004bb91f7652647b35..cb53ad87d0a99a71a25e2af85ba2457939484ae0 100644 (file)
@@ -331,18 +331,7 @@ static struct platform_driver au1xi2s_driver = {
        .remove         = __devexit_p(au1xi2s_drvremove),
 };
 
-static int __init au1xi2s_load(void)
-{
-       return platform_driver_register(&au1xi2s_driver);
-}
-
-static void __exit au1xi2s_unload(void)
-{
-       platform_driver_unregister(&au1xi2s_driver);
-}
-
-module_init(au1xi2s_load);
-module_exit(au1xi2s_unload);
+module_platform_driver(au1xi2s_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
index 0c6acd54714100b09401fac0278f4b412821f0b9..87daf456b1c9e6fffdc1eca455944d6487e4af36 100644 (file)
@@ -337,7 +337,7 @@ static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
        return au1xpsc_ac97_workdata ? 0 : -ENODEV;
 }
 
-static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
+static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
        .startup        = au1xpsc_ac97_startup,
        .trigger        = au1xpsc_ac97_trigger,
        .hw_params      = au1xpsc_ac97_hw_params,
index e03c5ce01b304ef680e1790f4fd9c39d1313483d..5c1dc8a141abed9881a09d643b2181994340a319 100644 (file)
@@ -265,7 +265,7 @@ static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
+static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
        .startup        = au1xpsc_i2s_startup,
        .trigger        = au1xpsc_i2s_trigger,
        .hw_params      = au1xpsc_i2s_hw_params,
@@ -435,18 +435,7 @@ static struct platform_driver au1xpsc_i2s_driver = {
        .remove         = __devexit_p(au1xpsc_i2s_drvremove),
 };
 
-static int __init au1xpsc_i2s_load(void)
-{
-       return platform_driver_register(&au1xpsc_i2s_driver);
-}
-
-static void __exit au1xpsc_i2s_unload(void)
-{
-       platform_driver_unregister(&au1xpsc_i2s_driver);
-}
-
-module_init(au1xpsc_i2s_load);
-module_exit(au1xpsc_i2s_unload);
+module_platform_driver(au1xpsc_i2s_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
index 56815c1d47b3fdb36f278e05894fc54a6ace93d7..fcff58390848d0d6d497a76748b200c1e09e1b8b 100644 (file)
@@ -475,17 +475,7 @@ static struct platform_driver bf5xx_pcm_driver = {
        .remove = __devexit_p(bf5xx_soc_platform_remove),
 };
 
-static int __init snd_bf5xx_pcm_init(void)
-{
-       return platform_driver_register(&bf5xx_pcm_driver);
-}
-module_init(snd_bf5xx_pcm_init);
-
-static void __exit snd_bf5xx_pcm_exit(void)
-{
-       platform_driver_unregister(&bf5xx_pcm_driver);
-}
-module_exit(snd_bf5xx_pcm_exit);
+module_platform_driver(bf5xx_pcm_driver);
 
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
index 6d216259088935633c598bb72d0ce516fc31df96..f4e9dc4e262e6c63a6a5e1cf318c4b58cab3b431 100644 (file)
@@ -375,18 +375,7 @@ static struct platform_driver asoc_bfin_ac97_driver = {
        .remove = __devexit_p(asoc_bfin_ac97_remove),
 };
 
-static int __init bfin_ac97_init(void)
-{
-       return platform_driver_register(&asoc_bfin_ac97_driver);
-}
-module_init(bfin_ac97_init);
-
-static void __exit bfin_ac97_exit(void)
-{
-       platform_driver_unregister(&asoc_bfin_ac97_driver);
-}
-module_exit(bfin_ac97_exit);
-
+module_platform_driver(asoc_bfin_ac97_driver);
 
 MODULE_AUTHOR("Roy Huang");
 MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
index 7565e1576ffa47a04ab165423cda019eb53c7375..6ec3d41b9b6d2f712830a202a08210da4a886f79 100644 (file)
@@ -314,17 +314,7 @@ static struct platform_driver bfin_i2s_pcm_driver = {
        .remove = __devexit_p(bfin_i2s_soc_platform_remove),
 };
 
-static int __init snd_bfin_i2s_pcm_init(void)
-{
-       return platform_driver_register(&bfin_i2s_pcm_driver);
-}
-module_init(snd_bfin_i2s_pcm_init);
-
-static void __exit snd_bfin_i2s_pcm_exit(void)
-{
-       platform_driver_unregister(&bfin_i2s_pcm_driver);
-}
-module_exit(snd_bfin_i2s_pcm_exit);
+module_platform_driver(bfin_i2s_pcm_driver);
 
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
index 00cc3e00b2fead767ca60cbc54e603b3521f960a..4dccf0374fe744fd54aaf379caf92e3eec5feda6 100644 (file)
@@ -223,7 +223,7 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
         SNDRV_PCM_FMTBIT_S24_LE | \
         SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
        .shutdown       = bf5xx_i2s_shutdown,
        .hw_params      = bf5xx_i2s_hw_params,
        .set_fmt        = bf5xx_i2s_set_dai_fmt,
@@ -288,18 +288,7 @@ static struct platform_driver bfin_i2s_driver = {
        },
 };
 
-static int __init bfin_i2s_init(void)
-{
-       return platform_driver_register(&bfin_i2s_driver);
-}
-
-static void __exit bfin_i2s_exit(void)
-{
-       platform_driver_unregister(&bfin_i2s_driver);
-}
-
-module_init(bfin_i2s_init);
-module_exit(bfin_i2s_exit);
+module_platform_driver(bfin_i2s_driver);
 
 /* Module information */
 MODULE_AUTHOR("Cliff Cai");
index c95cc03d583dd747a80477fd54b9137dc9bccb61..4406f9a865aedfbe5bf55339e3f9c1a10699d1ab 100644 (file)
@@ -339,17 +339,7 @@ static struct platform_driver bfin_tdm_driver = {
        .remove = __devexit_p(bf5xx_soc_platform_remove),
 };
 
-static int __init snd_bfin_tdm_init(void)
-{
-       return platform_driver_register(&bfin_tdm_driver);
-}
-module_init(snd_bfin_tdm_init);
-
-static void __exit snd_bfin_tdm_exit(void)
-{
-       platform_driver_unregister(&bfin_tdm_driver);
-}
-module_exit(snd_bfin_tdm_exit);
+module_platform_driver(bfin_tdm_driver);
 
 MODULE_AUTHOR("Barry Song");
 MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
index a822d1ee1380057db79148c265785e933616d1b2..594f88217c746e0f8639988b9851c105e2f5c0e5 100644 (file)
@@ -226,7 +226,7 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
 #define bf5xx_tdm_resume       NULL
 #endif
 
-static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
+static const struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
        .hw_params      = bf5xx_tdm_hw_params,
        .set_fmt        = bf5xx_tdm_set_dai_fmt,
        .shutdown       = bf5xx_tdm_shutdown,
@@ -314,17 +314,7 @@ static struct platform_driver bfin_tdm_driver = {
        },
 };
 
-static int __init bfin_tdm_init(void)
-{
-       return platform_driver_register(&bfin_tdm_driver);
-}
-module_init(bfin_tdm_init);
-
-static void __exit bfin_tdm_exit(void)
-{
-       platform_driver_unregister(&bfin_tdm_driver);
-}
-module_exit(bfin_tdm_exit);
+module_platform_driver(bfin_tdm_driver);
 
 /* Module information */
 MODULE_AUTHOR("Barry Song");
index 8df2a3b0cb3613d9bb1bdc2a2e918f5e5c7b3528..85ed39abe10eb2c41eedef391705edef5519b52d 100644 (file)
@@ -184,17 +184,7 @@ static struct platform_driver bfin_eval_adau1373_driver = {
        .remove = __devexit_p(bfin_eval_adau1373_remove),
 };
 
-static int __init bfin_eval_adau1373_init(void)
-{
-       return platform_driver_register(&bfin_eval_adau1373_driver);
-}
-module_init(bfin_eval_adau1373_init);
-
-static void __exit bfin_eval_adau1373_exit(void)
-{
-       platform_driver_unregister(&bfin_eval_adau1373_driver);
-}
-module_exit(bfin_eval_adau1373_exit);
+module_platform_driver(bfin_eval_adau1373_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver");
index e5550acba2c2c1614dc14a8d738fef611214f508..1a88fe9ce34ce22a0a586784655298d4aaaf7dd4 100644 (file)
@@ -121,17 +121,7 @@ static struct platform_driver bfin_eval_adau1701_driver = {
        .remove = __devexit_p(bfin_eval_adau1701_remove),
 };
 
-static int __init bfin_eval_adau1701_init(void)
-{
-       return platform_driver_register(&bfin_eval_adau1701_driver);
-}
-module_init(bfin_eval_adau1701_init);
-
-static void __exit bfin_eval_adau1701_exit(void)
-{
-       platform_driver_unregister(&bfin_eval_adau1701_driver);
-}
-module_exit(bfin_eval_adau1701_exit);
+module_platform_driver(bfin_eval_adau1701_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver");
index 897cfa68a2a668789b8844c00167b51eb1a12887..0bc995fb6283a6e22f18aa3542059793525c9175 100644 (file)
@@ -157,17 +157,7 @@ static struct platform_driver bfin_eval_adav80x_driver = {
        .id_table = bfin_eval_adav80x_ids,
 };
 
-static int __init bfin_eval_adav80x_init(void)
-{
-       return platform_driver_register(&bfin_eval_adav80x_driver);
-}
-module_init(bfin_eval_adav80x_init);
-
-static void __exit bfin_eval_adav80x_exit(void)
-{
-       platform_driver_unregister(&bfin_eval_adav80x_driver);
-}
-module_exit(bfin_eval_adav80x_exit);
+module_platform_driver(bfin_eval_adav80x_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver");
index 5ca122e51183a4531c612613c0bbf6c94da9f272..2d39123dd21a990576ca4b2b37d6ff0d438ad075 100644 (file)
@@ -1198,14 +1198,14 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
+static const struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
        .digital_mute   = pm860x_digital_mute,
        .hw_params      = pm860x_pcm_hw_params,
        .set_fmt        = pm860x_pcm_set_dai_fmt,
        .set_sysclk     = pm860x_set_dai_sysclk,
 };
 
-static struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
+static const struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
        .digital_mute   = pm860x_digital_mute,
        .hw_params      = pm860x_i2s_hw_params,
        .set_fmt        = pm860x_i2s_set_dai_fmt,
@@ -1481,17 +1481,7 @@ static struct platform_driver pm860x_codec_driver = {
        .remove = __devexit_p(pm860x_codec_remove),
 };
 
-static __init int pm860x_init(void)
-{
-       return platform_driver_register(&pm860x_codec_driver);
-}
-module_init(pm860x_init);
-
-static __exit void pm860x_exit(void)
-{
-       platform_driver_unregister(&pm860x_codec_driver);
-}
-module_exit(pm860x_exit);
+module_platform_driver(pm860x_codec_driver);
 
 MODULE_DESCRIPTION("ASoC 88PM860x driver");
 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
index 4584514d93d4fd21a92de37847d318951e824bf8..686f45a07f34a0e80b255fc5a34c0c8aed1fe3b6 100644 (file)
@@ -26,8 +26,10 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_AK4642 if I2C
        select SND_SOC_AK4671 if I2C
        select SND_SOC_ALC5623 if I2C
+       select SND_SOC_ALC5632 if I2C
        select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
        select SND_SOC_CS42L51 if I2C
+       select SND_SOC_CS42L73 if I2C
        select SND_SOC_CS4270 if I2C
        select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
        select SND_SOC_CX20442
@@ -168,6 +170,8 @@ config SND_SOC_AK4671
 
 config SND_SOC_ALC5623
        tristate
+config SND_SOC_ALC5632
+       tristate
 
 config SND_SOC_CQ0093VC
        tristate
@@ -175,6 +179,9 @@ config SND_SOC_CQ0093VC
 config SND_SOC_CS42L51
        tristate
 
+config SND_SOC_CS42L73
+       tristate
+
 # Cirrus Logic CS4270 Codec
 config SND_SOC_CS4270
        tristate
index a2c7842e357b6c3aa899a9e93155bed9855c2bbf..62b01e4e7983f8d1307daa06e615852e24913bb8 100644 (file)
@@ -15,13 +15,16 @@ snd-soc-ak4642-objs := ak4642.o
 snd-soc-ak4671-objs := ak4671.o
 snd-soc-cq93vc-objs := cq93vc.o
 snd-soc-cs42l51-objs := cs42l51.o
+snd-soc-cs42l73-objs := cs42l73.o
 snd-soc-cs4270-objs := cs4270.o
 snd-soc-cs4271-objs := cs4271.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
 snd-soc-dfbmcs320-objs := dfbmcs320.o
 snd-soc-dmic-objs := dmic.o
+snd-soc-jz4740-codec-objs := jz4740.o
 snd-soc-l3-objs := l3.o
+snd-soc-lm4857-objs := lm4857.o
 snd-soc-max98088-objs := max98088.o
 snd-soc-max98095-objs := max98095.o
 snd-soc-max9850-objs := max9850.o
@@ -29,6 +32,7 @@ snd-soc-pcm3008-objs := pcm3008.o
 snd-soc-rt5631-objs := rt5631.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
+snd-soc-alc5632-objs := alc5632.o
 snd-soc-sn95031-objs := sn95031.o
 snd-soc-spdif-objs := spdif_transciever.o
 snd-soc-ssm2602-objs := ssm2602.o
@@ -88,10 +92,8 @@ snd-soc-wm9705-objs := wm9705.o
 snd-soc-wm9712-objs := wm9712.o
 snd-soc-wm9713-objs := wm9713.o
 snd-soc-wm-hubs-objs := wm_hubs.o
-snd-soc-jz4740-codec-objs := jz4740.o
 
 # Amp
-snd-soc-lm4857-objs := lm4857.o
 snd-soc-max9877-objs := max9877.o
 snd-soc-tpa6130a2-objs := tpa6130a2.o
 snd-soc-wm2000-objs := wm2000.o
@@ -113,8 +115,10 @@ obj-$(CONFIG_SND_SOC_AK4641)       += snd-soc-ak4641.o
 obj-$(CONFIG_SND_SOC_AK4642)   += snd-soc-ak4642.o
 obj-$(CONFIG_SND_SOC_AK4671)   += snd-soc-ak4671.o
 obj-$(CONFIG_SND_SOC_ALC5623)    += snd-soc-alc5623.o
+obj-$(CONFIG_SND_SOC_ALC5632)  += snd-soc-alc5632.o
 obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
 obj-$(CONFIG_SND_SOC_CS42L51)  += snd-soc-cs42l51.o
+obj-$(CONFIG_SND_SOC_CS42L73)  += snd-soc-cs42l73.o
 obj-$(CONFIG_SND_SOC_CS4270)   += snd-soc-cs4270.o
 obj-$(CONFIG_SND_SOC_CS4271)   += snd-soc-cs4271.o
 obj-$(CONFIG_SND_SOC_CX20442)  += snd-soc-cx20442.o
@@ -122,6 +126,7 @@ obj-$(CONFIG_SND_SOC_DA7210)        += snd-soc-da7210.o
 obj-$(CONFIG_SND_SOC_DFBMCS320)        += snd-soc-dfbmcs320.o
 obj-$(CONFIG_SND_SOC_DMIC)     += snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_L3)       += snd-soc-l3.o
+obj-$(CONFIG_SND_SOC_LM4857)   += snd-soc-lm4857.o
 obj-$(CONFIG_SND_SOC_JZ4740_CODEC)     += snd-soc-jz4740-codec.o
 obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
 obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
@@ -190,7 +195,6 @@ obj-$(CONFIG_SND_SOC_WM9713)        += snd-soc-wm9713.o
 obj-$(CONFIG_SND_SOC_WM_HUBS)  += snd-soc-wm-hubs.o
 
 # Amp
-obj-$(CONFIG_SND_SOC_LM4857)   += snd-soc-lm4857.o
 obj-$(CONFIG_SND_SOC_MAX9877)  += snd-soc-max9877.o
 obj-$(CONFIG_SND_SOC_TPA6130A2)        += snd-soc-tpa6130a2.o
 obj-$(CONFIG_SND_SOC_WM2000)   += snd-soc-wm2000.o
index e715186b430064a33c939b9863da91f734e2af54..221ec29f68e38361cb073ff0c975de51f47e7762 100644 (file)
@@ -39,7 +39,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
                SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
                SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_dai_ops ac97_dai_ops = {
+static const struct snd_soc_dai_ops ac97_dai_ops = {
        .prepare        = ac97_prepare,
 };
 
@@ -148,17 +148,7 @@ static struct platform_driver ac97_codec_driver = {
        .remove = __devexit_p(ac97_remove),
 };
 
-static int __init ac97_init(void)
-{
-       return platform_driver_register(&ac97_codec_driver);
-}
-module_init(ac97_init);
-
-static void __exit ac97_exit(void)
-{
-       platform_driver_unregister(&ac97_codec_driver);
-}
-module_exit(ac97_exit);
+module_platform_driver(ac97_codec_driver);
 
 MODULE_DESCRIPTION("Soc Generic AC97 driver");
 MODULE_AUTHOR("Liam Girdwood");
index 4e5c5726366b12f4f2377e15da2bdea4598e6e98..fab0948f7a548cc23a9bb3e44ae2d63c59ded5e4 100644 (file)
@@ -189,7 +189,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops ad1836_dai_ops = {
+static const struct snd_soc_dai_ops ad1836_dai_ops = {
        .hw_params = ad1836_hw_params,
        .set_fmt = ad1836_set_dai_fmt,
 };
index 120602130b5c0a667cc612ab97877d016bb5a667..c1b7d928c347c70943bc213f74c842983ab88931 100644 (file)
@@ -30,21 +30,23 @@ struct ad193x_priv {
 /*
  * AD193X volume/mute/de-emphasis etc. controls
  */
-static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
+static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
 
 static const struct soc_enum ad193x_deemp_enum =
        SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp);
 
+static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
+
 static const struct snd_kcontrol_new ad193x_snd_controls[] = {
        /* DAC volume control */
-       SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL,
-                       AD193X_DAC_R1_VOL, 0, 0xFF, 1),
-       SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL,
-                       AD193X_DAC_R2_VOL, 0, 0xFF, 1),
-       SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL,
-                       AD193X_DAC_R3_VOL, 0, 0xFF, 1),
-       SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL,
-                       AD193X_DAC_R4_VOL, 0, 0xFF, 1),
+       SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
+                       AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL,
+                       AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv),
+       SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL,
+                       AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv),
+       SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
+                       AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
 
        /* ADC switch control */
        SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
@@ -75,6 +77,7 @@ static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
        SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
        SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
        SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
        SND_SOC_DAPM_OUTPUT("DAC1OUT"),
        SND_SOC_DAPM_OUTPUT("DAC2OUT"),
        SND_SOC_DAPM_OUTPUT("DAC3OUT"),
@@ -84,16 +87,17 @@ static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route audio_paths[] = {
-       { "DAC", NULL, "PLL_PWR" },
-       { "ADC", NULL, "PLL_PWR" },
+       { "DAC", NULL, "SYSCLK" },
+       { "ADC", NULL, "SYSCLK" },
        { "DAC", NULL, "ADC_PWR" },
        { "ADC", NULL, "ADC_PWR" },
-       { "DAC1OUT", "DAC1 Switch", "DAC" },
-       { "DAC2OUT", "DAC2 Switch", "DAC" },
-       { "DAC3OUT", "DAC3 Switch", "DAC" },
-       { "DAC4OUT", "DAC4 Switch", "DAC" },
-       { "ADC", "ADC1 Switch", "ADC1IN" },
-       { "ADC", "ADC2 Switch", "ADC2IN" },
+       { "DAC1OUT", NULL, "DAC" },
+       { "DAC2OUT", NULL, "DAC" },
+       { "DAC3OUT", NULL, "DAC" },
+       { "DAC4OUT", NULL, "DAC" },
+       { "ADC", NULL, "ADC1IN" },
+       { "ADC", NULL, "ADC2IN" },
+       { "SYSCLK", NULL, "PLL_PWR" },
 };
 
 /*
@@ -102,14 +106,14 @@ static const struct snd_soc_dapm_route audio_paths[] = {
 
 static int ad193x_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
 
        if (mute)
-               snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
+               regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
                                    AD193X_DAC_MASTER_MUTE,
                                    AD193X_DAC_MASTER_MUTE);
        else
-               snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
+               regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
                                    AD193X_DAC_MASTER_MUTE, 0);
 
        return 0;
@@ -118,36 +122,30 @@ static int ad193x_mute(struct snd_soc_dai *dai, int mute)
 static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                               unsigned int rx_mask, int slots, int width)
 {
-       struct snd_soc_codec *codec = dai->codec;
-       int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
-       int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2);
-
-       dac_reg &= ~AD193X_DAC_CHAN_MASK;
-       adc_reg &= ~AD193X_ADC_CHAN_MASK;
+       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec);
+       unsigned int channels;
 
        switch (slots) {
        case 2:
-               dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT;
-               adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT;
+               channels = AD193X_2_CHANNELS;
                break;
        case 4:
-               dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT;
-               adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT;
+               channels = AD193X_4_CHANNELS;
                break;
        case 8:
-               dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT;
-               adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT;
+               channels = AD193X_8_CHANNELS;
                break;
        case 16:
-               dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT;
-               adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT;
+               channels = AD193X_16_CHANNELS;
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
-       snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg);
+       regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
+               AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
+       regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
+               AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT);
 
        return 0;
 }
@@ -155,24 +153,20 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       int adc_reg1, adc_reg2, dac_reg;
-
-       adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1);
-       adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2);
-       dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
+       struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec);
+       unsigned int adc_serfmt = 0;
+       unsigned int adc_fmt = 0;
+       unsigned int dac_fmt = 0;
 
        /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
         * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
         */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-               adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
-               adc_reg1 |= AD193X_ADC_SERFMT_TDM;
+               adc_serfmt |= AD193X_ADC_SERFMT_TDM;
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
-               adc_reg1 |= AD193X_ADC_SERFMT_AUX;
+               adc_serfmt |= AD193X_ADC_SERFMT_AUX;
                break;
        default:
                return -EINVAL;
@@ -180,29 +174,20 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
-               adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
-               adc_reg2 &= ~AD193X_ADC_BCLK_INV;
-               dac_reg &= ~AD193X_DAC_LEFT_HIGH;
-               dac_reg &= ~AD193X_DAC_BCLK_INV;
                break;
        case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
-               adc_reg2 |= AD193X_ADC_LEFT_HIGH;
-               adc_reg2 &= ~AD193X_ADC_BCLK_INV;
-               dac_reg |= AD193X_DAC_LEFT_HIGH;
-               dac_reg &= ~AD193X_DAC_BCLK_INV;
+               adc_fmt |= AD193X_ADC_LEFT_HIGH;
+               dac_fmt |= AD193X_DAC_LEFT_HIGH;
                break;
        case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
-               adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
-               adc_reg2 |= AD193X_ADC_BCLK_INV;
-               dac_reg &= ~AD193X_DAC_LEFT_HIGH;
-               dac_reg |= AD193X_DAC_BCLK_INV;
+               adc_fmt |= AD193X_ADC_BCLK_INV;
+               dac_fmt |= AD193X_DAC_BCLK_INV;
                break;
-
        case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
-               adc_reg2 |= AD193X_ADC_LEFT_HIGH;
-               adc_reg2 |= AD193X_ADC_BCLK_INV;
-               dac_reg |= AD193X_DAC_LEFT_HIGH;
-               dac_reg |= AD193X_DAC_BCLK_INV;
+               adc_fmt |= AD193X_ADC_LEFT_HIGH;
+               adc_fmt |= AD193X_ADC_BCLK_INV;
+               dac_fmt |= AD193X_DAC_LEFT_HIGH;
+               dac_fmt |= AD193X_DAC_BCLK_INV;
                break;
        default:
                return -EINVAL;
@@ -210,36 +195,31 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
-               adc_reg2 |= AD193X_ADC_LCR_MASTER;
-               adc_reg2 |= AD193X_ADC_BCLK_MASTER;
-               dac_reg |= AD193X_DAC_LCR_MASTER;
-               dac_reg |= AD193X_DAC_BCLK_MASTER;
+               adc_fmt |= AD193X_ADC_LCR_MASTER;
+               adc_fmt |= AD193X_ADC_BCLK_MASTER;
+               dac_fmt |= AD193X_DAC_LCR_MASTER;
+               dac_fmt |= AD193X_DAC_BCLK_MASTER;
                break;
        case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
-               adc_reg2 |= AD193X_ADC_LCR_MASTER;
-               adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
-               dac_reg |= AD193X_DAC_LCR_MASTER;
-               dac_reg &= ~AD193X_DAC_BCLK_MASTER;
+               adc_fmt |= AD193X_ADC_LCR_MASTER;
+               dac_fmt |= AD193X_DAC_LCR_MASTER;
                break;
        case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
-               adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
-               adc_reg2 |= AD193X_ADC_BCLK_MASTER;
-               dac_reg &= ~AD193X_DAC_LCR_MASTER;
-               dac_reg |= AD193X_DAC_BCLK_MASTER;
+               adc_fmt |= AD193X_ADC_BCLK_MASTER;
+               dac_fmt |= AD193X_DAC_BCLK_MASTER;
                break;
        case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
-               adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
-               adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
-               dac_reg &= ~AD193X_DAC_LCR_MASTER;
-               dac_reg &= ~AD193X_DAC_BCLK_MASTER;
                break;
        default:
                return -EINVAL;
        }
 
-       snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1);
-       snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2);
-       snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
+       regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
+               AD193X_ADC_SERFMT_MASK, adc_serfmt);
+       regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
+               AD193X_ADC_FMT_MASK, adc_fmt);
+       regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
+               AD193X_DAC_FMT_MASK, dac_fmt);
 
        return 0;
 }
@@ -299,20 +279,20 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
                break;
        }
 
-       snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0,
+       regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
                            AD193X_PLL_INPUT_MASK, master_rate);
 
-       snd_soc_update_bits(codec, AD193X_DAC_CTRL2,
+       regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
                            AD193X_DAC_WORD_LEN_MASK,
                            word_len << AD193X_DAC_WORD_LEN_SHFT);
 
-       snd_soc_update_bits(codec, AD193X_ADC_CTRL1,
+       regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
                            AD193X_ADC_WORD_LEN_MASK, word_len);
 
        return 0;
 }
 
-static struct snd_soc_dai_ops ad193x_dai_ops = {
+static const struct snd_soc_dai_ops ad193x_dai_ops = {
        .hw_params = ad193x_hw_params,
        .digital_mute = ad193x_mute,
        .set_tdm_slot = ad193x_set_tdm_slot,
@@ -345,7 +325,6 @@ static struct snd_soc_dai_driver ad193x_dai = {
 static int ad193x_probe(struct snd_soc_codec *codec)
 {
        struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
        int ret;
 
        codec->control_data = ad193x->regmap;
@@ -358,32 +337,37 @@ static int ad193x_probe(struct snd_soc_codec *codec)
        /* default setting for ad193x */
 
        /* unmute dac channels */
-       snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
+       regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
        /* de-emphasis: 48kHz, powedown dac */
-       snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
+       regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
        /* powerdown dac, dac in tdm mode */
-       snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
+       regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41);
        /* high-pass filter enable */
-       snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
+       regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
        /* sata delay=1, adc aux mode */
-       snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
+       regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
        /* pll input: mclki/xi */
-       snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
-       snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
-
-       snd_soc_add_controls(codec, ad193x_snd_controls,
-                            ARRAY_SIZE(ad193x_snd_controls));
-       snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
-                                 ARRAY_SIZE(ad193x_dapm_widgets));
-       snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
+       regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
+       regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
 
        return ret;
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
        .probe =        ad193x_probe,
+       .controls = ad193x_snd_controls,
+       .num_controls = ARRAY_SIZE(ad193x_snd_controls),
+       .dapm_widgets = ad193x_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
+       .dapm_routes = audio_paths,
+       .num_dapm_routes = ARRAY_SIZE(audio_paths),
 };
 
+static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
+{
+       return false;
+}
+
 #if defined(CONFIG_SPI_MASTER)
 
 static const struct regmap_config ad193x_spi_regmap_config = {
@@ -391,6 +375,9 @@ static const struct regmap_config ad193x_spi_regmap_config = {
        .reg_bits = 16,
        .read_flag_mask = 0x09,
        .write_flag_mask = 0x08,
+
+       .max_register = AD193X_NUM_REGS - 1,
+       .volatile_reg = adau193x_reg_volatile,
 };
 
 static int __devinit ad193x_spi_probe(struct spi_device *spi)
@@ -450,6 +437,9 @@ static struct spi_driver ad193x_spi_driver = {
 static const struct regmap_config ad193x_i2c_regmap_config = {
        .val_bits = 8,
        .reg_bits = 8,
+
+       .max_register = AD193X_NUM_REGS - 1,
+       .volatile_reg = adau193x_reg_volatile,
 };
 
 static const struct i2c_device_id ad193x_id[] = {
index 1507eaa425a3a06d8114e6c42ca3d7e175c17b51..47338804999233d2aaf4b6e61b79322a95848d87 100644 (file)
 #define AD193X_DAC_SERFMT_STEREO       (0 << 6)
 #define AD193X_DAC_SERFMT_TDM          (1 << 6)
 #define AD193X_DAC_CTRL1        0x03
-#define AD193X_DAC_2_CHANNELS   0
-#define AD193X_DAC_4_CHANNELS   1
-#define AD193X_DAC_8_CHANNELS   2
-#define AD193X_DAC_16_CHANNELS  3
 #define AD193X_DAC_CHAN_SHFT    1
 #define AD193X_DAC_CHAN_MASK    (3 << AD193X_DAC_CHAN_SHFT)
 #define AD193X_DAC_LCR_MASTER   (1 << 4)
 #define AD193X_DAC_BCLK_MASTER  (1 << 5)
 #define AD193X_DAC_LEFT_HIGH    (1 << 3)
 #define AD193X_DAC_BCLK_INV     (1 << 7)
+#define AD193X_DAC_FMT_MASK    (AD193X_DAC_LCR_MASTER | \
+       AD193X_DAC_BCLK_MASTER | AD193X_DAC_LEFT_HIGH | AD193X_DAC_BCLK_INV)
 #define AD193X_DAC_CTRL2        0x04
 #define AD193X_DAC_WORD_LEN_SHFT        3
 #define AD193X_DAC_WORD_LEN_MASK        0x18
 #define AD193X_ADC_SERFMT_AUX          (2 << 5)
 #define AD193X_ADC_WORD_LEN_MASK       0x3
 #define AD193X_ADC_CTRL2        0x10
-#define AD193X_ADC_2_CHANNELS   0
-#define AD193X_ADC_4_CHANNELS   1
-#define AD193X_ADC_8_CHANNELS   2
-#define AD193X_ADC_16_CHANNELS  3
 #define AD193X_ADC_CHAN_SHFT    4
 #define AD193X_ADC_CHAN_MASK    (3 << AD193X_ADC_CHAN_SHFT)
 #define AD193X_ADC_LCR_MASTER   (1 << 3)
 #define AD193X_ADC_BCLK_MASTER  (1 << 6)
 #define AD193X_ADC_LEFT_HIGH    (1 << 2)
 #define AD193X_ADC_BCLK_INV     (1 << 1)
+#define AD193X_ADC_FMT_MASK    (AD193X_ADC_LCR_MASTER | \
+       AD193X_ADC_BCLK_MASTER | AD193X_ADC_LEFT_HIGH | AD193X_ADC_BCLK_INV)
+
+#define AD193X_2_CHANNELS   0
+#define AD193X_4_CHANNELS   1
+#define AD193X_8_CHANNELS   2
+#define AD193X_16_CHANNELS  3
 
 #define AD193X_NUM_REGS          17
 
index e3931cc5e66c6736d75fa053e7755acfda7a8b8e..9bba7f849464391778e5c33f0076c0e20b3ea44f 100644 (file)
@@ -277,17 +277,7 @@ static struct platform_driver ad1980_codec_driver = {
        .remove = __devexit_p(ad1980_remove),
 };
 
-static int __init ad1980_init(void)
-{
-       return platform_driver_register(&ad1980_codec_driver);
-}
-module_init(ad1980_init);
-
-static void __exit ad1980_exit(void)
-{
-       platform_driver_unregister(&ad1980_codec_driver);
-}
-module_exit(ad1980_exit);
+module_platform_driver(ad1980_codec_driver);
 
 MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)");
 MODULE_AUTHOR("Roy Huang, Cliff Cai");
index 8d793e993e9a8a7110d2601141649a72072baee6..ee7a68dcefd2442b1650b16395025bc2eed39990 100644 (file)
@@ -63,17 +63,7 @@ static struct platform_driver ad73311_codec_driver = {
        .remove = __devexit_p(ad73311_remove),
 };
 
-static int __init ad73311_init(void)
-{
-       return platform_driver_register(&ad73311_codec_driver);
-}
-module_init(ad73311_init);
-
-static void __exit ad73311_exit(void)
-{
-       platform_driver_unregister(&ad73311_codec_driver);
-}
-module_exit(ad73311_exit);
+module_platform_driver(ad73311_codec_driver);
 
 MODULE_DESCRIPTION("ASoC ad73311 driver");
 MODULE_AUTHOR("Cliff Cai ");
index 9082e0f729f307d626cd467bc0c777993cd987f8..8103b938b8c001214858e9a628ae60908424cde3 100644 (file)
@@ -58,17 +58,7 @@ static struct platform_driver ads117x_codec_driver = {
        .remove = __devexit_p(ads117x_remove),
 };
 
-static int __init ads117x_init(void)
-{
-       return platform_driver_register(&ads117x_codec_driver);
-}
-module_init(ads117x_init);
-
-static void __exit ads117x_exit(void)
-{
-       platform_driver_unregister(&ads117x_codec_driver);
-}
-module_exit(ads117x_exit);
+module_platform_driver(ads117x_codec_driver);
 
 MODULE_DESCRIPTION("ASoC ads117x driver");
 MODULE_AUTHOR("Graeme Gregory");
index d3b29dce6ed7f27c080e7059ed5fc067d0d3ad0a..152420ca78b88310a19537a9ced6836181424629 100644 (file)
@@ -170,7 +170,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
        return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val);
 }
 
-static struct snd_soc_dai_ops ak4101_dai_ops = {
+static const struct snd_soc_dai_ops ak4101_dai_ops = {
        .hw_params = ak4104_hw_params,
        .set_fmt = ak4104_set_dai_fmt,
 };
index 95d782d86e7d5fc906e122c23dd7ae48ff39fd4a..e1f531085453df4e62d612f8169c6572d4a0fead 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -331,7 +330,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
                SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
                SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_dai_ops ak4535_dai_ops = {
+static const struct snd_soc_dai_ops ak4535_dai_ops = {
        .hw_params      = ak4535_hw_params,
        .set_fmt        = ak4535_set_dai_fmt,
        .digital_mute   = ak4535_mute,
index 77838586f3588ffc61960f70cfaea2a29b6bfccf..f53f314805656db959f2c536953c73e5abc6325e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/gpio.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -442,14 +441,14 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
                         SNDRV_PCM_RATE_16000)
 #define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
 
-static struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
+static const struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
        .hw_params    = ak4641_i2s_hw_params,
        .set_fmt      = ak4641_i2s_set_dai_fmt,
        .digital_mute = ak4641_mute,
        .set_sysclk   = ak4641_set_dai_sysclk,
 };
 
-static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
+static const struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
        .hw_params    = NULL, /* rates are controlled by BT chip */
        .set_fmt      = ak4641_pcm_set_dai_fmt,
        .digital_mute = ak4641_mute,
index 12c1bdef67323f5f260290c037ce23f50dff42de..9b4ee6c63d28c948eae4509edfc772e994ff786b 100644 (file)
  * This is very simple driver.
  * It can use headphone output / stereo input only
  *
- * AK4642 is not tested.
+ * AK4642 is tested.
  * AK4643 is tested.
+ * AK4648 is tested.
  */
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
 
-#define AK4642_VERSION "0.0.1"
-
 #define PW_MGMT1       0x00
 #define PW_MGMT2       0x01
 #define SG_SL1         0x02
@@ -71,8 +69,6 @@
 #define HP_MS          0x23
 #define SPK_MS         0x24
 
-#define AK4642_CACHEREGNUM     0x25
-
 /* PW_MGMT1*/
 #define PMVCM          (1 << 6) /* VCOM Power Management */
 #define PMMIN          (1 << 5) /* MIN Input Power Management */
@@ -150,8 +146,52 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 
        SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
                         0, 0xFF, 1, out_tlv),
+
+       SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
+       SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
+       SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+
+       /* Outputs */
+       SND_SOC_DAPM_OUTPUT("HPOUTL"),
+       SND_SOC_DAPM_OUTPUT("HPOUTR"),
+       SND_SOC_DAPM_OUTPUT("LINEOUT"),
+
+       SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
+                          &ak4642_hpout_mixer_controls[0],
+                          ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
+                          &ak4642_hpout_mixer_controls[0],
+                          ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
+                          &ak4642_lout_mixer_controls[0],
+                          ARRAY_SIZE(ak4642_lout_mixer_controls)),
+
+       /* DAC */
+       SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0),
 };
 
+static const struct snd_soc_dapm_route ak4642_intercon[] = {
+
+       /* Outputs */
+       {"HPOUTL", NULL, "HPOUTL Mixer"},
+       {"HPOUTR", NULL, "HPOUTR Mixer"},
+       {"LINEOUT", NULL, "LINEOUT Mixer"},
+
+       {"HPOUTL Mixer", "DACH", "DAC"},
+       {"HPOUTR Mixer", "DACH", "DAC"},
+       {"LINEOUT Mixer", "DACL", "DAC"},
+};
 
 /* codec private data */
 struct ak4642_priv {
@@ -162,7 +202,7 @@ struct ak4642_priv {
 /*
  * ak4642 register cache
  */
-static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
+static const u8 ak4642_reg[] = {
        0x00, 0x00, 0x01, 0x00,
        0x02, 0x00, 0x00, 0x00,
        0xe1, 0xe1, 0x18, 0x00,
@@ -175,6 +215,19 @@ static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
        0x00,
 };
 
+static const u8 ak4648_reg[] = {
+       0x00, 0x00, 0x01, 0x00,
+       0x02, 0x00, 0x00, 0x00,
+       0xe1, 0xe1, 0x18, 0x00,
+       0xe1, 0x18, 0x11, 0xb8,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x88, 0x88, 0x08,
+};
+
 static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                              struct snd_soc_dai *dai)
 {
@@ -192,14 +245,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                 * This operation came from example code of
                 * "ASAHI KASEI AK4642" (japanese) manual p97.
                 */
-               snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
-               snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
                snd_soc_write(codec, L_IVC, 0x91); /* volume */
                snd_soc_write(codec, R_IVC, 0x91); /* volume */
-               snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
-                                                    PMVCM | PMMIN | PMDAC);
-               snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
-               snd_soc_update_bits(codec, PW_MGMT2, HPMTN,     HPMTN);
        } else {
                /*
                 * start stereo input
@@ -217,8 +264,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
                snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
                snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
                snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
-               snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
-                                                    PMVCM | PMADL);
+               snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL);
                snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
        }
 
@@ -232,12 +278,6 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
        struct snd_soc_codec *codec = dai->codec;
 
        if (is_play) {
-               /* stop headphone output */
-               snd_soc_update_bits(codec, PW_MGMT2, HPMTN,     0);
-               snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
-               snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0);
-               snd_soc_update_bits(codec, MD_CTL3, BST1, 0);
-               snd_soc_update_bits(codec, MD_CTL4, DACH, 0);
        } else {
                /* stop stereo input */
                snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
@@ -376,7 +416,23 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops ak4642_dai_ops = {
+static int ak4642_set_bias_level(struct snd_soc_codec *codec,
+                                enum snd_soc_bias_level level)
+{
+       switch (level) {
+       case SND_SOC_BIAS_OFF:
+               snd_soc_write(codec, PW_MGMT1, 0x00);
+               break;
+       default:
+               snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
+               break;
+       }
+       codec->dapm.bias_level = level;
+
+       return 0;
+}
+
+static const struct snd_soc_dai_ops ak4642_dai_ops = {
        .startup        = ak4642_dai_startup,
        .shutdown       = ak4642_dai_shutdown,
        .set_sysclk     = ak4642_dai_set_sysclk,
@@ -414,8 +470,6 @@ static int ak4642_probe(struct snd_soc_codec *codec)
        struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
-       dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
-
        ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -425,15 +479,43 @@ static int ak4642_probe(struct snd_soc_codec *codec)
        snd_soc_add_controls(codec, ak4642_snd_controls,
                             ARRAY_SIZE(ak4642_snd_controls));
 
+       ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       return 0;
+}
+
+static int ak4642_remove(struct snd_soc_codec *codec)
+{
+       ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
        return 0;
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
        .probe                  = ak4642_probe,
+       .remove                 = ak4642_remove,
+       .resume                 = ak4642_resume,
+       .set_bias_level         = ak4642_set_bias_level,
+       .reg_cache_default      = ak4642_reg,                   /* ak4642 reg */
+       .reg_cache_size         = ARRAY_SIZE(ak4642_reg),       /* ak4642 reg */
+       .reg_word_size          = sizeof(u8),
+       .dapm_widgets           = ak4642_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4642_dapm_widgets),
+       .dapm_routes            = ak4642_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
+       .probe                  = ak4642_probe,
+       .remove                 = ak4642_remove,
        .resume                 = ak4642_resume,
-       .reg_cache_size         = ARRAY_SIZE(ak4642_reg),
+       .set_bias_level         = ak4642_set_bias_level,
+       .reg_cache_default      = ak4648_reg,                   /* ak4648 reg */
+       .reg_cache_size         = ARRAY_SIZE(ak4648_reg),       /* ak4648 reg */
        .reg_word_size          = sizeof(u8),
-       .reg_cache_default      = ak4642_reg,
+       .dapm_widgets           = ak4642_dapm_widgets,
+       .num_dapm_widgets       = ARRAY_SIZE(ak4642_dapm_widgets),
+       .dapm_routes            = ak4642_intercon,
+       .num_dapm_routes        = ARRAY_SIZE(ak4642_intercon),
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -451,7 +533,8 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
        ak4642->control_type = SND_SOC_I2C;
 
        ret =  snd_soc_register_codec(&i2c->dev,
-                       &soc_codec_dev_ak4642, &ak4642_dai, 1);
+                               (struct snd_soc_codec_driver *)id->driver_data,
+                               &ak4642_dai, 1);
        if (ret < 0)
                kfree(ak4642);
        return ret;
@@ -465,8 +548,9 @@ static __devexit int ak4642_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id ak4642_i2c_id[] = {
-       { "ak4642", 0 },
-       { "ak4643", 0 },
+       { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 },
+       { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 },
+       { "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
index de9ff66d3721d5dd367b2fc3f60178d9d5ee9e7c..4f5c69f735a94a35bd560e2292035142e6458ab4 100644 (file)
@@ -594,7 +594,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
 
 #define AK4671_FORMATS         SNDRV_PCM_FMTBIT_S16_LE
 
-static struct snd_soc_dai_ops ak4671_dai_ops = {
+static const struct snd_soc_dai_ops ak4671_dai_ops = {
        .hw_params      = ak4671_hw_params,
        .set_sysclk     = ak4671_set_dai_sysclk,
        .set_fmt        = ak4671_set_dai_fmt,
index 984b14bcb6054bfbaa3d5f84ac7d60613d0f5c2c..6a5c001e8ba8ae6ab2390e2e643effbf2373f12a 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
-#include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -839,7 +838,7 @@ static int alc5623_set_bias_level(struct snd_soc_codec *codec,
                        | SNDRV_PCM_FMTBIT_S24_LE \
                        | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops alc5623_dai_ops = {
+static const struct snd_soc_dai_ops alc5623_dai_ops = {
                .hw_params = alc5623_pcm_hw_params,
                .digital_mute = alc5623_mute,
                .set_fmt = alc5623_set_dai_fmt,
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
new file mode 100644 (file)
index 0000000..3f750de
--- /dev/null
@@ -0,0 +1,1159 @@
+/*
+* alc5632.c  --  ALC5632 ALSA SoC Audio Codec
+*
+* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+*
+* Authors:  Leon Romanovsky <leon@leon.nu>
+*           Andrey Danin <danindrey@mail.ru>
+*           Ilya Petrov <ilya.muromec@gmail.com>
+*           Marc Dietrich <marvin24@gmx.de>
+*
+* Based on alc5623.c by Arnaud Patard
+*
+* 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/tlv.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+
+#include "alc5632.h"
+
+/*
+ * ALC5632 register cache
+ */
+static struct reg_default  alc5632_reg_defaults[] = {
+       {   2, 0x8080 },        /* R2   - Speaker Output Volume */
+       {   4, 0x8080 },        /* R4   - Headphone Output Volume */
+       {   6, 0x8080 },        /* R6   - AUXOUT Volume */
+       {   8, 0xC800 },        /* R8   - Phone Input */
+       {  10, 0xE808 },        /* R10  - LINE_IN Volume */
+       {  12, 0x1010 },        /* R12  - STEREO DAC Input Volume */
+       {  14, 0x0808 },        /* R14  - MIC Input Volume */
+       {  16, 0xEE0F },        /* R16  - Stereo DAC and MIC Routing Control */
+       {  18, 0xCBCB },        /* R18  - ADC Record Gain */
+       {  20, 0x7F7F },        /* R20  - ADC Record Mixer Control */
+       {  24, 0xE010 },        /* R24  - Voice DAC Volume */
+       {  28, 0x8008 },        /* R28  - Output Mixer Control */
+       {  34, 0x0000 },        /* R34  - Microphone Control */
+       {  36, 0x00C0 },    /* R36  - Codec Digital MIC/Digital Boost
+                                                  Control */
+       {  46, 0x0000 },        /* R46  - Stereo DAC/Voice DAC/Stereo ADC
+                                                  Function Select */
+       {  52, 0x8000 },        /* R52  - Main Serial Data Port Control
+                                                  (Stereo I2S) */
+       {  54, 0x0000 },        /* R54  - Extend Serial Data Port Control
+                                                  (VoDAC_I2S/PCM) */
+       {  58, 0x0000 },        /* R58  - Power Management Addition 1 */
+       {  60, 0x0000 },        /* R60  - Power Management Addition 2 */
+       {  62, 0x8000 },        /* R62  - Power Management Addition 3 */
+       {  64, 0x0C0A },        /* R64  - General Purpose Control Register 1 */
+       {  66, 0x0000 },        /* R66  - General Purpose Control Register 2 */
+       {  68, 0x0000 },        /* R68  - PLL1 Control */
+       {  70, 0x0000 },        /* R70  - PLL2 Control */
+       {  76, 0xBE3E },        /* R76  - GPIO Pin Configuration */
+       {  78, 0xBE3E },        /* R78  - GPIO Pin Polarity */
+       {  80, 0x0000 },        /* R80  - GPIO Pin Sticky */
+       {  82, 0x0000 },        /* R82  - GPIO Pin Wake Up */
+       {  86, 0x0000 },        /* R86  - Pin Sharing */
+       {  90, 0x0009 },        /* R90  - Soft Volume Control Setting */
+       {  92, 0x0000 },        /* R92  - GPIO_Output Pin Control */
+       {  94, 0x3000 },        /* R94  - MISC Control */
+       {  96, 0x3075 },        /* R96  - Stereo DAC Clock Control_1 */
+       {  98, 0x1010 },        /* R98  - Stereo DAC Clock Control_2 */
+       { 100, 0x3110 },        /* R100 - VoDAC_PCM Clock Control_1 */
+       { 104, 0x0553 },        /* R104 - Pseudo Stereo and Spatial Effect
+                                                  Block Control */
+       { 106, 0x0000 },        /* R106 - Private Register Address */
+};
+
+/* codec private data */
+struct alc5632_priv {
+       struct regmap *regmap;
+       u8 id;
+       unsigned int sysclk;
+};
+
+static bool alc5632_volatile_register(struct device *dev,
+                                                       unsigned int reg)
+{
+       switch (reg) {
+       case ALC5632_RESET:
+       case ALC5632_PWR_DOWN_CTRL_STATUS:
+       case ALC5632_GPIO_PIN_STATUS:
+       case ALC5632_OVER_CURR_STATUS:
+       case ALC5632_HID_CTRL_DATA:
+       case ALC5632_EQ_CTRL:
+       case ALC5632_VENDOR_ID1:
+       case ALC5632_VENDOR_ID2:
+               return true;
+
+       default:
+               break;
+       }
+
+       return false;
+}
+
+static inline int alc5632_reset(struct regmap *map)
+{
+       return regmap_write(map, ALC5632_RESET, 0x59B4);
+}
+
+static int amp_mixer_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       /* to power-on/off class-d amp generators/speaker */
+       /* need to write to 'index-46h' register :        */
+       /* so write index num (here 0x46) to reg 0x6a     */
+       /* and then 0xffff/0 to reg 0x6c                  */
+       snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46);
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
+               break;
+       case SND_SOC_DAPM_POST_PMD:
+               snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0);
+               break;
+       }
+
+       return 0;
+}
+
+/*
+ * ALC5632 Controls
+ */
+
+/* -34.5db min scale, 1.5db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
+/* -46.5db min scale, 1.5db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
+/* -16.5db min scale, 1.5db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
+static const unsigned int boost_tlv[] = {
+       TLV_DB_RANGE_HEAD(3),
+       0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+       1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+       2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
+};
+/* 0db min scale, 6 db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
+/* 0db min scalem 0.75db steps, no mute */
+static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0);
+
+static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
+       /* left starts at bit 8, right at bit 0 */
+       /* 31 steps (5 bit), -46.5db scale */
+       SOC_DOUBLE_TLV("Speaker Playback Volume",
+                       ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+       /* bit 15 mutes left, bit 7 right */
+       SOC_DOUBLE("Speaker Playback Switch",
+                       ALC5632_SPK_OUT_VOL, 15, 7, 1, 1),
+       SOC_DOUBLE_TLV("Headphone Playback Volume",
+                       ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+       SOC_DOUBLE("Headphone Playback Switch",
+                       ALC5632_HP_OUT_VOL, 15, 7, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_snd_controls[] = {
+       SOC_DOUBLE_TLV("Auxout Playback Volume",
+                       ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
+       SOC_DOUBLE("Auxout Playback Switch",
+                       ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
+       SOC_SINGLE_TLV("Voice DAC Playback Volume",
+                       ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
+       SOC_SINGLE_TLV("Phone Capture Volume",
+                       ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
+       SOC_DOUBLE_TLV("LineIn Capture Volume",
+                       ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
+       SOC_DOUBLE_TLV("Master Playback Volume",
+                       ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
+       SOC_DOUBLE("Master Playback Switch",
+                       ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
+       SOC_SINGLE_TLV("Mic1 Capture Volume",
+                       ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
+       SOC_SINGLE_TLV("Mic2 Capture Volume",
+                       ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
+       SOC_DOUBLE_TLV("Rec Capture Volume",
+                       ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
+       SOC_SINGLE_TLV("Mic 1 Boost Volume",
+                       ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv),
+       SOC_SINGLE_TLV("Mic 2 Boost Volume",
+                       ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv),
+       SOC_SINGLE_TLV("Digital Boost Volume",
+                       ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
+};
+
+/*
+ * DAPM Controls
+ */
+static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1),
+SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1),
+SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1),
+SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1),
+SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1),
+SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1),
+SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC12MONO Playback Switch",
+                                       ALC5632_MIC_ROUTING_CTRL, 13, 1, 1),
+SOC_DAPM_SINGLE("MIC22MONO Playback Switch",
+                                       ALC5632_MIC_ROUTING_CTRL, 9, 1, 1),
+SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1),
+SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1),
+};
+
+static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = {
+SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC12SPK Playback Switch",
+                                       ALC5632_MIC_ROUTING_CTRL, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC22SPK Playback Switch",
+                                       ALC5632_MIC_ROUTING_CTRL, 10, 1, 1),
+SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1),
+SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
+};
+
+/* Left Record Mixer */
+static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
+SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
+SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
+SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
+};
+
+/* Right Record Mixer */
+static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
+SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
+SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
+SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
+SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
+SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
+SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
+};
+
+static const char *alc5632_spk_n_sour_sel[] = {
+               "RN/-R", "RP/+R", "LN/-R", "Mute"};
+static const char *alc5632_hpl_out_input_sel[] = {
+               "Vmid", "HP Left Mix"};
+static const char *alc5632_hpr_out_input_sel[] = {
+               "Vmid", "HP Right Mix"};
+static const char *alc5632_spkout_input_sel[] = {
+               "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+static const char *alc5632_aux_out_input_sel[] = {
+               "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+
+/* auxout output mux */
+static const struct soc_enum alc5632_aux_out_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel);
+static const struct snd_kcontrol_new alc5632_auxout_mux_controls =
+SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum);
+
+/* speaker output mux */
+static const struct soc_enum alc5632_spkout_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel);
+static const struct snd_kcontrol_new alc5632_spkout_mux_controls =
+SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum);
+
+/* headphone left output mux */
+static const struct soc_enum alc5632_hpl_out_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel);
+static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls =
+SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum);
+
+/* headphone right output mux */
+static const struct soc_enum alc5632_hpr_out_input_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel);
+static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls =
+SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum);
+
+/* speaker output N select */
+static const struct soc_enum alc5632_spk_n_sour_enum =
+SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel);
+static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls =
+SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum);
+
+/* speaker amplifier */
+static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"};
+static const struct soc_enum alc5632_amp_enum =
+       SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names);
+static const struct snd_kcontrol_new alc5632_amp_mux_controls =
+       SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
+
+
+static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
+/* Muxes */
+SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
+       &alc5632_auxout_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
+       &alc5632_spkout_mux_controls),
+SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
+       &alc5632_hpl_out_mux_controls),
+SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
+       &alc5632_hpr_out_mux_controls),
+SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
+       &alc5632_spkoutn_mux_controls),
+
+/* output mixers */
+SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
+       &alc5632_hp_mixer_controls[0],
+       ARRAY_SIZE(alc5632_hp_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0,
+       &alc5632_hpr_mixer_controls[0],
+       ARRAY_SIZE(alc5632_hpr_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0,
+       &alc5632_hpl_mixer_controls[0],
+       ARRAY_SIZE(alc5632_hpl_mixer_controls)),
+SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
+       &alc5632_mono_mixer_controls[0],
+       ARRAY_SIZE(alc5632_mono_mixer_controls)),
+SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
+       &alc5632_speaker_mixer_controls[0],
+       ARRAY_SIZE(alc5632_speaker_mixer_controls)),
+
+/* input mixers */
+SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
+       &alc5632_captureL_mixer_controls[0],
+       ARRAY_SIZE(alc5632_captureL_mixer_controls)),
+SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
+       &alc5632_captureR_mixer_controls[0],
+       ARRAY_SIZE(alc5632_captureR_mixer_controls)),
+
+SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback",
+       ALC5632_PWR_MANAG_ADD2, 9, 0),
+SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback",
+       ALC5632_PWR_MANAG_ADD2, 8, 0),
+SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("DAC Right Channel",
+       ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture",
+       ALC5632_PWR_MANAG_ADD2, 7, 0),
+SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
+       ALC5632_PWR_MANAG_ADD2, 6, 0),
+SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0),
+SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("Mic Bias1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("Mic Bias2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0,
+       amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0),
+SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0,
+       &alc5632_amp_mux_controls),
+
+SND_SOC_DAPM_OUTPUT("AUXOUT"),
+SND_SOC_DAPM_OUTPUT("HPL"),
+SND_SOC_DAPM_OUTPUT("HPR"),
+SND_SOC_DAPM_OUTPUT("SPKOUT"),
+SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+SND_SOC_DAPM_INPUT("LINEINL"),
+SND_SOC_DAPM_INPUT("LINEINR"),
+SND_SOC_DAPM_INPUT("PHONEP"),
+SND_SOC_DAPM_INPUT("PHONEN"),
+SND_SOC_DAPM_INPUT("MIC1"),
+SND_SOC_DAPM_INPUT("MIC2"),
+SND_SOC_DAPM_VMID("Vmid"),
+};
+
+
+static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
+       /* virtual mixer - mixes left & right channels */
+       {"I2S Mix",     NULL,   "Left DAC"},
+       {"I2S Mix",     NULL,   "Right DAC"},
+       {"Line Mix",    NULL,   "Right LineIn"},
+       {"Line Mix",    NULL,   "Left LineIn"},
+       {"Phone Mix",   NULL,   "Phone"},
+       {"Phone Mix",   NULL,   "Phone ADMix"},
+       {"AUXOUT",              NULL,   "Aux Out"},
+
+       /* DAC */
+       {"DAC Right Channel",   NULL,   "I2S Mix"},
+       {"DAC Left Channel",    NULL,   "I2S Mix"},
+
+       /* HP mixer */
+       {"HPL Mix",     "ADC2HP_L Playback Switch",     "Left Capture Mix"},
+       {"HPL Mix", NULL,                                       "HP Mix"},
+       {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
+       {"HPR Mix", NULL,                                       "HP Mix"},
+       {"HP Mix",      "LI2HP Playback Switch",        "Line Mix"},
+       {"HP Mix",      "PHONE2HP Playback Switch",     "Phone Mix"},
+       {"HP Mix",      "MIC12HP Playback Switch",      "MIC1 PGA"},
+       {"HP Mix",      "MIC22HP Playback Switch",      "MIC2 PGA"},
+
+       {"HPR Mix", "DACR2HP Playback Switch",  "DAC Right Channel"},
+       {"HPL Mix", "DACL2HP Playback Switch",  "DAC Left Channel"},
+
+       /* speaker mixer */
+       {"Speaker Mix", "LI2SPK Playback Switch",       "Line Mix"},
+       {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"},
+       {"Speaker Mix", "MIC12SPK Playback Switch",     "MIC1 PGA"},
+       {"Speaker Mix", "MIC22SPK Playback Switch",     "MIC2 PGA"},
+       {"Speaker Mix", "DAC2SPK Playback Switch",      "DAC Left Channel"},
+
+
+
+       /* mono mixer */
+       {"Mono Mix", "ADC2MONO_L Playback Switch",      "Left Capture Mix"},
+       {"Mono Mix", "ADC2MONO_R Playback Switch",      "Right Capture Mix"},
+       {"Mono Mix", "LI2MONO Playback Switch",         "Line Mix"},
+       {"Mono Mix", "VOICE2MONO Playback Switch",      "Phone Mix"},
+       {"Mono Mix", "MIC12MONO Playback Switch",       "MIC1 PGA"},
+       {"Mono Mix", "MIC22MONO Playback Switch",       "MIC2 PGA"},
+       {"Mono Mix", "DAC2MONO Playback Switch",        "DAC Left Channel"},
+
+       /* Left record mixer */
+       {"Left Capture Mix", "LineInL Capture Switch",  "LINEINL"},
+       {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"},
+       {"Left Capture Mix", "Mic1 Capture Switch",     "MIC1 Pre Amp"},
+       {"Left Capture Mix", "Mic2 Capture Switch",     "MIC2 Pre Amp"},
+       {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
+       {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+       {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+       /*Right record mixer */
+       {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
+       {"Right Capture Mix", "Right Phone Capture Switch",     "PHONEP"},
+       {"Right Capture Mix", "Mic1 Capture Switch",    "MIC1 Pre Amp"},
+       {"Right Capture Mix", "Mic2 Capture Switch",    "MIC2 Pre Amp"},
+       {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
+       {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
+       {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+
+       /* headphone left mux */
+       {"Left Headphone Mux", "HP Left Mix",           "HPL Mix"},
+       {"Left Headphone Mux", "Vmid",                  "Vmid"},
+
+       /* headphone right mux */
+       {"Right Headphone Mux", "HP Right Mix",         "HPR Mix"},
+       {"Right Headphone Mux", "Vmid",                 "Vmid"},
+
+       /* speaker out mux */
+       {"SpeakerOut Mux", "Vmid",                      "Vmid"},
+       {"SpeakerOut Mux", "HPOut Mix",                 "HPOut Mix"},
+       {"SpeakerOut Mux", "Speaker Mix",               "Speaker Mix"},
+       {"SpeakerOut Mux", "Mono Mix",                  "Mono Mix"},
+
+       /* Mono/Aux Out mux */
+       {"AuxOut Mux", "Vmid",                          "Vmid"},
+       {"AuxOut Mux", "HPOut Mix",                     "HPOut Mix"},
+       {"AuxOut Mux", "Speaker Mix",                   "Speaker Mix"},
+       {"AuxOut Mux", "Mono Mix",                      "Mono Mix"},
+
+       /* output pga */
+       {"HPL", NULL,                                   "Left Headphone"},
+       {"Left Headphone", NULL,                        "Left Headphone Mux"},
+       {"HPR", NULL,                                   "Right Headphone"},
+       {"Right Headphone", NULL,                       "Right Headphone Mux"},
+       {"Aux Out", NULL,                               "AuxOut Mux"},
+
+       /* input pga */
+       {"Left LineIn", NULL,                           "LINEINL"},
+       {"Right LineIn", NULL,                          "LINEINR"},
+       {"Phone", NULL,                         "PHONEP"},
+       {"MIC1 Pre Amp", NULL,                          "MIC1"},
+       {"MIC2 Pre Amp", NULL,                          "MIC2"},
+       {"MIC1 PGA", NULL,                              "MIC1 Pre Amp"},
+       {"MIC2 PGA", NULL,                              "MIC2 Pre Amp"},
+
+       /* left ADC */
+       {"Left ADC", NULL,                              "Left Capture Mix"},
+
+       /* right ADC */
+       {"Right ADC", NULL,                             "Right Capture Mix"},
+
+       {"SpeakerOut N Mux", "RN/-R",                   "Left Speaker"},
+       {"SpeakerOut N Mux", "RP/+R",                   "Left Speaker"},
+       {"SpeakerOut N Mux", "LN/-R",                   "Left Speaker"},
+       {"SpeakerOut N Mux", "Mute",                    "Vmid"},
+
+       {"SpeakerOut N Mux", "RN/-R",                   "Right Speaker"},
+       {"SpeakerOut N Mux", "RP/+R",                   "Right Speaker"},
+       {"SpeakerOut N Mux", "LN/-R",                   "Right Speaker"},
+       {"SpeakerOut N Mux", "Mute",                    "Vmid"},
+
+       {"AB Amp", NULL,                                "SpeakerOut Mux"},
+       {"D Amp", NULL,                                 "SpeakerOut Mux"},
+       {"AB-D Amp Mux", "AB Amp",                      "AB Amp"},
+       {"AB-D Amp Mux", "D Amp",                       "D Amp"},
+       {"Left Speaker", NULL,                          "AB-D Amp Mux"},
+       {"Right Speaker", NULL,                         "AB-D Amp Mux"},
+
+       {"SPKOUT", NULL,                                "Left Speaker"},
+       {"SPKOUT", NULL,                                "Right Speaker"},
+
+       {"SPKOUTN", NULL,                               "SpeakerOut N Mux"},
+
+};
+
+/* PLL divisors */
+struct _pll_div {
+       u32 pll_in;
+       u32 pll_out;
+       u16 regvalue;
+};
+
+/* Note : pll code from original alc5632 driver. Not sure of how good it is */
+/* usefull only for master mode */
+static const struct _pll_div codec_master_pll_div[] = {
+
+       {  2048000,  8192000,   0x0ea0},
+       {  3686400,  8192000,   0x4e27},
+       { 12000000,  8192000,   0x456b},
+       { 13000000,  8192000,   0x495f},
+       { 13100000,  8192000,   0x0320},
+       {  2048000,  11289600,  0xf637},
+       {  3686400,  11289600,  0x2f22},
+       { 12000000,  11289600,  0x3e2f},
+       { 13000000,  11289600,  0x4d5b},
+       { 13100000,  11289600,  0x363b},
+       {  2048000,  16384000,  0x1ea0},
+       {  3686400,  16384000,  0x9e27},
+       { 12000000,  16384000,  0x452b},
+       { 13000000,  16384000,  0x542f},
+       { 13100000,  16384000,  0x03a0},
+       {  2048000,  16934400,  0xe625},
+       {  3686400,  16934400,  0x9126},
+       { 12000000,  16934400,  0x4d2c},
+       { 13000000,  16934400,  0x742f},
+       { 13100000,  16934400,  0x3c27},
+       {  2048000,  22579200,  0x2aa0},
+       {  3686400,  22579200,  0x2f20},
+       { 12000000,  22579200,  0x7e2f},
+       { 13000000,  22579200,  0x742f},
+       { 13100000,  22579200,  0x3c27},
+       {  2048000,  24576000,  0x2ea0},
+       {  3686400,  24576000,  0xee27},
+       { 12000000,  24576000,  0x2915},
+       { 13000000,  24576000,  0x772e},
+       { 13100000,  24576000,  0x0d20},
+};
+
+/* FOUT = MCLK*(N+2)/((M+2)*(K+2))
+   N: bit 15:8 (div 2 .. div 257)
+   K: bit  6:4 typical 2
+   M: bit  3:0 (div 2 .. div 17)
+
+   same as for 5623 - thanks!
+*/
+
+static const struct _pll_div codec_slave_pll_div[] = {
+
+       {  1024000,  16384000,  0x3ea0},
+       {  1411200,  22579200,  0x3ea0},
+       {  1536000,  24576000,  0x3ea0},
+       {  2048000,  16384000,  0x1ea0},
+       {  2822400,  22579200,  0x1ea0},
+       {  3072000,  24576000,  0x1ea0},
+
+};
+
+static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+               int source, unsigned int freq_in, unsigned int freq_out)
+{
+       int i;
+       struct snd_soc_codec *codec = codec_dai->codec;
+       int gbl_clk = 0, pll_div = 0;
+       u16 reg;
+
+       if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK)
+               return -EINVAL;
+
+       /* Disable PLL power */
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_PWR_ADD2_PLL1,
+                               0);
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_PWR_ADD2_PLL2,
+                               0);
+
+       /* pll is not used in slave mode */
+       reg = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+       if (reg & ALC5632_DAI_SDP_SLAVE_MODE)
+               return 0;
+
+       if (!freq_in || !freq_out)
+               return 0;
+
+       switch (pll_id) {
+       case ALC5632_PLL_FR_MCLK:
+               for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
+                       if (codec_master_pll_div[i].pll_in == freq_in
+                          && codec_master_pll_div[i].pll_out == freq_out) {
+                               /* PLL source from MCLK */
+                               pll_div  = codec_master_pll_div[i].regvalue;
+                               break;
+                       }
+               }
+               break;
+       case ALC5632_PLL_FR_BCLK:
+               for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
+                       if (codec_slave_pll_div[i].pll_in == freq_in
+                          && codec_slave_pll_div[i].pll_out == freq_out) {
+                               /* PLL source from Bitclk */
+                               gbl_clk = ALC5632_PLL_FR_BCLK;
+                               pll_div = codec_slave_pll_div[i].regvalue;
+                               break;
+                       }
+               }
+               break;
+       case ALC5632_PLL_FR_VBCLK:
+               for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
+                       if (codec_slave_pll_div[i].pll_in == freq_in
+                          && codec_slave_pll_div[i].pll_out == freq_out) {
+                               /* PLL source from voice clock */
+                               gbl_clk = ALC5632_PLL_FR_VBCLK;
+                               pll_div = codec_slave_pll_div[i].regvalue;
+                               break;
+                       }
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (!pll_div)
+               return -EINVAL;
+
+       /* choose MCLK/BCLK/VBCLK */
+       snd_soc_write(codec, ALC5632_GPCR2, gbl_clk);
+       /* choose PLL1 clock rate */
+       snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div);
+       /* enable PLL1 */
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_PWR_ADD2_PLL1,
+                               ALC5632_PWR_ADD2_PLL1);
+       /* enable PLL2 */
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_PWR_ADD2_PLL2,
+                               ALC5632_PWR_ADD2_PLL2);
+       /* use PLL1 as main SYSCLK */
+       snd_soc_update_bits(codec, ALC5632_GPCR1,
+                       ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1,
+                       ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1);
+
+       return 0;
+}
+
+struct _coeff_div {
+       u16 fs;
+       u16 regvalue;
+};
+
+/* codec hifi mclk (after PLL) clock divider coefficients */
+/* values inspired from column BCLK=32Fs of Appendix A table */
+static const struct _coeff_div coeff_div[] = {
+       {512*1, 0x3075},
+};
+
+static int get_coeff(struct snd_soc_codec *codec, int rate)
+{
+       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+               if (coeff_div[i].fs * rate == alc5632->sysclk)
+                       return i;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Clock after PLL and dividers
+ */
+static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+               int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+
+       switch (freq) {
+       case  8192000:
+       case 11289600:
+       case 12288000:
+       case 16384000:
+       case 16934400:
+       case 18432000:
+       case 22579200:
+       case 24576000:
+               alc5632->sysclk = freq;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 iface = 0;
+
+       /* set master/slave audio interface */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               iface = ALC5632_DAI_SDP_MASTER_MODE;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               iface = ALC5632_DAI_SDP_SLAVE_MODE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* interface format */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               iface |= ALC5632_DAI_I2S_DF_I2S;
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               iface |= ALC5632_DAI_I2S_DF_LEFT;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               iface |= ALC5632_DAI_I2S_DF_PCM_A;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               iface |= ALC5632_DAI_I2S_DF_PCM_B;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* clock inversion */
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+}
+
+static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
+               struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_codec *codec = rtd->codec;
+       int coeff, rate;
+       u16 iface;
+
+       iface = snd_soc_read(codec, ALC5632_DAI_CONTROL);
+       iface &= ~ALC5632_DAI_I2S_DL_MASK;
+
+       /* bit size */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               iface |= ALC5632_DAI_I2S_DL_16;
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               iface |= ALC5632_DAI_I2S_DL_20;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               iface |= ALC5632_DAI_I2S_DL_24;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* set iface & srate */
+       snd_soc_write(codec, ALC5632_DAI_CONTROL, iface);
+       rate = params_rate(params);
+       coeff = get_coeff(codec, rate);
+       if (coeff < 0)
+               return -EINVAL;
+
+       coeff = coeff_div[coeff].regvalue;
+       snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff);
+
+       return 0;
+}
+
+static int alc5632_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L
+                                               |ALC5632_MISC_HP_DEPOP_MUTE_R;
+       u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute;
+
+       if (mute)
+               mute_reg |= hp_mute;
+
+       return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg);
+}
+
+#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF)
+
+#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD)
+
+#define ALC5632_ADD1_POWER_EN \
+               (ALC5632_PWR_ADD1_DAC_REF \
+               | ALC5632_PWR_ADD1_SOFTGEN_EN \
+               | ALC5632_PWR_ADD1_HP_OUT_AMP \
+               | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \
+               | ALC5632_PWR_ADD1_MAIN_BIAS)
+
+static void enable_power_depop(struct snd_soc_codec *codec)
+{
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+                               ALC5632_PWR_ADD1_SOFTGEN_EN,
+                               ALC5632_PWR_ADD1_SOFTGEN_EN);
+
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+                               ALC5632_ADD3_POWER_EN,
+                               ALC5632_ADD3_POWER_EN);
+
+       snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+                               ALC5632_MISC_HP_DEPOP_MODE2_EN,
+                               ALC5632_MISC_HP_DEPOP_MODE2_EN);
+
+       /* "normal" mode: 0 @ 26 */
+       /* set all PR0-7 mixers to 0 */
+       snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+                               ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
+                               0);
+
+       msleep(500);
+
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_ADD2_POWER_EN,
+                               ALC5632_ADD2_POWER_EN);
+
+       snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+                               ALC5632_ADD1_POWER_EN,
+                               ALC5632_ADD1_POWER_EN);
+
+       /* disable HP Depop2 */
+       snd_soc_update_bits(codec, ALC5632_MISC_CTRL,
+                               ALC5632_MISC_HP_DEPOP_MODE2_EN,
+                               0);
+
+}
+
+static int alc5632_set_bias_level(struct snd_soc_codec *codec,
+                                     enum snd_soc_bias_level level)
+{
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               enable_power_depop(codec);
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               /* everything off except vref/vmid, */
+               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+                               ALC5632_PWR_MANAG_ADD1_MASK,
+                               ALC5632_PWR_ADD1_MAIN_BIAS);
+               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_PWR_MANAG_ADD2_MASK,
+                               ALC5632_PWR_ADD2_VREF);
+               /* "normal" mode: 0 @ 26 */
+               snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS,
+                               ALC5632_PWR_DOWN_CTRL_STATUS_MASK,
+                               0xffff ^ (ALC5632_PWR_VREF_PR3
+                               | ALC5632_PWR_VREF_PR2));
+               break;
+       case SND_SOC_BIAS_OFF:
+               /* everything off, dac mute, inactive */
+               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2,
+                               ALC5632_PWR_MANAG_ADD2_MASK, 0);
+               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3,
+                               ALC5632_PWR_MANAG_ADD3_MASK, 0);
+               snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1,
+                               ALC5632_PWR_MANAG_ADD1_MASK, 0);
+               break;
+       }
+       codec->dapm.bias_level = level;
+       return 0;
+}
+
+#define ALC5632_FORMATS        (SNDRV_PCM_FMTBIT_S16_LE \
+                       | SNDRV_PCM_FMTBIT_S24_LE \
+                       | SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_soc_dai_ops alc5632_dai_ops = {
+               .hw_params = alc5632_pcm_hw_params,
+               .digital_mute = alc5632_mute,
+               .set_fmt = alc5632_set_dai_fmt,
+               .set_sysclk = alc5632_set_dai_sysclk,
+               .set_pll = alc5632_set_dai_pll,
+};
+
+static struct snd_soc_dai_driver alc5632_dai = {
+       .name = "alc5632-hifi",
+       .playback = {
+               .stream_name = "HiFi Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rate_min =     8000,
+               .rate_max =     48000,
+               .rates = SNDRV_PCM_RATE_8000_48000,
+               .formats = ALC5632_FORMATS,},
+       .capture = {
+               .stream_name = "HiFi Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rate_min =     8000,
+               .rate_max =     48000,
+               .rates = SNDRV_PCM_RATE_8000_48000,
+               .formats = ALC5632_FORMATS,},
+
+       .ops = &alc5632_dai_ops,
+       .symmetric_rates = 1,
+};
+
+#ifdef CONFIG_PM
+static int alc5632_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
+{
+       alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static int alc5632_resume(struct snd_soc_codec *codec)
+{
+       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+
+       regcache_sync(alc5632->regmap);
+
+       alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       return 0;
+}
+#else
+#define        alc5632_suspend NULL
+#define        alc5632_resume  NULL
+#endif
+
+static int alc5632_probe(struct snd_soc_codec *codec)
+{
+       struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
+       int ret;
+
+       codec->control_data = alc5632->regmap;
+
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
+
+       /* power on device  */
+       alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       switch (alc5632->id) {
+       case 0x5c:
+               snd_soc_add_controls(codec, alc5632_vol_snd_controls,
+                       ARRAY_SIZE(alc5632_vol_snd_controls));
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+/* power down chip */
+static int alc5632_remove(struct snd_soc_codec *codec)
+{
+       alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
+       .probe = alc5632_probe,
+       .remove = alc5632_remove,
+       .suspend = alc5632_suspend,
+       .resume = alc5632_resume,
+       .set_bias_level = alc5632_set_bias_level,
+       .controls = alc5632_snd_controls,
+       .num_controls = ARRAY_SIZE(alc5632_snd_controls),
+       .dapm_widgets = alc5632_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets),
+       .dapm_routes = alc5632_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
+};
+
+static struct regmap_config alc5632_regmap = {
+       .reg_bits = 8,
+       .val_bits = 16,
+
+       .max_register = ALC5632_MAX_REGISTER,
+       .reg_defaults = alc5632_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults),
+       .volatile_reg = alc5632_volatile_register,
+       .cache_type = REGCACHE_RBTREE,
+};
+
+/*
+ * alc5632 2 wire address is determined by A1 pin
+ * state during powerup.
+ *    low  = 0x1a
+ *    high = 0x1b
+ */
+static __devinit int alc5632_i2c_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+{
+       struct alc5632_priv *alc5632;
+       int ret, ret1, ret2;
+       unsigned int vid1, vid2;
+
+       alc5632 = devm_kzalloc(&client->dev,
+                        sizeof(struct alc5632_priv), GFP_KERNEL);
+       if (alc5632 == NULL)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, alc5632);
+
+       alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap);
+       if (IS_ERR(alc5632->regmap)) {
+               ret = PTR_ERR(alc5632->regmap);
+               dev_err(&client->dev, "regmap_init() failed: %d\n", ret);
+               return ret;
+       }
+
+       ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1);
+       ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2);
+       if (ret1 != 0 || ret2 != 0) {
+               dev_err(&client->dev,
+               "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);
+               regmap_exit(alc5632->regmap);
+               return -EIO;
+       }
+
+       vid2 >>= 8;
+
+       if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
+               dev_err(&client->dev,
+               "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
+               regmap_exit(alc5632->regmap);
+               return -EINVAL;
+       }
+
+       ret = alc5632_reset(alc5632->regmap);
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to issue reset\n");
+               regmap_exit(alc5632->regmap);
+               return ret;
+       }
+
+       alc5632->id = vid2;
+       switch (alc5632->id) {
+       case 0x5c:
+               alc5632_dai.name = "alc5632-hifi";
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = snd_soc_register_codec(&client->dev,
+               &soc_codec_device_alc5632, &alc5632_dai, 1);
+
+       if (ret < 0) {
+               dev_err(&client->dev, "Failed to register codec: %d\n", ret);
+               regmap_exit(alc5632->regmap);
+               return ret;
+       }
+
+       return ret;
+}
+
+static int alc5632_i2c_remove(struct i2c_client *client)
+{
+       struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
+       snd_soc_unregister_codec(&client->dev);
+       regmap_exit(alc5632->regmap);
+       return 0;
+}
+
+static const struct i2c_device_id alc5632_i2c_table[] = {
+       {"alc5632", 0x5c},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
+
+/* i2c codec control layer */
+static struct i2c_driver alc5632_i2c_driver = {
+       .driver = {
+               .name = "alc5632",
+               .owner = THIS_MODULE,
+       },
+       .probe = alc5632_i2c_probe,
+       .remove =  __devexit_p(alc5632_i2c_remove),
+       .id_table = alc5632_i2c_table,
+};
+
+static int __init alc5632_modinit(void)
+{
+       int ret;
+
+       ret = i2c_add_driver(&alc5632_i2c_driver);
+       if (ret != 0) {
+               printk(KERN_ERR "%s: can't add i2c driver", __func__);
+               return ret;
+       }
+
+       return ret;
+}
+module_init(alc5632_modinit);
+
+static void __exit alc5632_modexit(void)
+{
+       i2c_del_driver(&alc5632_i2c_driver);
+}
+module_exit(alc5632_modexit);
+
+MODULE_DESCRIPTION("ASoC ALC5632 driver");
+MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h
new file mode 100644 (file)
index 0000000..357651e
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+* alc5632.h  --  ALC5632 ALSA SoC Audio Codec
+*
+* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
+*
+* Authors:  Leon Romanovsky <leon@leon.nu>
+*           Andrey Danin <danindrey@mail.ru>
+*           Ilya Petrov <ilya.muromec@gmail.com>
+*           Marc Dietrich <marvin24@gmx.de>
+*
+* Based on alc5623.h by Arnaud Patard
+*
+* 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 _ALC5632_H
+#define _ALC5632_H
+
+#define ALC5632_RESET                          0x00
+/* speaker output vol             2    2           */
+/* line output vol                      4    2      */
+/* HP output vol                  4    0    4      */
+#define ALC5632_SPK_OUT_VOL                    0x02 /* spe out vol */
+#define ALC5632_SPK_OUT_VOL_STEP               1.5
+#define ALC5632_HP_OUT_VOL                     0x04 /* hp out vol */
+#define ALC5632_AUX_OUT_VOL                    0x06 /* aux out vol */
+#define ALC5632_PHONE_IN_VOL                   0x08 /* phone in vol */
+#define ALC5632_LINE_IN_VOL                    0x0A /* line in vol */
+#define ALC5632_STEREO_DAC_IN_VOL              0x0C /* stereo dac in vol */
+#define ALC5632_MIC_VOL                                0x0E /* mic in vol */
+/* stero dac/mic routing */
+#define ALC5632_MIC_ROUTING_CTRL               0x10
+#define ALC5632_MIC_ROUTE_MONOMIX              (1 << 0)
+#define ALC5632_MIC_ROUTE_SPK                  (1 << 1)
+#define ALC5632_MIC_ROUTE_HP                   (1 << 2)
+
+#define ALC5632_ADC_REC_GAIN                   0x12 /* rec gain */
+#define ALC5632_ADC_REC_GAIN_RANGE             0x1F1F
+#define ALC5632_ADC_REC_GAIN_BASE              (-16.5)
+#define ALC5632_ADC_REC_GAIN_STEP              1.5
+
+#define ALC5632_ADC_REC_MIXER                  0x14 /* mixer control */
+#define ALC5632_ADC_REC_MIC1                   (1 << 6)
+#define ALC5632_ADC_REC_MIC2                   (1 << 5)
+#define ALC5632_ADC_REC_LINE_IN                        (1 << 4)
+#define ALC5632_ADC_REC_AUX                    (1 << 3)
+#define ALC5632_ADC_REC_HP                     (1 << 2)
+#define ALC5632_ADC_REC_SPK                    (1 << 1)
+#define ALC5632_ADC_REC_MONOMIX                        (1 << 0)
+
+#define ALC5632_VOICE_DAC_VOL                  0x18 /* voice dac vol */
+/* ALC5632_OUTPUT_MIXER_CTRL :                 */
+/* same remark as for reg 2 line vs speaker    */
+#define ALC5632_OUTPUT_MIXER_CTRL              0x1C /* out mix ctrl */
+#define ALC5632_OUTPUT_MIXER_RP                        (1 << 14)
+#define ALC5632_OUTPUT_MIXER_WEEK              (1 << 12)
+#define ALC5632_OUTPUT_MIXER_HP                        (1 << 10)
+#define ALC5632_OUTPUT_MIXER_AUX_SPK           (2 <<  6)
+#define ALC5632_OUTPUT_MIXER_AUX_HP_LR          (1 << 6)
+#define ALC5632_OUTPUT_MIXER_HP_R               (1 << 8)
+#define ALC5632_OUTPUT_MIXER_HP_L               (1 << 9)
+
+#define ALC5632_MIC_CTRL                       0x22 /* mic phone ctrl */
+#define ALC5632_MIC_BOOST_BYPASS               0
+#define ALC5632_MIC_BOOST_20DB                 1
+#define ALC5632_MIC_BOOST_30DB                 2
+#define ALC5632_MIC_BOOST_40DB                 3
+
+#define ALC5632_DIGI_BOOST_CTRL                        0x24 /* digi mic / bost ctl */
+#define ALC5632_MIC_BOOST_RANGE                        7
+#define ALC5632_MIC_BOOST_STEP                 6
+#define ALC5632_PWR_DOWN_CTRL_STATUS           0x26
+#define ALC5632_PWR_DOWN_CTRL_STATUS_MASK      0xEF00
+#define ALC5632_PWR_VREF_PR3                   (1 << 11)
+#define ALC5632_PWR_VREF_PR2                   (1 << 10)
+#define ALC5632_PWR_VREF_STATUS                        (1 << 3)
+#define ALC5632_PWR_AMIX_STATUS                        (1 << 2)
+#define ALC5632_PWR_DAC_STATUS                 (1 << 1)
+#define ALC5632_PWR_ADC_STATUS                 (1 << 0)
+/* stereo/voice DAC / stereo adc func ctrl */
+#define ALC5632_DAC_FUNC_SELECT                        0x2E
+
+/* Main serial data port ctrl (i2s) */
+#define ALC5632_DAI_CONTROL                    0x34
+
+#define ALC5632_DAI_SDP_MASTER_MODE            (0 << 15)
+#define ALC5632_DAI_SDP_SLAVE_MODE             (1 << 15)
+#define ALC5632_DAI_SADLRCK_MODE               (1 << 14)
+/* 0:voice, 1:main */
+#define ALC5632_DAI_MAIN_I2S_SYSCLK_SEL                (1 <<  8)
+#define ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL     (1 <<  7)
+/* 0:normal, 1:invert */
+#define ALC5632_DAI_MAIN_I2S_LRCK_INV          (1 <<  6)
+#define ALC5632_DAI_I2S_DL_MASK                        (3 <<  2)
+#define ALC5632_DAI_I2S_DL_8                   (3 <<  2)
+#define        ALC5632_DAI_I2S_DL_24                   (2 <<  2)
+#define        ALC5632_DAI_I2S_DL_20                   (1 <<  2)
+#define ALC5632_DAI_I2S_DL_16                  (0 <<  2)
+#define ALC5632_DAI_I2S_DF_MASK                        (3 <<  0)
+#define ALC5632_DAI_I2S_DF_PCM_B               (3 <<  0)
+#define        ALC5632_DAI_I2S_DF_PCM_A                (2 <<  0)
+#define ALC5632_DAI_I2S_DF_LEFT                        (1 <<  0)
+#define ALC5632_DAI_I2S_DF_I2S                 (0 <<  0)
+/* extend serial data port control (VoDAC_i2c/pcm) */
+#define ALC5632_DAI_CONTROL2                   0x36
+/* 0:gpio func, 1:voice pcm */
+#define ALC5632_DAI_VOICE_PCM_ENABLE           (1 << 15)
+/* 0:master, 1:slave */
+#define ALC5632_DAI_VOICE_MODE_SEL             (1 << 14)
+/* 0:disable, 1:enable */
+#define ALC5632_DAI_HPF_CLK_CTRL               (1 << 13)
+/* 0:main, 1:voice */
+#define ALC5632_DAI_VOICE_I2S_SYSCLK_SEL       (1 <<  8)
+/* 0:normal, 1:invert */
+#define ALC5632_DAI_VOICE_VBCLK_SYSCLK_SEL     (1 <<  7)
+/* 0:normal, 1:invert */
+#define ALC5632_DAI_VOICE_I2S_LR_INV           (1 <<  6)
+#define ALC5632_DAI_VOICE_DL_MASK              (3 <<  2)
+#define ALC5632_DAI_VOICE_DL_16                        (0 <<  2)
+#define ALC5632_DAI_VOICE_DL_20                        (1 <<  2)
+#define ALC5632_DAI_VOICE_DL_24                        (2 <<  2)
+#define ALC5632_DAI_VOICE_DL_8                 (3 <<  2)
+#define ALC5632_DAI_VOICE_DF_MASK              (3 <<  0)
+#define ALC5632_DAI_VOICE_DF_I2S               (0 <<  0)
+#define ALC5632_DAI_VOICE_DF_LEFT              (1 <<  0)
+#define ALC5632_DAI_VOICE_DF_PCM_A             (2 <<  0)
+#define ALC5632_DAI_VOICE_DF_PCM_B             (3 <<  0)
+
+#define        ALC5632_PWR_MANAG_ADD1                  0x3A
+#define        ALC5632_PWR_MANAG_ADD1_MASK             0xEFFF
+#define ALC5632_PWR_ADD1_DAC_L_EN              (1 << 15)
+#define ALC5632_PWR_ADD1_DAC_R_EN              (1 << 14)
+#define ALC5632_PWR_ADD1_ZERO_CROSS            (1 << 13)
+#define ALC5632_PWR_ADD1_MAIN_I2S_EN           (1 << 11)
+#define ALC5632_PWR_ADD1_SPK_AMP_EN            (1 << 10)
+#define ALC5632_PWR_ADD1_HP_OUT_AMP            (1 <<  9)
+#define ALC5632_PWR_ADD1_HP_OUT_ENH_AMP                (1 <<  8)
+#define ALC5632_PWR_ADD1_VOICE_DAC_MIX         (1 <<  7)
+#define        ALC5632_PWR_ADD1_SOFTGEN_EN             (1 <<  6)
+#define        ALC5632_PWR_ADD1_MIC1_SHORT_CURR        (1 <<  5)
+#define        ALC5632_PWR_ADD1_MIC2_SHORT_CURR        (1 <<  4)
+#define        ALC5632_PWR_ADD1_MIC1_EN                (1 <<  3)
+#define        ALC5632_PWR_ADD1_MIC2_EN                (1 <<  2)
+#define ALC5632_PWR_ADD1_MAIN_BIAS             (1 <<  1)
+#define ALC5632_PWR_ADD1_DAC_REF               (1 <<  0)
+
+#define ALC5632_PWR_MANAG_ADD2                 0x3C
+#define ALC5632_PWR_MANAG_ADD2_MASK            0x7FFF
+#define ALC5632_PWR_ADD2_PLL1                  (1 << 15)
+#define ALC5632_PWR_ADD2_PLL2                  (1 << 14)
+#define ALC5632_PWR_ADD2_VREF                  (1 << 13)
+#define ALC5632_PWR_ADD2_OVT_DET               (1 << 12)
+#define ALC5632_PWR_ADD2_VOICE_DAC             (1 << 10)
+#define ALC5632_PWR_ADD2_L_DAC_CLK             (1 <<  9)
+#define ALC5632_PWR_ADD2_R_DAC_CLK             (1 <<  8)
+#define ALC5632_PWR_ADD2_L_ADC_CLK_GAIN                (1 <<  7)
+#define ALC5632_PWR_ADD2_R_ADC_CLK_GAIN                (1 <<  6)
+#define ALC5632_PWR_ADD2_L_HP_MIXER            (1 <<  5)
+#define ALC5632_PWR_ADD2_R_HP_MIXER            (1 <<  4)
+#define ALC5632_PWR_ADD2_SPK_MIXER             (1 <<  3)
+#define ALC5632_PWR_ADD2_MONO_MIXER            (1 <<  2)
+#define ALC5632_PWR_ADD2_L_ADC_REC_MIXER       (1 <<  1)
+#define ALC5632_PWR_ADD2_R_ADC_REC_MIXER       (1 <<  0)
+
+#define ALC5632_PWR_MANAG_ADD3                 0x3E
+#define ALC5632_PWR_MANAG_ADD3_MASK            0x7CFF
+#define ALC5632_PWR_ADD3_AUXOUT_VOL            (1 << 14)
+#define ALC5632_PWR_ADD3_SPK_L_OUT             (1 << 13)
+#define ALC5632_PWR_ADD3_SPK_R_OUT             (1 << 12)
+#define ALC5632_PWR_ADD3_HP_L_OUT_VOL          (1 << 11)
+#define ALC5632_PWR_ADD3_HP_R_OUT_VOL          (1 << 10)
+#define ALC5632_PWR_ADD3_LINEIN_L_VOL          (1 <<  7)
+#define ALC5632_PWR_ADD3_LINEIN_R_VOL          (1 <<  6)
+#define ALC5632_PWR_ADD3_AUXIN_VOL             (1 <<  5)
+#define ALC5632_PWR_ADD3_AUXIN_MIX             (1 <<  4)
+#define ALC5632_PWR_ADD3_MIC1_VOL              (1 <<  3)
+#define ALC5632_PWR_ADD3_MIC2_VOL              (1 <<  2)
+#define ALC5632_PWR_ADD3_MIC1_BOOST_AD         (1 <<  1)
+#define ALC5632_PWR_ADD3_MIC2_BOOST_AD         (1 <<  0)
+
+#define ALC5632_GPCR1                          0x40
+#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1     (1 << 15)
+#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_MCLK     (0 << 15)
+#define ALC5632_GPCR1_DAC_HI_FLT_EN            (1 << 10)
+#define ALC5632_GPCR1_SPK_AMP_CTRL             (7 <<  1)
+#define ALC5632_GPCR1_VDD_100                  (5 <<  1)
+#define ALC5632_GPCR1_VDD_125                  (4 <<  1)
+#define ALC5632_GPCR1_VDD_150                  (3 <<  1)
+#define ALC5632_GPCR1_VDD_175                  (2 <<  1)
+#define ALC5632_GPCR1_VDD_200                  (1 <<  1)
+#define ALC5632_GPCR1_VDD_225                  (0 <<  1)
+
+#define        ALC5632_GPCR2                           0x42
+#define ALC5632_GPCR2_PLL1_SOUR_SEL            (3 << 12)
+#define ALC5632_PLL_FR_MCLK                    (0 << 12)
+#define ALC5632_PLL_FR_BCLK                    (2 << 12)
+#define ALC5632_PLL_FR_VBCLK                   (3 << 12)
+#define ALC5632_GPCR2_CLK_PLL_PRE_DIV1         (0 <<  0)
+
+#define ALC5632_PLL1_CTRL                      0x44
+#define ALC5632_PLL1_CTRL_N_VAL(n)             (((n) & 0x0f) << 8)
+#define ALC5632_PLL1_M_BYPASS                  (1 <<  7)
+#define ALC5632_PLL1_CTRL_K_VAL(k)             (((k) & 0x07) << 4)
+#define ALC5632_PLL1_CTRL_M_VAL(m)             (((m) & 0x0f) << 0)
+
+#define ALC5632_PLL2_CTRL                      0x46
+#define ALC5632_PLL2_EN                                (1 << 15)
+#define ALC5632_PLL2_RATIO                     (0 << 15)
+
+#define ALC5632_GPIO_PIN_CONFIG                        0x4C
+#define ALC5632_GPIO_PIN_POLARITY              0x4E
+#define ALC5632_GPIO_PIN_STICKY                        0x50
+#define ALC5632_GPIO_PIN_WAKEUP                        0x52
+#define ALC5632_GPIO_PIN_STATUS                        0x54
+#define ALC5632_GPIO_PIN_SHARING               0x56
+#define        ALC5632_OVER_CURR_STATUS                0x58
+#define ALC5632_SOFTVOL_CTRL                   0x5A
+#define ALC5632_GPIO_OUPUT_PIN_CTRL            0x5C
+
+#define ALC5632_MISC_CTRL                      0x5E
+#define ALC5632_MISC_DISABLE_FAST_VREG         (1 << 15)
+#define ALC5632_MISC_AVC_TRGT_SEL              (3 << 12)
+#define ALC5632_MISC_AVC_TRGT_RIGHT            (1 << 12)
+#define ALC5632_MISC_AVC_TRGT_LEFT             (2 << 12)
+#define ALC5632_MISC_AVC_TRGT_BOTH             (3 << 12)
+#define ALC5632_MISC_HP_DEPOP_MODE1_EN         (1 <<  9)
+#define ALC5632_MISC_HP_DEPOP_MODE2_EN         (1 <<  8)
+#define ALC5632_MISC_HP_DEPOP_MUTE_L           (1 <<  7)
+#define ALC5632_MISC_HP_DEPOP_MUTE_R           (1 <<  6)
+#define ALC5632_MISC_HP_DEPOP_MUTE             (1 <<  5)
+#define ALC5632_MISC_GPIO_WAKEUP_CTRL          (1 <<  1)
+#define ALC5632_MISC_IRQOUT_INV_CTRL           (1 <<  0)
+
+#define ALC5632_DAC_CLK_CTRL1                  0x60
+#define ALC5632_DAC_CLK_CTRL2                  0x62
+#define ALC5632_DAC_CLK_CTRL2_DIV1_2           (1 << 0)
+#define ALC5632_VOICE_DAC_PCM_CLK_CTRL1                0x64
+#define ALC5632_PSEUDO_SPATIAL_CTRL            0x68
+#define ALC5632_HID_CTRL_INDEX                 0x6A
+#define ALC5632_HID_CTRL_DATA                  0x6C
+#define ALC5632_EQ_CTRL                                0x6E
+
+/* undocumented */
+#define ALC5632_VENDOR_ID1                     0x7C
+#define ALC5632_VENDOR_ID2                     0x7E
+
+#define ALC5632_MAX_REGISTER        0x7E
+
+#endif
index 46dbfd067f79647b7fca338eb85addd177eda966..4854b472d5fdb98ca5d6cae18863286a17f3b408 100644 (file)
@@ -122,7 +122,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
 #define CQ93VC_RATES   (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
 #define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
 
-static struct snd_soc_dai_ops cq93vc_dai_ops = {
+static const struct snd_soc_dai_ops cq93vc_dai_ops = {
        .digital_mute   = cq93vc_mute,
        .set_sysclk     = cq93vc_set_dai_sysclk,
 };
@@ -206,17 +206,7 @@ static struct platform_driver cq93vc_codec_driver = {
        .remove = __devexit_p(cq93vc_platform_remove),
 };
 
-static int __init cq93vc_init(void)
-{
-       return platform_driver_register(&cq93vc_codec_driver);
-}
-module_init(cq93vc_init);
-
-static void __exit cq93vc_exit(void)
-{
-       platform_driver_unregister(&cq93vc_codec_driver);
-}
-module_exit(cq93vc_exit);
+module_platform_driver(cq93vc_codec_driver);
 
 MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver");
 MODULE_AUTHOR("Miguel Aguilar");
index 73f46eb459f15fa43c5aadc89c2d5a61346fb351..dc77ff7ba339719075d520f4d730a25924ab4656 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/soc.h>
@@ -447,7 +446,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
                snd_soc_get_volsw, cs4270_soc_put_mute),
 };
 
-static struct snd_soc_dai_ops cs4270_dai_ops = {
+static const struct snd_soc_dai_ops cs4270_dai_ops = {
        .hw_params      = cs4270_hw_params,
        .set_sysclk     = cs4270_set_dai_sysclk,
        .set_fmt        = cs4270_set_dai_fmt,
index 69fde1506fe1fde2fe312ff80176723171ccef07..a6f77a855f45273a7f831f8a7320ddb119f4e6ff 100644 (file)
@@ -402,7 +402,7 @@ static const struct snd_kcontrol_new cs4271_snd_controls[] = {
                7, 1, 1),
 };
 
-static struct snd_soc_dai_ops cs4271_dai_ops = {
+static const struct snd_soc_dai_ops cs4271_dai_ops = {
        .hw_params      = cs4271_hw_params,
        .set_sysclk     = cs4271_set_dai_sysclk,
        .set_fmt        = cs4271_set_dai_fmt,
index 1ee66361f61b946e5738798daf03d61baf2f8ecb..528510b8e5de4962441e1352bed424c7fae53c84 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/soc.h>
@@ -175,21 +174,18 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
 static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
-       unsigned long value;
-
-       value = snd_soc_read(w->codec, CS42L51_POWER_CTL1);
-       value &= ~CS42L51_POWER_CTL1_PDN;
-
        switch (event) {
        case SND_SOC_DAPM_PRE_PMD:
-               value |= CS42L51_POWER_CTL1_PDN;
+               snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
+                                   CS42L51_POWER_CTL1_PDN,
+                                   CS42L51_POWER_CTL1_PDN);
                break;
        default:
        case SND_SOC_DAPM_POST_PMD:
+               snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
+                                   CS42L51_POWER_CTL1_PDN, 0);
                break;
        }
-       snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1,
-               CS42L51_POWER_CTL1_PDN, value);
 
        return 0;
 }
@@ -486,7 +482,7 @@ static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute)
        return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg);
 }
 
-static struct snd_soc_dai_ops cs42l51_dai_ops = {
+static const struct snd_soc_dai_ops cs42l51_dai_ops = {
        .hw_params      = cs42l51_hw_params,
        .set_sysclk     = cs42l51_set_dai_sysclk,
        .set_fmt        = cs42l51_set_dai_fmt,
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
new file mode 100644 (file)
index 0000000..9fd5de7
--- /dev/null
@@ -0,0 +1,1452 @@
+/*
+ * cs42l73.c  --  CS42L73 ALSA Soc Audio driver
+ *
+ * Copyright 2011 Cirrus Logic, Inc.
+ *
+ * Authors: Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>
+ *         Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include "cs42l73.h"
+
+struct sp_config {
+       u8 spc, mmcc, spfs;
+       u32 srate;
+};
+struct  cs42l73_private {
+       struct sp_config config[3];
+       struct regmap *regmap;
+       u32 sysclk;
+       u8 mclksel;
+       u32 mclk;
+};
+
+static const struct reg_default cs42l73_reg_defaults[] = {
+       { 1, 0x42 },    /* r01  - Device ID A&B */
+       { 2, 0xA7 },    /* r02  - Device ID C&D */
+       { 3, 0x30 },    /* r03  - Device ID E */
+       { 6, 0xF1 },    /* r06  - Power Ctl 1 */
+       { 7, 0xDF },    /* r07  - Power Ctl 2 */
+       { 8, 0x3F },    /* r08  - Power Ctl 3 */
+       { 9, 0x50 },    /* r09  - Charge Pump Freq */
+       { 10, 0x53 },   /* r0A  - Output Load MicBias Short Detect */
+       { 11, 0x00 },   /* r0B  - DMIC Master Clock Ctl */
+       { 12, 0x00 },   /* r0C  - Aux PCM Ctl */
+       { 13, 0x15 },   /* r0D  - Aux PCM Master Clock Ctl */
+       { 14, 0x00 },   /* r0E  - Audio PCM Ctl */
+       { 15, 0x15 },   /* r0F  - Audio PCM Master Clock Ctl */
+       { 16, 0x00 },   /* r10  - Voice PCM Ctl */
+       { 17, 0x15 },   /* r11  - Voice PCM Master Clock Ctl */
+       { 18, 0x00 },   /* r12  - Voice/Aux Sample Rate */
+       { 19, 0x06 },   /* r13  - Misc I/O Path Ctl */
+       { 20, 0x00 },   /* r14  - ADC Input Path Ctl */
+       { 21, 0x00 },   /* r15  - MICA Preamp, PGA Volume */
+       { 22, 0x00 },   /* r16  - MICB Preamp, PGA Volume */
+       { 23, 0x00 },   /* r17  - Input Path A Digital Volume */
+       { 24, 0x00 },   /* r18  - Input Path B Digital Volume */
+       { 25, 0x00 },   /* r19  - Playback Digital Ctl */
+       { 26, 0x00 },   /* r1A  - HP/LO Left Digital Volume */
+       { 27, 0x00 },   /* r1B  - HP/LO Right Digital Volume */
+       { 28, 0x00 },   /* r1C  - Speakerphone Digital Volume */
+       { 29, 0x00 },   /* r1D  - Ear/SPKLO Digital Volume */
+       { 30, 0x00 },   /* r1E  - HP Left Analog Volume */
+       { 31, 0x00 },   /* r1F  - HP Right Analog Volume */
+       { 32, 0x00 },   /* r20  - LO Left Analog Volume */
+       { 33, 0x00 },   /* r21  - LO Right Analog Volume */
+       { 34, 0x00 },   /* r22  - Stereo Input Path Advisory Volume */
+       { 35, 0x00 },   /* r23  - Aux PCM Input Advisory Volume */
+       { 36, 0x00 },   /* r24  - Audio PCM Input Advisory Volume */
+       { 37, 0x00 },   /* r25  - Voice PCM Input Advisory Volume */
+       { 38, 0x00 },   /* r26  - Limiter Attack Rate HP/LO */
+       { 39, 0x7F },   /* r27  - Limter Ctl, Release Rate HP/LO */
+       { 40, 0x00 },   /* r28  - Limter Threshold HP/LO */
+       { 41, 0x00 },   /* r29  - Limiter Attack Rate Speakerphone */
+       { 42, 0x3F },   /* r2A  - Limter Ctl, Release Rate Speakerphone */
+       { 43, 0x00 },   /* r2B  - Limter Threshold Speakerphone */
+       { 44, 0x00 },   /* r2C  - Limiter Attack Rate Ear/SPKLO */
+       { 45, 0x3F },   /* r2D  - Limter Ctl, Release Rate Ear/SPKLO */
+       { 46, 0x00 },   /* r2E  - Limter Threshold Ear/SPKLO */
+       { 47, 0x00 },   /* r2F  - ALC Enable, Attack Rate Left/Right */
+       { 48, 0x3F },   /* r30  - ALC Release Rate Left/Right */
+       { 49, 0x00 },   /* r31  - ALC Threshold Left/Right */
+       { 50, 0x00 },   /* r32  - Noise Gate Ctl Left/Right */
+       { 51, 0x00 },   /* r33  - ALC/NG Misc Ctl */
+       { 52, 0x18 },   /* r34  - Mixer Ctl */
+       { 53, 0x3F },   /* r35  - HP/LO Left Mixer Input Path Volume */
+       { 54, 0x3F },   /* r36  - HP/LO Right Mixer Input Path Volume */
+       { 55, 0x3F },   /* r37  - HP/LO Left Mixer Aux PCM Volume */
+       { 56, 0x3F },   /* r38  - HP/LO Right Mixer Aux PCM Volume */
+       { 57, 0x3F },   /* r39  - HP/LO Left Mixer Audio PCM Volume */
+       { 58, 0x3F },   /* r3A  - HP/LO Right Mixer Audio PCM Volume */
+       { 59, 0x3F },   /* r3B  - HP/LO Left Mixer Voice PCM Mono Volume */
+       { 60, 0x3F },   /* r3C  - HP/LO Right Mixer Voice PCM Mono Volume */
+       { 61, 0x3F },   /* r3D  - Aux PCM Left Mixer Input Path Volume */
+       { 62, 0x3F },   /* r3E  - Aux PCM Right Mixer Input Path Volume */
+       { 63, 0x3F },   /* r3F  - Aux PCM Left Mixer Volume */
+       { 64, 0x3F },   /* r40  - Aux PCM Left Mixer Volume */
+       { 65, 0x3F },   /* r41  - Aux PCM Left Mixer Audio PCM L Volume */
+       { 66, 0x3F },   /* r42  - Aux PCM Right Mixer Audio PCM R Volume */
+       { 67, 0x3F },   /* r43  - Aux PCM Left Mixer Voice PCM Volume */
+       { 68, 0x3F },   /* r44  - Aux PCM Right Mixer Voice PCM Volume */
+       { 69, 0x3F },   /* r45  - Audio PCM Left Input Path Volume */
+       { 70, 0x3F },   /* r46  - Audio PCM Right Input Path Volume */
+       { 71, 0x3F },   /* r47  - Audio PCM Left Mixer Aux PCM L Volume */
+       { 72, 0x3F },   /* r48  - Audio PCM Right Mixer Aux PCM R Volume */
+       { 73, 0x3F },   /* r49  - Audio PCM Left Mixer Volume */
+       { 74, 0x3F },   /* r4A  - Audio PCM Right Mixer Volume */
+       { 75, 0x3F },   /* r4B  - Audio PCM Left Mixer Voice PCM Volume */
+       { 76, 0x3F },   /* r4C  - Audio PCM Right Mixer Voice PCM Volume */
+       { 77, 0x3F },   /* r4D  - Voice PCM Left Input Path Volume */
+       { 78, 0x3F },   /* r4E  - Voice PCM Right Input Path Volume */
+       { 79, 0x3F },   /* r4F  - Voice PCM Left Mixer Aux PCM L Volume */
+       { 80, 0x3F },   /* r50  - Voice PCM Right Mixer Aux PCM R Volume */
+       { 81, 0x3F },   /* r51  - Voice PCM Left Mixer Audio PCM L Volume */
+       { 82, 0x3F },   /* r52  - Voice PCM Right Mixer Audio PCM R Volume */
+       { 83, 0x3F },   /* r53  - Voice PCM Left Mixer Voice PCM Volume */
+       { 84, 0x3F },   /* r54  - Voice PCM Right Mixer Voice PCM Volume */
+       { 85, 0xAA },   /* r55  - Mono Mixer Ctl */
+       { 86, 0x3F },   /* r56  - SPK Mono Mixer Input Path Volume */
+       { 87, 0x3F },   /* r57  - SPK Mono Mixer Aux PCM Mono/L/R Volume */
+       { 88, 0x3F },   /* r58  - SPK Mono Mixer Audio PCM Mono/L/R Volume */
+       { 89, 0x3F },   /* r59  - SPK Mono Mixer Voice PCM Mono Volume */
+       { 90, 0x3F },   /* r5A  - SPKLO Mono Mixer Input Path Mono Volume */
+       { 91, 0x3F },   /* r5B  - SPKLO Mono Mixer Aux Mono/L/R Volume */
+       { 92, 0x3F },   /* r5C  - SPKLO Mono Mixer Audio Mono/L/R Volume */
+       { 93, 0x3F },   /* r5D  - SPKLO Mono Mixer Voice Mono Volume */
+       { 94, 0x00 },   /* r5E  - Interrupt Mask 1 */
+       { 95, 0x00 },   /* r5F  - Interrupt Mask 2 */
+};
+
+static bool cs42l73_volatile_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case CS42L73_IS1:
+       case CS42L73_IS2:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool cs42l73_readable_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case CS42L73_DEVID_AB:
+       case CS42L73_DEVID_CD:
+       case CS42L73_DEVID_E:
+       case CS42L73_REVID:
+       case CS42L73_PWRCTL1:
+       case CS42L73_PWRCTL2:
+       case CS42L73_PWRCTL3:
+       case CS42L73_CPFCHC:
+       case CS42L73_OLMBMSDC:
+       case CS42L73_DMMCC:
+       case CS42L73_XSPC:
+       case CS42L73_XSPMMCC:
+       case CS42L73_ASPC:
+       case CS42L73_ASPMMCC:
+       case CS42L73_VSPC:
+       case CS42L73_VSPMMCC:
+       case CS42L73_VXSPFS:
+       case CS42L73_MIOPC:
+       case CS42L73_ADCIPC:
+       case CS42L73_MICAPREPGAAVOL:
+       case CS42L73_MICBPREPGABVOL:
+       case CS42L73_IPADVOL:
+       case CS42L73_IPBDVOL:
+       case CS42L73_PBDC:
+       case CS42L73_HLADVOL:
+       case CS42L73_HLBDVOL:
+       case CS42L73_SPKDVOL:
+       case CS42L73_ESLDVOL:
+       case CS42L73_HPAAVOL:
+       case CS42L73_HPBAVOL:
+       case CS42L73_LOAAVOL:
+       case CS42L73_LOBAVOL:
+       case CS42L73_STRINV:
+       case CS42L73_XSPINV:
+       case CS42L73_ASPINV:
+       case CS42L73_VSPINV:
+       case CS42L73_LIMARATEHL:
+       case CS42L73_LIMRRATEHL:
+       case CS42L73_LMAXHL:
+       case CS42L73_LIMARATESPK:
+       case CS42L73_LIMRRATESPK:
+       case CS42L73_LMAXSPK:
+       case CS42L73_LIMARATEESL:
+       case CS42L73_LIMRRATEESL:
+       case CS42L73_LMAXESL:
+       case CS42L73_ALCARATE:
+       case CS42L73_ALCRRATE:
+       case CS42L73_ALCMINMAX:
+       case CS42L73_NGCAB:
+       case CS42L73_ALCNGMC:
+       case CS42L73_MIXERCTL:
+       case CS42L73_HLAIPAA:
+       case CS42L73_HLBIPBA:
+       case CS42L73_HLAXSPAA:
+       case CS42L73_HLBXSPBA:
+       case CS42L73_HLAASPAA:
+       case CS42L73_HLBASPBA:
+       case CS42L73_HLAVSPMA:
+       case CS42L73_HLBVSPMA:
+       case CS42L73_XSPAIPAA:
+       case CS42L73_XSPBIPBA:
+       case CS42L73_XSPAXSPAA:
+       case CS42L73_XSPBXSPBA:
+       case CS42L73_XSPAASPAA:
+       case CS42L73_XSPAASPBA:
+       case CS42L73_XSPAVSPMA:
+       case CS42L73_XSPBVSPMA:
+       case CS42L73_ASPAIPAA:
+       case CS42L73_ASPBIPBA:
+       case CS42L73_ASPAXSPAA:
+       case CS42L73_ASPBXSPBA:
+       case CS42L73_ASPAASPAA:
+       case CS42L73_ASPBASPBA:
+       case CS42L73_ASPAVSPMA:
+       case CS42L73_ASPBVSPMA:
+       case CS42L73_VSPAIPAA:
+       case CS42L73_VSPBIPBA:
+       case CS42L73_VSPAXSPAA:
+       case CS42L73_VSPBXSPBA:
+       case CS42L73_VSPAASPAA:
+       case CS42L73_VSPBASPBA:
+       case CS42L73_VSPAVSPMA:
+       case CS42L73_VSPBVSPMA:
+       case CS42L73_MMIXCTL:
+       case CS42L73_SPKMIPMA:
+       case CS42L73_SPKMXSPA:
+       case CS42L73_SPKMASPA:
+       case CS42L73_SPKMVSPMA:
+       case CS42L73_ESLMIPMA:
+       case CS42L73_ESLMXSPA:
+       case CS42L73_ESLMASPA:
+       case CS42L73_ESLMVSPMA:
+       case CS42L73_IM1:
+       case CS42L73_IM2:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const unsigned int hpaloa_tlv[] = {
+       TLV_DB_RANGE_HEAD(2),
+       0, 13, TLV_DB_SCALE_ITEM(-7600, 200, 0),
+       14, 75, TLV_DB_SCALE_ITEM(-4900, 100, 0),
+};
+
+static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2500, 0);
+
+static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0);
+
+static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0);
+
+static DECLARE_TLV_DB_SCALE(micpga_tlv, -600, 50, 0);
+
+static const unsigned int limiter_tlv[] = {
+       TLV_DB_RANGE_HEAD(2),
+       0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
+       3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0),
+};
+
+static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1);
+
+static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" };
+static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" };
+
+static const struct soc_enum pgaa_enum =
+       SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3,
+               ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text);
+
+static const struct soc_enum pgab_enum =
+       SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7,
+               ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text);
+
+static const struct snd_kcontrol_new pgaa_mux =
+       SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum);
+
+static const struct snd_kcontrol_new pgab_mux =
+       SOC_DAPM_ENUM("Right Analog Input Capture Mux", pgab_enum);
+
+static const struct snd_kcontrol_new input_left_mixer[] = {
+       SOC_DAPM_SINGLE("ADC Left Input", CS42L73_PWRCTL1,
+                       5, 1, 1),
+       SOC_DAPM_SINGLE("DMIC Left Input", CS42L73_PWRCTL1,
+                       4, 1, 1),
+};
+
+static const struct snd_kcontrol_new input_right_mixer[] = {
+       SOC_DAPM_SINGLE("ADC Right Input", CS42L73_PWRCTL1,
+                       7, 1, 1),
+       SOC_DAPM_SINGLE("DMIC Right Input", CS42L73_PWRCTL1,
+                       6, 1, 1),
+};
+
+static const char * const cs42l73_ng_delay_text[] = {
+       "50ms", "100ms", "150ms", "200ms" };
+
+static const struct soc_enum ng_delay_enum =
+       SOC_ENUM_SINGLE(CS42L73_NGCAB, 0,
+               ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text);
+
+static const char * const charge_pump_freq_text[] = {
+       "0", "1", "2", "3", "4",
+       "5", "6", "7", "8", "9",
+       "10", "11", "12", "13", "14", "15" };
+
+static const struct soc_enum charge_pump_enum =
+       SOC_ENUM_SINGLE(CS42L73_CPFCHC, 4,
+               ARRAY_SIZE(charge_pump_freq_text), charge_pump_freq_text);
+
+static const char * const cs42l73_mono_mix_texts[] = {
+       "Left", "Right", "Mono Mix"};
+
+static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 };
+
+static const struct soc_enum spk_asp_enum =
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1,
+                             ARRAY_SIZE(cs42l73_mono_mix_texts),
+                             cs42l73_mono_mix_texts,
+                             cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new spk_asp_mixer =
+       SOC_DAPM_ENUM("Route", spk_asp_enum);
+
+static const struct soc_enum spk_xsp_enum =
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 4, 3,
+                             ARRAY_SIZE(cs42l73_mono_mix_texts),
+                             cs42l73_mono_mix_texts,
+                             cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new spk_xsp_mixer =
+       SOC_DAPM_ENUM("Route", spk_xsp_enum);
+
+static const struct soc_enum esl_asp_enum =
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5,
+                             ARRAY_SIZE(cs42l73_mono_mix_texts),
+                             cs42l73_mono_mix_texts,
+                             cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new esl_asp_mixer =
+       SOC_DAPM_ENUM("Route", esl_asp_enum);
+
+static const struct soc_enum esl_xsp_enum =
+       SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7,
+                             ARRAY_SIZE(cs42l73_mono_mix_texts),
+                             cs42l73_mono_mix_texts,
+                             cs42l73_mono_mix_values);
+
+static const struct snd_kcontrol_new esl_xsp_mixer =
+       SOC_DAPM_ENUM("Route", esl_xsp_enum);
+
+static const char * const cs42l73_ip_swap_text[] = {
+       "Stereo", "Mono A", "Mono B", "Swap A-B"};
+
+static const struct soc_enum ip_swap_enum =
+       SOC_ENUM_SINGLE(CS42L73_MIOPC, 6,
+               ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text);
+
+static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"};
+
+static const struct soc_enum vsp_output_mux_enum =
+       SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5,
+               ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
+
+static const struct soc_enum xsp_output_mux_enum =
+       SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4,
+               ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text);
+
+static const struct snd_kcontrol_new vsp_output_mux =
+       SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
+
+static const struct snd_kcontrol_new xsp_output_mux =
+       SOC_DAPM_ENUM("Route", xsp_output_mux_enum);
+
+static const struct snd_kcontrol_new hp_amp_ctl =
+       SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1);
+
+static const struct snd_kcontrol_new lo_amp_ctl =
+       SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 1, 1, 1);
+
+static const struct snd_kcontrol_new spk_amp_ctl =
+       SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 2, 1, 1);
+
+static const struct snd_kcontrol_new spklo_amp_ctl =
+       SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 4, 1, 1);
+
+static const struct snd_kcontrol_new ear_amp_ctl =
+       SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 3, 1, 1);
+
+static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
+       SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume",
+                       CS42L73_HPAAVOL, CS42L73_HPBAVOL, 7,
+                       0xffffffC1, 0x0C, hpaloa_tlv),
+
+       SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL,
+                       CS42L73_LOBAVOL, 7, 0xffffffC1, 0x0C, hpaloa_tlv),
+
+       SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL,
+                       CS42L73_MICBPREPGABVOL, 5, 0xffffff35,
+                       0x34, micpga_tlv),
+
+       SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL,
+                       CS42L73_MICBPREPGABVOL, 6, 1, 1),
+
+       SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL,
+                       CS42L73_IPBDVOL, 7, 0xffffffA0, 0xA0, ipd_tlv),
+
+       SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume",
+                       CS42L73_HLADVOL, CS42L73_HLBDVOL, 7, 0xffffffE5,
+                       0xE4, hl_tlv),
+
+       SOC_SINGLE_TLV("ADC A Boost Volume",
+                       CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv),
+
+       SOC_SINGLE_TLV("ADC B Boost Volume",
+                       CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv),
+
+       SOC_SINGLE_TLV("Speakerphone Digital Playback Volume",
+                       CS42L73_SPKDVOL, 0, 0xE4, 1, hl_tlv),
+
+       SOC_SINGLE_TLV("Ear Speaker Digital Playback Volume",
+                       CS42L73_ESLDVOL, 0, 0xE4, 1, hl_tlv),
+
+       SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL,
+                       CS42L73_HPBAVOL, 7, 1, 1),
+
+       SOC_DOUBLE_R("LineOut Analog Playback Switch", CS42L73_LOAAVOL,
+                       CS42L73_LOBAVOL, 7, 1, 1),
+       SOC_DOUBLE("Input Path Digital Switch", CS42L73_ADCIPC, 0, 4, 1, 1),
+       SOC_DOUBLE("HL Digital Playback Switch", CS42L73_PBDC, 0,
+                       1, 1, 1),
+       SOC_SINGLE("Speakerphone Digital Playback Switch", CS42L73_PBDC, 2, 1,
+                       1),
+       SOC_SINGLE("Ear Speaker Digital Playback Switch", CS42L73_PBDC, 3, 1,
+                       1),
+
+       SOC_SINGLE("PGA Soft-Ramp Switch", CS42L73_MIOPC, 3, 1, 0),
+       SOC_SINGLE("Analog Zero Cross Switch", CS42L73_MIOPC, 2, 1, 0),
+       SOC_SINGLE("Digital Soft-Ramp Switch", CS42L73_MIOPC, 1, 1, 0),
+       SOC_SINGLE("Analog Output Soft-Ramp Switch", CS42L73_MIOPC, 0, 1, 0),
+
+       SOC_DOUBLE("ADC Signal Polarity Switch", CS42L73_ADCIPC, 1, 5, 1,
+                       0),
+
+       SOC_SINGLE("HL Limiter Attack Rate", CS42L73_LIMARATEHL, 0, 0x3F,
+                       0),
+       SOC_SINGLE("HL Limiter Release Rate", CS42L73_LIMRRATEHL, 0,
+                       0x3F, 0),
+
+
+       SOC_SINGLE("HL Limiter Switch", CS42L73_LIMRRATEHL, 7, 1, 0),
+       SOC_SINGLE("HL Limiter All Channels Switch", CS42L73_LIMRRATEHL, 6, 1,
+                       0),
+
+       SOC_SINGLE_TLV("HL Limiter Max Threshold Volume", CS42L73_LMAXHL, 5, 7,
+                       1, limiter_tlv),
+
+       SOC_SINGLE_TLV("HL Limiter Cushion Volume", CS42L73_LMAXHL, 2, 7, 1,
+                       limiter_tlv),
+
+       SOC_SINGLE("SPK Limiter Attack Rate Volume", CS42L73_LIMARATESPK, 0,
+                       0x3F, 0),
+       SOC_SINGLE("SPK Limiter Release Rate Volume", CS42L73_LIMRRATESPK, 0,
+                       0x3F, 0),
+       SOC_SINGLE("SPK Limiter Switch", CS42L73_LIMRRATESPK, 7, 1, 0),
+       SOC_SINGLE("SPK Limiter All Channels Switch", CS42L73_LIMRRATESPK,
+                       6, 1, 0),
+       SOC_SINGLE_TLV("SPK Limiter Max Threshold Volume", CS42L73_LMAXSPK, 5,
+                       7, 1, limiter_tlv),
+
+       SOC_SINGLE_TLV("SPK Limiter Cushion Volume", CS42L73_LMAXSPK, 2, 7, 1,
+                       limiter_tlv),
+
+       SOC_SINGLE("ESL Limiter Attack Rate Volume", CS42L73_LIMARATEESL, 0,
+                       0x3F, 0),
+       SOC_SINGLE("ESL Limiter Release Rate Volume", CS42L73_LIMRRATEESL, 0,
+                       0x3F, 0),
+       SOC_SINGLE("ESL Limiter Switch", CS42L73_LIMRRATEESL, 7, 1, 0),
+       SOC_SINGLE_TLV("ESL Limiter Max Threshold Volume", CS42L73_LMAXESL, 5,
+                       7, 1, limiter_tlv),
+
+       SOC_SINGLE_TLV("ESL Limiter Cushion Volume", CS42L73_LMAXESL, 2, 7, 1,
+                       limiter_tlv),
+
+       SOC_SINGLE("ALC Attack Rate Volume", CS42L73_ALCARATE, 0, 0x3F, 0),
+       SOC_SINGLE("ALC Release Rate Volume", CS42L73_ALCRRATE, 0, 0x3F, 0),
+       SOC_DOUBLE("ALC Switch", CS42L73_ALCARATE, 6, 7, 1, 0),
+       SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L73_ALCMINMAX, 5, 7, 0,
+                       limiter_tlv),
+       SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L73_ALCMINMAX, 2, 7, 0,
+                       limiter_tlv),
+
+       SOC_DOUBLE("NG Enable Switch", CS42L73_NGCAB, 6, 7, 1, 0),
+       SOC_SINGLE("NG Boost Switch", CS42L73_NGCAB, 5, 1, 0),
+       /*
+           NG Threshold depends on NG_BOOTSAB, which selects
+           between two threshold scales in decibels.
+           Set linear values for now ..
+       */
+       SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0),
+       SOC_ENUM("NG Delay", ng_delay_enum),
+
+       SOC_ENUM("Charge Pump Frequency", charge_pump_enum),
+
+       SOC_DOUBLE_R_TLV("XSP-IP Volume",
+                       CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("XSP-XSP Volume",
+                       CS42L73_XSPAXSPAA, CS42L73_XSPBXSPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("XSP-ASP Volume",
+                       CS42L73_XSPAASPAA, CS42L73_XSPAASPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("XSP-VSP Volume",
+                       CS42L73_XSPAVSPMA, CS42L73_XSPBVSPMA, 0, 0x3F, 1,
+                       attn_tlv),
+
+       SOC_DOUBLE_R_TLV("ASP-IP Volume",
+                       CS42L73_ASPAIPAA, CS42L73_ASPBIPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("ASP-XSP Volume",
+                       CS42L73_ASPAXSPAA, CS42L73_ASPBXSPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("ASP-ASP Volume",
+                       CS42L73_ASPAASPAA, CS42L73_ASPBASPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("ASP-VSP Volume",
+                       CS42L73_ASPAVSPMA, CS42L73_ASPBVSPMA, 0, 0x3F, 1,
+                       attn_tlv),
+
+       SOC_DOUBLE_R_TLV("VSP-IP Volume",
+                       CS42L73_VSPAIPAA, CS42L73_VSPBIPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("VSP-XSP Volume",
+                       CS42L73_VSPAXSPAA, CS42L73_VSPBXSPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("VSP-ASP Volume",
+                       CS42L73_VSPAASPAA, CS42L73_VSPBASPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("VSP-VSP Volume",
+                       CS42L73_VSPAVSPMA, CS42L73_VSPBVSPMA, 0, 0x3F, 1,
+                       attn_tlv),
+
+       SOC_DOUBLE_R_TLV("HL-IP Volume",
+                       CS42L73_HLAIPAA, CS42L73_HLBIPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("HL-XSP Volume",
+                       CS42L73_HLAXSPAA, CS42L73_HLBXSPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("HL-ASP Volume",
+                       CS42L73_HLAASPAA, CS42L73_HLBASPBA, 0, 0x3F, 1,
+                       attn_tlv),
+       SOC_DOUBLE_R_TLV("HL-VSP Volume",
+                       CS42L73_HLAVSPMA, CS42L73_HLBVSPMA, 0, 0x3F, 1,
+                       attn_tlv),
+
+       SOC_SINGLE_TLV("SPK-IP Mono Volume",
+                       CS42L73_SPKMIPMA, 0, 0x3E, 1, attn_tlv),
+       SOC_SINGLE_TLV("SPK-XSP Mono Volume",
+                       CS42L73_SPKMXSPA, 0, 0x3E, 1, attn_tlv),
+       SOC_SINGLE_TLV("SPK-ASP Mono Volume",
+                       CS42L73_SPKMASPA, 0, 0x3E, 1, attn_tlv),
+       SOC_SINGLE_TLV("SPK-VSP Mono Volume",
+                       CS42L73_SPKMVSPMA, 0, 0x3E, 1, attn_tlv),
+
+       SOC_SINGLE_TLV("ESL-IP Mono Volume",
+                       CS42L73_ESLMIPMA, 0, 0x3E, 1, attn_tlv),
+       SOC_SINGLE_TLV("ESL-XSP Mono Volume",
+                       CS42L73_ESLMXSPA, 0, 0x3E, 1, attn_tlv),
+       SOC_SINGLE_TLV("ESL-ASP Mono Volume",
+                       CS42L73_ESLMASPA, 0, 0x3E, 1, attn_tlv),
+       SOC_SINGLE_TLV("ESL-VSP Mono Volume",
+                       CS42L73_ESLMVSPMA, 0, 0x3E, 1, attn_tlv),
+
+       SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum),
+
+       SOC_ENUM("VSPOUT Mono/Stereo Select", vsp_output_mux_enum),
+       SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
+};
+
+static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
+       SND_SOC_DAPM_INPUT("LINEINA"),
+       SND_SOC_DAPM_INPUT("LINEINB"),
+       SND_SOC_DAPM_INPUT("MIC1"),
+       SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS42L73_PWRCTL2, 6, 1, NULL, 0),
+       SND_SOC_DAPM_INPUT("MIC2"),
+       SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0),
+
+       SND_SOC_DAPM_AIF_OUT("XSPOUTL", "XSP Capture",  0,
+                       CS42L73_PWRCTL2, 1, 1),
+       SND_SOC_DAPM_AIF_OUT("XSPOUTR", "XSP Capture",  0,
+                       CS42L73_PWRCTL2, 1, 1),
+       SND_SOC_DAPM_AIF_OUT("ASPOUTL", "ASP Capture",  0,
+                       CS42L73_PWRCTL2, 3, 1),
+       SND_SOC_DAPM_AIF_OUT("ASPOUTR", "ASP Capture",  0,
+                       CS42L73_PWRCTL2, 3, 1),
+       SND_SOC_DAPM_AIF_OUT("VSPOUTL", "VSP Capture",  0,
+                       CS42L73_PWRCTL2, 4, 1),
+       SND_SOC_DAPM_AIF_OUT("VSPOUTR", "VSP Capture",  0,
+                       CS42L73_PWRCTL2, 4, 1),
+
+       SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("PGA Right", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_MUX("PGA Left Mux", SND_SOC_NOPM, 0, 0, &pgaa_mux),
+       SND_SOC_DAPM_MUX("PGA Right Mux", SND_SOC_NOPM, 0, 0, &pgab_mux),
+
+       SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L73_PWRCTL1, 7, 1),
+       SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L73_PWRCTL1, 5, 1),
+       SND_SOC_DAPM_ADC("DMIC Left", NULL, CS42L73_PWRCTL1, 6, 1),
+       SND_SOC_DAPM_ADC("DMIC Right", NULL, CS42L73_PWRCTL1, 4, 1),
+
+       SND_SOC_DAPM_MIXER_NAMED_CTL("Input Left Capture", SND_SOC_NOPM,
+                        0, 0, input_left_mixer,
+                        ARRAY_SIZE(input_left_mixer)),
+
+       SND_SOC_DAPM_MIXER_NAMED_CTL("Input Right Capture", SND_SOC_NOPM,
+                       0, 0, input_right_mixer,
+                       ARRAY_SIZE(input_right_mixer)),
+
+       SND_SOC_DAPM_MIXER("ASPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_AIF_IN("XSPINL", "XSP Playback", 0,
+                               CS42L73_PWRCTL2, 0, 1),
+       SND_SOC_DAPM_AIF_IN("XSPINR", "XSP Playback", 0,
+                               CS42L73_PWRCTL2, 0, 1),
+       SND_SOC_DAPM_AIF_IN("XSPINM", "XSP Playback", 0,
+                               CS42L73_PWRCTL2, 0, 1),
+
+       SND_SOC_DAPM_AIF_IN("ASPINL", "ASP Playback", 0,
+                               CS42L73_PWRCTL2, 2, 1),
+       SND_SOC_DAPM_AIF_IN("ASPINR", "ASP Playback", 0,
+                               CS42L73_PWRCTL2, 2, 1),
+       SND_SOC_DAPM_AIF_IN("ASPINM", "ASP Playback", 0,
+                               CS42L73_PWRCTL2, 2, 1),
+
+       SND_SOC_DAPM_AIF_IN("VSPIN", "VSP Playback", 0,
+                               CS42L73_PWRCTL2, 4, 1),
+
+       SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("HL Right Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("SPK Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("ESL Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_MUX("ESL-XSP Mux", SND_SOC_NOPM,
+                        0, 0, &esl_xsp_mixer),
+
+       SND_SOC_DAPM_MUX("ESL-ASP Mux", SND_SOC_NOPM,
+                        0, 0, &esl_asp_mixer),
+
+       SND_SOC_DAPM_MUX("SPK-ASP Mux", SND_SOC_NOPM,
+                        0, 0, &spk_asp_mixer),
+
+       SND_SOC_DAPM_MUX("SPK-XSP Mux", SND_SOC_NOPM,
+                        0, 0, &spk_xsp_mixer),
+
+       SND_SOC_DAPM_PGA("HL Left DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("HL Right DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
+                           &hp_amp_ctl),
+       SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
+                           &lo_amp_ctl),
+       SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
+                           &spk_amp_ctl),
+       SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
+                           &ear_amp_ctl),
+       SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
+                           &spklo_amp_ctl),
+
+       SND_SOC_DAPM_OUTPUT("HPOUTA"),
+       SND_SOC_DAPM_OUTPUT("HPOUTB"),
+       SND_SOC_DAPM_OUTPUT("LINEOUTA"),
+       SND_SOC_DAPM_OUTPUT("LINEOUTB"),
+       SND_SOC_DAPM_OUTPUT("EAROUT"),
+       SND_SOC_DAPM_OUTPUT("SPKOUT"),
+       SND_SOC_DAPM_OUTPUT("SPKLINEOUT"),
+};
+
+static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
+
+       /* SPKLO EARSPK Paths */
+       {"EAROUT", NULL, "EAR Amp"},
+       {"SPKLINEOUT", NULL, "SPKLO Amp"},
+
+       {"EAR Amp", "Switch", "ESL DAC"},
+       {"SPKLO Amp", "Switch", "ESL DAC"},
+
+       {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"},
+       {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"},
+       {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"},
+       /* Loopback */
+       {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"},
+       {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"},
+
+       {"ESL Mixer", NULL, "ESL-ASP Mux"},
+       {"ESL Mixer", NULL, "ESL-XSP Mux"},
+
+       {"ESL-ASP Mux", "Left", "ASPINL"},
+       {"ESL-ASP Mux", "Right", "ASPINR"},
+       {"ESL-ASP Mux", "Mono Mix", "ASPINM"},
+
+       {"ESL-XSP Mux", "Left", "XSPINL"},
+       {"ESL-XSP Mux", "Right", "XSPINR"},
+       {"ESL-XSP Mux", "Mono Mix", "XSPINM"},
+
+       /* Speakerphone Paths */
+       {"SPKOUT", NULL, "SPK Amp"},
+       {"SPK Amp", "Switch", "SPK DAC"},
+
+       {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"},
+       {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"},
+       {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"},
+       /* Loopback */
+       {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"},
+       {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"},
+
+       {"SPK Mixer", NULL, "SPK-ASP Mux"},
+       {"SPK Mixer", NULL, "SPK-XSP Mux"},
+
+       {"SPK-ASP Mux", "Left", "ASPINL"},
+       {"SPK-ASP Mux", "Mono Mix", "ASPINM"},
+       {"SPK-ASP Mux", "Right", "ASPINR"},
+
+       {"SPK-XSP Mux", "Left", "XSPINL"},
+       {"SPK-XSP Mux", "Mono Mix", "XSPINM"},
+       {"SPK-XSP Mux", "Right", "XSPINR"},
+
+       /* HP LineOUT Paths */
+       {"HPOUTA", NULL, "HP Amp"},
+       {"HPOUTB", NULL, "HP Amp"},
+       {"LINEOUTA", NULL, "LO Amp"},
+       {"LINEOUTB", NULL, "LO Amp"},
+
+       {"HP Amp", "Switch", "HL Left DAC"},
+       {"HP Amp", "Switch", "HL Right DAC"},
+       {"LO Amp", "Switch", "HL Left DAC"},
+       {"LO Amp", "Switch", "HL Right DAC"},
+
+       {"HL Left DAC", "HL-XSP Volume", "HL Left Mixer"},
+       {"HL Right DAC", "HL-XSP Volume", "HL Right Mixer"},
+       {"HL Left DAC", "HL-ASP Volume", "HL Left Mixer"},
+       {"HL Right DAC", "HL-ASP Volume", "HL Right Mixer"},
+       {"HL Left DAC", "HL-VSP Volume", "HL Left Mixer"},
+       {"HL Right DAC", "HL-VSP Volume", "HL Right Mixer"},
+       /* Loopback */
+       {"HL Left DAC", "HL-IP Volume", "HL Left Mixer"},
+       {"HL Right DAC", "HL-IP Volume", "HL Right Mixer"},
+       {"HL Left Mixer", NULL, "Input Left Capture"},
+       {"HL Right Mixer", NULL, "Input Right Capture"},
+
+       {"HL Left Mixer", NULL, "ASPINL"},
+       {"HL Right Mixer", NULL, "ASPINR"},
+       {"HL Left Mixer", NULL, "XSPINL"},
+       {"HL Right Mixer", NULL, "XSPINR"},
+       {"HL Left Mixer", NULL, "VSPIN"},
+       {"HL Right Mixer", NULL, "VSPIN"},
+
+       /* Capture Paths */
+       {"MIC1", NULL, "MIC1 Bias"},
+       {"PGA Left Mux", "Mic 1", "MIC1"},
+       {"MIC2", NULL, "MIC2 Bias"},
+       {"PGA Right Mux", "Mic 2", "MIC2"},
+
+       {"PGA Left Mux", "Line A", "LINEINA"},
+       {"PGA Right Mux", "Line B", "LINEINB"},
+
+       {"PGA Left", NULL, "PGA Left Mux"},
+       {"PGA Right", NULL, "PGA Right Mux"},
+
+       {"ADC Left", NULL, "PGA Left"},
+       {"ADC Right", NULL, "PGA Right"},
+
+       {"Input Left Capture", "ADC Left Input", "ADC Left"},
+       {"Input Right Capture", "ADC Right Input", "ADC Right"},
+       {"Input Left Capture", "DMIC Left Input", "DMIC Left"},
+       {"Input Right Capture", "DMIC Right Input", "DMIC Right"},
+
+       /* Audio Capture */
+       {"ASPL Output Mixer", NULL, "Input Left Capture"},
+       {"ASPR Output Mixer", NULL, "Input Right Capture"},
+
+       {"ASPOUTL", "ASP-IP Volume", "ASPL Output Mixer"},
+       {"ASPOUTR", "ASP-IP Volume", "ASPR Output Mixer"},
+
+       /* Auxillary Capture */
+       {"XSPL Output Mixer", NULL, "Input Left Capture"},
+       {"XSPR Output Mixer", NULL, "Input Right Capture"},
+
+       {"XSPOUTL", "XSP-IP Volume", "XSPL Output Mixer"},
+       {"XSPOUTR", "XSP-IP Volume", "XSPR Output Mixer"},
+
+       {"XSPOUTL", NULL, "XSPL Output Mixer"},
+       {"XSPOUTR", NULL, "XSPR Output Mixer"},
+
+       /* Voice Capture */
+       {"VSPL Output Mixer", NULL, "Input Left Capture"},
+       {"VSPR Output Mixer", NULL, "Input Left Capture"},
+
+       {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"},
+       {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"},
+
+       {"VSPOUTL", NULL, "VSPL Output Mixer"},
+       {"VSPOUTR", NULL, "VSPR Output Mixer"},
+};
+
+struct cs42l73_mclk_div {
+       u32 mclk;
+       u32 srate;
+       u8 mmcc;
+};
+
+static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
+       /* MCLK, Sample Rate, xMMCC[5:0] */
+       {5644800, 11025, 0x30},
+       {5644800, 22050, 0x20},
+       {5644800, 44100, 0x10},
+
+       {6000000,  8000, 0x39},
+       {6000000, 11025, 0x33},
+       {6000000, 12000, 0x31},
+       {6000000, 16000, 0x29},
+       {6000000, 22050, 0x23},
+       {6000000, 24000, 0x21},
+       {6000000, 32000, 0x19},
+       {6000000, 44100, 0x13},
+       {6000000, 48000, 0x11},
+
+       {6144000,  8000, 0x38},
+       {6144000, 12000, 0x30},
+       {6144000, 16000, 0x28},
+       {6144000, 24000, 0x20},
+       {6144000, 32000, 0x18},
+       {6144000, 48000, 0x10},
+
+       {6500000,  8000, 0x3C},
+       {6500000, 11025, 0x35},
+       {6500000, 12000, 0x34},
+       {6500000, 16000, 0x2C},
+       {6500000, 22050, 0x25},
+       {6500000, 24000, 0x24},
+       {6500000, 32000, 0x1C},
+       {6500000, 44100, 0x15},
+       {6500000, 48000, 0x14},
+
+       {6400000,  8000, 0x3E},
+       {6400000, 11025, 0x37},
+       {6400000, 12000, 0x36},
+       {6400000, 16000, 0x2E},
+       {6400000, 22050, 0x27},
+       {6400000, 24000, 0x26},
+       {6400000, 32000, 0x1E},
+       {6400000, 44100, 0x17},
+       {6400000, 48000, 0x16},
+};
+
+struct cs42l73_mclkx_div {
+       u32 mclkx;
+       u8 ratio;
+       u8 mclkdiv;
+};
+
+static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
+       {5644800,  1, 0},       /* 5644800 */
+       {6000000,  1, 0},       /* 6000000 */
+       {6144000,  1, 0},       /* 6144000 */
+       {11289600, 2, 2},       /* 5644800 */
+       {12288000, 2, 2},       /* 6144000 */
+       {12000000, 2, 2},       /* 6000000 */
+       {13000000, 2, 2},       /* 6500000 */
+       {19200000, 3, 3},       /* 6400000 */
+       {24000000, 4, 4},       /* 6000000 */
+       {26000000, 4, 4},       /* 6500000 */
+       {38400000, 6, 5}        /* 6400000 */
+};
+
+static int cs42l73_get_mclkx_coeff(int mclkx)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(cs42l73_mclkx_coeffs); i++) {
+               if (cs42l73_mclkx_coeffs[i].mclkx == mclkx)
+                       return i;
+       }
+       return -EINVAL;
+}
+
+static int cs42l73_get_mclk_coeff(int mclk, int srate)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(cs42l73_mclk_coeffs); i++) {
+               if (cs42l73_mclk_coeffs[i].mclk == mclk &&
+                   cs42l73_mclk_coeffs[i].srate == srate)
+                       return i;
+       }
+       return -EINVAL;
+
+}
+
+static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+
+       int mclkx_coeff;
+       u32 mclk = 0;
+       u8 dmmcc = 0;
+
+       /* MCLKX -> MCLK */
+       mclkx_coeff = cs42l73_get_mclkx_coeff(freq);
+
+       mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx /
+               cs42l73_mclkx_coeffs[mclkx_coeff].ratio;
+
+       dev_dbg(codec->dev, "MCLK%u %u  <-> internal MCLK %u\n",
+                priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx,
+                mclk);
+
+       dmmcc = (priv->mclksel << 4) |
+               (cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1);
+
+       snd_soc_write(codec, CS42L73_DMMCC, dmmcc);
+
+       priv->sysclk = mclkx_coeff;
+       priv->mclk = mclk;
+
+       return 0;
+}
+
+static int cs42l73_set_sysclk(struct snd_soc_dai *dai,
+                             int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+
+       switch (clk_id) {
+       case CS42L73_CLKID_MCLK1:
+               break;
+       case CS42L73_CLKID_MCLK2:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if ((cs42l73_set_mclk(dai, freq)) < 0) {
+               dev_err(codec->dev, "Unable to set MCLK for dai %s\n",
+                       dai->name);
+               return -EINVAL;
+       }
+
+       priv->mclksel = clk_id;
+
+       return 0;
+}
+
+static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       u8 id = codec_dai->id;
+       unsigned int inv, format;
+       u8 spc, mmcc;
+
+       spc = snd_soc_read(codec, CS42L73_SPC(id));
+       mmcc = snd_soc_read(codec, CS42L73_MMCC(id));
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               mmcc |= MS_MASTER;
+               break;
+
+       case SND_SOC_DAIFMT_CBS_CFS:
+               mmcc &= ~MS_MASTER;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+       inv = (fmt & SND_SOC_DAIFMT_INV_MASK);
+
+       switch (format) {
+       case SND_SOC_DAIFMT_I2S:
+               spc &= ~SPDIF_PCM;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+       case SND_SOC_DAIFMT_DSP_B:
+               if (mmcc & MS_MASTER) {
+                       dev_err(codec->dev,
+                               "PCM format in slave mode only\n");
+                       return -EINVAL;
+               }
+               if (id == CS42L73_ASP) {
+                       dev_err(codec->dev,
+                               "PCM format is not supported on ASP port\n");
+                       return -EINVAL;
+               }
+               spc |= SPDIF_PCM;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (spc & SPDIF_PCM) {
+               spc &= (31 << 3);       /* Clear PCM mode, set MSB->LSB */
+               switch (format) {
+               case SND_SOC_DAIFMT_DSP_B:
+                       if (inv == SND_SOC_DAIFMT_IB_IF)
+                               spc |= PCM_MODE0;
+                       if (inv == SND_SOC_DAIFMT_IB_NF)
+                               spc |= PCM_MODE1;
+               break;
+               case SND_SOC_DAIFMT_DSP_A:
+                       if (inv == SND_SOC_DAIFMT_IB_IF)
+                               spc |= PCM_MODE1;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       priv->config[id].spc = spc;
+       priv->config[id].mmcc = mmcc;
+
+       return 0;
+}
+
+static u32 cs42l73_asrc_rates[] = {
+       8000, 11025, 12000, 16000, 22050,
+       24000, 32000, 44100, 48000
+};
+
+static unsigned int cs42l73_get_xspfs_coeff(u32 rate)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(cs42l73_asrc_rates); i++) {
+               if (cs42l73_asrc_rates[i] == rate)
+                       return i + 1;
+       }
+       return 0;               /* 0 = Don't know */
+}
+
+static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate)
+{
+       u8 spfs = 0;
+
+       if (srate > 0)
+               spfs = cs42l73_get_xspfs_coeff(srate);
+
+       switch (id) {
+       case CS42L73_XSP:
+               snd_soc_update_bits(codec, CS42L73_VXSPFS, 0x0f, spfs);
+       break;
+       case CS42L73_ASP:
+               snd_soc_update_bits(codec, CS42L73_ASPC, 0x3c, spfs << 2);
+       break;
+       case CS42L73_VSP:
+               snd_soc_update_bits(codec, CS42L73_VXSPFS, 0xf0, spfs << 4);
+       break;
+       default:
+       break;
+       }
+}
+
+static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_codec *codec = rtd->codec;
+       struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
+       int id = dai->id;
+       int mclk_coeff;
+       int srate = params_rate(params);
+
+       if (priv->config[id].mmcc & MS_MASTER) {
+               /* CS42L73 Master */
+               /* MCLK -> srate */
+               mclk_coeff =
+                   cs42l73_get_mclk_coeff(priv->mclk, srate);
+
+               if (mclk_coeff < 0)
+                       return -EINVAL;
+
+               dev_dbg(codec->dev,
+                        "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n",
+                        id, priv->mclk, srate,
+                        cs42l73_mclk_coeffs[mclk_coeff].mmcc);
+
+               priv->config[id].mmcc &= 0xC0;
+               priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
+               priv->config[id].spc &= 0xFC;
+               priv->config[id].spc &= MCK_SCLK_64FS;
+       } else {
+               /* CS42L73 Slave */
+               priv->config[id].spc &= 0xFC;
+               priv->config[id].spc |= MCK_SCLK_64FS;
+       }
+       /* Update ASRCs */
+       priv->config[id].srate = srate;
+
+       snd_soc_write(codec, CS42L73_SPC(id), priv->config[id].spc);
+       snd_soc_write(codec, CS42L73_MMCC(id), priv->config[id].mmcc);
+
+       cs42l73_update_asrc(codec, id, srate);
+
+       return 0;
+}
+
+static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
+                                 enum snd_soc_bias_level level)
+{
+       struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 0);
+               snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 0);
+               break;
+
+       case SND_SOC_BIAS_PREPARE:
+               break;
+
+       case SND_SOC_BIAS_STANDBY:
+               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+                       regcache_cache_only(cs42l73->regmap, false);
+                       regcache_sync(cs42l73->regmap);
+               }
+               snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
+               break;
+
+       case SND_SOC_BIAS_OFF:
+               snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
+               snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
+               break;
+       }
+       codec->dapm.bias_level = level;
+       return 0;
+}
+
+static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       int id = dai->id;
+
+       return snd_soc_update_bits(codec, CS42L73_SPC(id),
+                                       0x7F, tristate << 7);
+}
+
+static struct snd_pcm_hw_constraint_list constraints_12_24 = {
+       .count  = ARRAY_SIZE(cs42l73_asrc_rates),
+       .list   = cs42l73_asrc_rates,
+};
+
+static int cs42l73_pcm_startup(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
+{
+       snd_pcm_hw_constraint_list(substream->runtime, 0,
+                                       SNDRV_PCM_HW_PARAM_RATE,
+                                       &constraints_12_24);
+       return 0;
+}
+
+/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */
+#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
+
+
+#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+       SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dai_ops cs42l73_ops = {
+       .startup = cs42l73_pcm_startup,
+       .hw_params = cs42l73_pcm_hw_params,
+       .set_fmt = cs42l73_set_dai_fmt,
+       .set_sysclk = cs42l73_set_sysclk,
+       .set_tristate = cs42l73_set_tristate,
+};
+
+static struct snd_soc_dai_driver cs42l73_dai[] = {
+       {
+               .name = "cs42l73-xsp",
+               .id = CS42L73_XSP,
+               .playback = {
+                       .stream_name = "XSP Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = CS42L73_RATES,
+                       .formats = CS42L73_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "XSP Capture",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = CS42L73_RATES,
+                       .formats = CS42L73_FORMATS,
+               },
+               .ops = &cs42l73_ops,
+               .symmetric_rates = 1,
+        },
+       {
+               .name = "cs42l73-asp",
+               .id = CS42L73_ASP,
+               .playback = {
+                       .stream_name = "ASP Playback",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = CS42L73_RATES,
+                       .formats = CS42L73_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "ASP Capture",
+                       .channels_min = 2,
+                       .channels_max = 2,
+                       .rates = CS42L73_RATES,
+                       .formats = CS42L73_FORMATS,
+               },
+               .ops = &cs42l73_ops,
+               .symmetric_rates = 1,
+        },
+       {
+               .name = "cs42l73-vsp",
+               .id = CS42L73_VSP,
+               .playback = {
+                       .stream_name = "VSP Playback",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = CS42L73_RATES,
+                       .formats = CS42L73_FORMATS,
+               },
+               .capture = {
+                       .stream_name = "VSP Capture",
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = CS42L73_RATES,
+                       .formats = CS42L73_FORMATS,
+               },
+               .ops = &cs42l73_ops,
+               .symmetric_rates = 1,
+        }
+};
+
+static int cs42l73_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+       cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       return 0;
+}
+
+static int cs42l73_resume(struct snd_soc_codec *codec)
+{
+       cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       return 0;
+}
+
+static int cs42l73_probe(struct snd_soc_codec *codec)
+{
+       int ret;
+       struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
+
+       codec->control_data = cs42l73->regmap;
+
+       ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
+
+       regcache_cache_only(cs42l73->regmap, true);
+
+       cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       cs42l73->mclksel = CS42L73_CLKID_MCLK1; /* MCLK1 as master clk */
+       cs42l73->mclk = 0;
+
+       return ret;
+}
+
+static int cs42l73_remove(struct snd_soc_codec *codec)
+{
+       cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
+       .probe = cs42l73_probe,
+       .remove = cs42l73_remove,
+       .suspend = cs42l73_suspend,
+       .resume = cs42l73_resume,
+       .set_bias_level = cs42l73_set_bias_level,
+
+       .dapm_widgets = cs42l73_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets),
+       .dapm_routes = cs42l73_audio_map,
+       .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map),
+
+       .controls = cs42l73_snd_controls,
+       .num_controls = ARRAY_SIZE(cs42l73_snd_controls),
+};
+
+static struct regmap_config cs42l73_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = CS42L73_MAX_REGISTER,
+       .reg_defaults = cs42l73_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(cs42l73_reg_defaults),
+       .volatile_reg = cs42l73_volatile_register,
+       .readable_reg = cs42l73_readable_register,
+       .cache_type = REGCACHE_RBTREE,
+};
+
+static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
+                                      const struct i2c_device_id *id)
+{
+       struct cs42l73_private *cs42l73;
+       int ret;
+       unsigned int devid = 0;
+       unsigned int reg;
+
+       cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private),
+                              GFP_KERNEL);
+       if (!cs42l73) {
+               dev_err(&i2c_client->dev, "could not allocate codec\n");
+               return -ENOMEM;
+       }
+
+       i2c_set_clientdata(i2c_client, cs42l73);
+
+       cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap);
+       if (IS_ERR(cs42l73->regmap)) {
+               ret = PTR_ERR(cs42l73->regmap);
+               dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
+               goto err;
+       }
+       /* initialize codec */
+       ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg);
+       devid = (reg & 0xFF) << 12;
+
+       ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, &reg);
+       devid |= (reg & 0xFF) << 4;
+
+       ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, &reg);
+       devid |= (reg & 0xF0) >> 4;
+
+
+       if (devid != CS42L73_DEVID) {
+               ret = -ENODEV;
+               dev_err(&i2c_client->dev,
+                       "CS42L73 Device ID (%X). Expected %X\n",
+                       devid, CS42L73_DEVID);
+               goto err_regmap;
+       }
+
+       ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg);
+       if (ret < 0) {
+               dev_err(&i2c_client->dev, "Get Revision ID failed\n");
+               goto err_regmap;
+       }
+
+       dev_info(&i2c_client->dev,
+                "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF);
+
+       regcache_cache_only(cs42l73->regmap, true);
+
+       ret =  snd_soc_register_codec(&i2c_client->dev,
+                       &soc_codec_dev_cs42l73, cs42l73_dai,
+                       ARRAY_SIZE(cs42l73_dai));
+       if (ret < 0)
+               goto err_regmap;
+       return 0;
+
+err_regmap:
+       regmap_exit(cs42l73->regmap);
+
+err:
+       return ret;
+}
+
+static __devexit int cs42l73_i2c_remove(struct i2c_client *client)
+{
+       struct cs42l73_private *cs42l73 = i2c_get_clientdata(client);
+
+       snd_soc_unregister_codec(&client->dev);
+       regmap_exit(cs42l73->regmap);
+
+       return 0;
+}
+
+static const struct i2c_device_id cs42l73_id[] = {
+       {"cs42l73", 0},
+       {}
+};
+
+MODULE_DEVICE_TABLE(i2c, cs42l73_id);
+
+static struct i2c_driver cs42l73_i2c_driver = {
+       .driver = {
+                  .name = "cs42l73",
+                  .owner = THIS_MODULE,
+                  },
+       .id_table = cs42l73_id,
+       .probe = cs42l73_i2c_probe,
+       .remove = __devexit_p(cs42l73_i2c_remove),
+
+};
+
+static int __init cs42l73_modinit(void)
+{
+       int ret;
+       ret = i2c_add_driver(&cs42l73_i2c_driver);
+       if (ret != 0) {
+               pr_err("Failed to register CS42L73 I2C driver: %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+module_init(cs42l73_modinit);
+
+static void __exit cs42l73_exit(void)
+{
+       i2c_del_driver(&cs42l73_i2c_driver);
+}
+
+module_exit(cs42l73_exit);
+
+MODULE_DESCRIPTION("ASoC CS42L73 driver");
+MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>");
+MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l73.h b/sound/soc/codecs/cs42l73.h
new file mode 100644 (file)
index 0000000..f30a4c4
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * ALSA SoC CS42L73 codec driver
+ *
+ * Copyright 2011 Cirrus Logic, Inc.
+ *
+ * Author: Georgi Vlaev <joe@nucleusys.com>
+ *        Brian Austin <brian.austin@cirrus.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
+ *
+ */
+
+#ifndef __CS42L73_H__
+#define __CS42L73_H__
+
+/* I2C Registers */
+/* I2C Address: 1001010[R/W] - 10010100 = 0x94(Write); 10010101 = 0x95(Read) */
+#define CS42L73_CHIP_ID                0x4a
+#define CS42L73_DEVID_AB       0x01    /* Device ID A & B [RO]. */
+#define CS42L73_DEVID_CD       0x02    /* Device ID C & D [RO]. */
+#define CS42L73_DEVID_E                0x03    /* Device ID E [RO]. */
+#define CS42L73_REVID          0x05    /* Revision ID [RO]. */
+#define CS42L73_PWRCTL1                0x06    /* Power Control 1. */
+#define CS42L73_PWRCTL2                0x07    /* Power Control 2. */
+#define CS42L73_PWRCTL3                0x08    /* Power Control 3. */
+#define CS42L73_CPFCHC         0x09    /* Charge Pump Freq. Class H Ctl. */
+#define CS42L73_OLMBMSDC       0x0A    /* Output Load, MIC Bias, MIC2 SDT */
+#define CS42L73_DMMCC          0x0B    /* Digital MIC & Master Clock Ctl. */
+#define CS42L73_XSPC           0x0C    /* Auxiliary Serial Port (XSP) Ctl. */
+#define CS42L73_XSPMMCC                0x0D    /* XSP Master Mode Clocking Control. */
+#define CS42L73_ASPC           0x0E    /* Audio Serial Port (ASP) Control. */
+#define CS42L73_ASPMMCC                0x0F    /* ASP Master Mode Clocking Control. */
+#define CS42L73_VSPC           0x10    /* Voice Serial Port (VSP) Control. */
+#define CS42L73_VSPMMCC                0x11    /* VSP Master Mode Clocking Control. */
+#define CS42L73_VXSPFS         0x12    /* VSP & XSP Sample Rate. */
+#define CS42L73_MIOPC          0x13    /* Misc. Input & Output Path Control. */
+#define CS42L73_ADCIPC         0x14    /* ADC/IP Control. */
+#define CS42L73_MICAPREPGAAVOL 0x15    /* MIC 1 [A] PreAmp, PGAA Vol. */
+#define CS42L73_MICBPREPGABVOL 0x16    /* MIC 2 [B] PreAmp, PGAB Vol. */
+#define CS42L73_IPADVOL                0x17    /* Input Pat7h A Digital Volume. */
+#define CS42L73_IPBDVOL                0x18    /* Input Path B Digital Volume. */
+#define CS42L73_PBDC           0x19    /* Playback Digital Control. */
+#define CS42L73_HLADVOL                0x1A    /* HP/Line A Out Digital Vol. */
+#define CS42L73_HLBDVOL                0x1B    /* HP/Line B Out Digital Vol. */
+#define CS42L73_SPKDVOL                0x1C    /* Spkphone Out [A] Digital Vol. */
+#define CS42L73_ESLDVOL                0x1D    /* Ear/Spkphone LO [B] Digital */
+#define CS42L73_HPAAVOL                0x1E    /* HP A Analog Volume. */
+#define CS42L73_HPBAVOL                0x1F    /* HP B Analog Volume. */
+#define CS42L73_LOAAVOL                0x20    /* Line Out A Analog Volume. */
+#define CS42L73_LOBAVOL                0x21    /* Line Out B Analog Volume. */
+#define CS42L73_STRINV         0x22    /* Stereo Input Path Adv. Vol. */
+#define CS42L73_XSPINV         0x23    /* Auxiliary Port Input Advisory Vol. */
+#define CS42L73_ASPINV         0x24    /* Audio Port Input Advisory Vol. */
+#define CS42L73_VSPINV         0x25    /* Voice Port Input Advisory Vol. */
+#define CS42L73_LIMARATEHL     0x26    /* Lmtr Attack Rate HP/Line. */
+#define CS42L73_LIMRRATEHL     0x27    /* Lmtr Ctl, Rel.Rate HP/Line. */
+#define CS42L73_LMAXHL         0x28    /* Lmtr Thresholds HP/Line. */
+#define CS42L73_LIMARATESPK    0x29    /* Lmtr Attack Rate Spkphone [A]. */
+#define CS42L73_LIMRRATESPK    0x2A    /* Lmtr Ctl,Release Rate Spk. [A]. */
+#define CS42L73_LMAXSPK                0x2B    /* Lmtr Thresholds Spkphone [A]. */
+#define CS42L73_LIMARATEESL    0x2C    /* Lmtr Attack Rate  */
+#define CS42L73_LIMRRATEESL    0x2D    /* Lmtr Ctl,Release Rate */
+#define CS42L73_LMAXESL                0x2E    /* Lmtr Thresholds */
+#define CS42L73_ALCARATE       0x2F    /* ALC Enable, Attack Rate AB. */
+#define CS42L73_ALCRRATE       0x30    /* ALC Release Rate AB.  */
+#define CS42L73_ALCMINMAX      0x31    /* ALC Thresholds AB. */
+#define CS42L73_NGCAB          0x32    /* Noise Gate Ctl AB. */
+#define CS42L73_ALCNGMC                0x33    /* ALC & Noise Gate Misc Ctl. */
+#define CS42L73_MIXERCTL       0x34    /* Mixer Control. */
+#define CS42L73_HLAIPAA                0x35    /* HP/LO Left Mixer: L. */
+#define CS42L73_HLBIPBA                0x36    /* HP/LO Right Mixer: R.  */
+#define CS42L73_HLAXSPAA       0x37    /* HP/LO Left Mixer: XSP L */
+#define CS42L73_HLBXSPBA       0x38    /* HP/LO Right Mixer: XSP R */
+#define CS42L73_HLAASPAA       0x39    /* HP/LO Left Mixer: ASP L */
+#define CS42L73_HLBASPBA       0x3A    /* HP/LO Right Mixer: ASP R */
+#define CS42L73_HLAVSPMA       0x3B    /* HP/LO Left Mixer: VSP. */
+#define CS42L73_HLBVSPMA       0x3C    /* HP/LO Right Mixer: VSP */
+#define CS42L73_XSPAIPAA       0x3D    /* XSP Left Mixer: Left */
+#define CS42L73_XSPBIPBA       0x3E    /* XSP Rt. Mixer: Right */
+#define CS42L73_XSPAXSPAA      0x3F    /* XSP Left Mixer: XSP L */
+#define CS42L73_XSPBXSPBA      0x40    /* XSP Rt. Mixer: XSP R */
+#define CS42L73_XSPAASPAA      0x41    /* XSP Left Mixer: ASP L */
+#define CS42L73_XSPAASPBA      0x42    /* XSP Rt. Mixer: ASP R */
+#define CS42L73_XSPAVSPMA      0x43    /* XSP Left Mixer: VSP */
+#define CS42L73_XSPBVSPMA      0x44    /* XSP Rt. Mixer: VSP */
+#define CS42L73_ASPAIPAA       0x45    /* ASP Left Mixer: Left */
+#define CS42L73_ASPBIPBA       0x46    /* ASP Rt. Mixer: Right */
+#define CS42L73_ASPAXSPAA      0x47    /* ASP Left Mixer: XSP L */
+#define CS42L73_ASPBXSPBA      0x48    /* ASP Rt. Mixer: XSP R */
+#define CS42L73_ASPAASPAA      0x49    /* ASP Left Mixer: ASP L */
+#define CS42L73_ASPBASPBA      0x4A    /* ASP Rt. Mixer: ASP R */
+#define CS42L73_ASPAVSPMA      0x4B    /* ASP Left Mixer: VSP */
+#define CS42L73_ASPBVSPMA      0x4C    /* ASP Rt. Mixer: VSP */
+#define CS42L73_VSPAIPAA       0x4D    /* VSP Left Mixer: Left */
+#define CS42L73_VSPBIPBA       0x4E    /* VSP Rt. Mixer: Right */
+#define CS42L73_VSPAXSPAA      0x4F    /* VSP Left Mixer: XSP L */
+#define CS42L73_VSPBXSPBA      0x50    /* VSP Rt. Mixer: XSP R */
+#define CS42L73_VSPAASPAA      0x51    /* VSP Left Mixer: ASP Left */
+#define CS42L73_VSPBASPBA      0x52    /* VSP Rt. Mixer: ASP Right */
+#define CS42L73_VSPAVSPMA      0x53    /* VSP Left Mixer: VSP */
+#define CS42L73_VSPBVSPMA      0x54    /* VSP Rt. Mixer: VSP */
+#define CS42L73_MMIXCTL                0x55    /* Mono Mixer Controls. */
+#define CS42L73_SPKMIPMA       0x56    /* SPK Mono Mixer: In. Path */
+#define CS42L73_SPKMXSPA       0x57    /* SPK Mono Mixer: XSP Mono/L/R Att. */
+#define CS42L73_SPKMASPA       0x58    /* SPK Mono Mixer: ASP Mono/L/R Att. */
+#define CS42L73_SPKMVSPMA      0x59    /* SPK Mono Mixer: VSP Mono Atten. */
+#define CS42L73_ESLMIPMA       0x5A    /* Ear/SpLO Mono Mixer: */
+#define CS42L73_ESLMXSPA       0x5B    /* Ear/SpLO Mono Mixer: XSP */
+#define CS42L73_ESLMASPA       0x5C    /* Ear/SpLO Mono Mixer: ASP */
+#define CS42L73_ESLMVSPMA      0x5D    /* Ear/SpLO Mono Mixer: VSP */
+#define CS42L73_IM1            0x5E    /* Interrupt Mask 1.  */
+#define CS42L73_IM2            0x5F    /* Interrupt Mask 2. */
+#define CS42L73_IS1            0x60    /* Interrupt Status 1 [RO]. */
+#define CS42L73_IS2            0x61    /* Interrupt Status 2 [RO]. */
+#define CS42L73_MAX_REGISTER   0x61    /* Total Registers */
+/* Bitfield Definitions */
+
+/* CS42L73_PWRCTL1 */
+#define PDN_ADCB               (1 << 7)
+#define PDN_DMICB              (1 << 6)
+#define PDN_ADCA               (1 << 5)
+#define PDN_DMICA              (1 << 4)
+#define PDN_LDO                        (1 << 2)
+#define DISCHG_FILT            (1 << 1)
+#define PDN                    (1 << 0)
+
+/* CS42L73_PWRCTL2 */
+#define PDN_MIC2_BIAS          (1 << 7)
+#define PDN_MIC1_BIAS          (1 << 6)
+#define PDN_VSP                        (1 << 4)
+#define PDN_ASP_SDOUT          (1 << 3)
+#define PDN_ASP_SDIN           (1 << 2)
+#define PDN_XSP_SDOUT          (1 << 1)
+#define PDN_XSP_SDIN           (1 << 0)
+
+/* CS42L73_PWRCTL3 */
+#define PDN_THMS               (1 << 5)
+#define PDN_SPKLO              (1 << 4)
+#define PDN_EAR                        (1 << 3)
+#define PDN_SPK                        (1 << 2)
+#define PDN_LO                 (1 << 1)
+#define PDN_HP                 (1 << 0)
+
+/* Thermal Overload Detect. Requires interrupt ... */
+#define THMOVLD_150C           0
+#define THMOVLD_132C           1
+#define THMOVLD_115C           2
+#define THMOVLD_098C           3
+
+
+/* CS42L73_ASPC, CS42L73_XSPC, CS42L73_VSPC */
+#define        SP_3ST                  (1 << 7)
+#define SPDIF_I2S              (0 << 6)
+#define SPDIF_PCM              (1 << 6)
+#define PCM_MODE0              (0 << 4)
+#define PCM_MODE1              (1 << 4)
+#define PCM_MODE2              (2 << 4)
+#define PCM_MODE_MASK          (3 << 4)
+#define PCM_BIT_ORDER          (1 << 3)
+#define MCK_SCLK_64FS          (0 << 0)
+#define MCK_SCLK_MCLK          (2 << 0)
+#define MCK_SCLK_PREMCLK       (3 << 0)
+
+/* CS42L73_xSPMMCC */
+#define MS_MASTER              (1 << 7)
+
+
+/* CS42L73_DMMCC */
+#define MCLKDIS                        (1 << 0)
+#define MCLKSEL_MCLK2          (1 << 4)
+#define MCLKSEL_MCLK1          (0 << 4)
+
+/* CS42L73 MCLK derived from MCLK1 or MCLK2 */
+#define CS42L73_CLKID_MCLK1     0
+#define CS42L73_CLKID_MCLK2     1
+
+#define CS42L73_MCLKXDIV       0
+#define CS42L73_MMCCDIV         1
+
+#define CS42L73_XSP            0
+#define CS42L73_ASP            1
+#define CS42L73_VSP            2
+
+/* IS1, IM1 */
+#define MIC2_SDET              (1 << 6)
+#define THMOVLD                        (1 << 4)
+#define DIGMIXOVFL             (1 << 3)
+#define IPBOVFL                        (1 << 1)
+#define IPAOVFL                        (1 << 0)
+
+/* Analog Softramp */
+#define ANLGOSFT               (1 << 0)
+
+/* HP A/B Analog Mute */
+#define HPA_MUTE               (1 << 7)
+/* LO A/B Analog Mute  */
+#define LOA_MUTE               (1 << 7)
+/* Digital Mute */
+#define HLAD_MUTE              (1 << 0)
+#define HLBD_MUTE              (1 << 1)
+#define SPKD_MUTE              (1 << 2)
+#define ESLD_MUTE              (1 << 3)
+
+/* Misc defines for codec */
+#define CS42L73_RESET_GPIO 143
+
+#define CS42L73_DEVID          0x00042A73
+#define CS42L73_MCLKX_MIN      5644800
+#define CS42L73_MCLKX_MAX      38400000
+
+#define CS42L73_SPC(id)                (CS42L73_XSPC + (id << 1))
+#define CS42L73_MMCC(id)       (CS42L73_XSPMMCC + (id << 1))
+#define CS42L73_SPFS(id)       ((id == CS42L73_ASP) ? CS42L73_ASPC : CS42L73_VXSPFS)
+
+#endif /* __CS42L73_H__ */
index bc7067db8ae4ec54697c4163e23f97af3670bd19..ae55e31bfc721172c7210cc48b2c6706fc0d9831 100644 (file)
@@ -391,17 +391,7 @@ static struct platform_driver cx20442_platform_driver = {
        .remove = __exit_p(cx20442_platform_remove),
 };
 
-static int __init cx20442_init(void)
-{
-       return platform_driver_register(&cx20442_platform_driver);
-}
-module_init(cx20442_init);
-
-static void __exit cx20442_exit(void)
-{
-       platform_driver_unregister(&cx20442_platform_driver);
-}
-module_exit(cx20442_exit);
+module_platform_driver(cx20442_platform_driver);
 
 MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
 MODULE_AUTHOR("Janusz Krzysztofik");
index b545b7d3722271dd14e43213a34992a0b5174525..e4ca61c18605027362f390466368cfced743befc 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <sound/pcm.h>
@@ -240,7 +239,7 @@ static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1);
 static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0);
 
 /* ADC and DAC high pass filter f0 value */
-static const char const *da7210_hpf_cutoff_txt[] = {
+static const char * const da7210_hpf_cutoff_txt[] = {
        "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi"
 };
 
@@ -251,7 +250,7 @@ static const struct soc_enum da7210_adc_hpf_cutoff =
        SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt);
 
 /* ADC and DAC voice (8kHz) high pass cutoff value */
-static const char const *da7210_vf_cutoff_txt[] = {
+static const char * const da7210_vf_cutoff_txt[] = {
        "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
 };
 
@@ -761,7 +760,7 @@ static int da7210_mute(struct snd_soc_dai *dai, int mute)
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
 /* DAI operations */
-static struct snd_soc_dai_ops da7210_dai_ops = {
+static const struct snd_soc_dai_ops da7210_dai_ops = {
        .hw_params      = da7210_hw_params,
        .set_fmt        = da7210_set_dai_fmt,
        .digital_mute   = da7210_mute,
index 704bbde65737577aec3739fa4159307a70f61ee2..bfe46aa90362fe262b7894d0bd9451ad3042f23f 100644 (file)
@@ -55,17 +55,7 @@ static struct platform_driver dfmcs320_driver = {
        .remove = __devexit_p(dfbmcs320_remove),
 };
 
-static int __init dfbmcs320_init(void)
-{
-       return platform_driver_register(&dfmcs320_driver);
-}
-module_init(dfbmcs320_init);
-
-static void __exit dfbmcs320_exit(void)
-{
-       platform_driver_unregister(&dfmcs320_driver);
-}
-module_exit(dfbmcs320_exit);
+module_platform_driver(dfmcs320_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
index 6fae765e3ad8baf3611f7251bd3240e2c6591a06..3e929f079a1f0eb4b3fa472482d68503703da8c4 100644 (file)
@@ -89,17 +89,7 @@ static struct platform_driver dmic_driver = {
        .remove = __devexit_p(dmic_dev_remove),
 };
 
-static int __init dmic_init(void)
-{
-       return platform_driver_register(&dmic_driver);
-}
-module_init(dmic_init);
-
-static void __exit dmic_exit(void)
-{
-       platform_driver_unregister(&dmic_driver);
-}
-module_exit(dmic_exit);
+module_platform_driver(dmic_driver);
 
 MODULE_DESCRIPTION("Generic DMIC driver");
 MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
index e373f8f0690731874d0a153190951ddc564500fe..4fca8bccd53573f2bacffe88bdead55288e3d3a3 100644 (file)
@@ -206,7 +206,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
+static const struct snd_soc_dai_ops jz4740_codec_dai_ops = {
        .hw_params = jz4740_codec_hw_params,
 };
 
@@ -424,17 +424,7 @@ static struct platform_driver jz4740_codec_driver = {
        },
 };
 
-static int __init jz4740_codec_init(void)
-{
-       return platform_driver_register(&jz4740_codec_driver);
-}
-module_init(jz4740_codec_init);
-
-static void __exit jz4740_codec_exit(void)
-{
-       platform_driver_unregister(&jz4740_codec_driver);
-}
-module_exit(jz4740_codec_exit);
+module_platform_driver(jz4740_codec_driver);
 
 MODULE_DESCRIPTION("JZ4740 SoC internal codec driver");
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
index ebbf63c79c34e2873088aa2faaf6bcce400d99a0..9b6036e5738aeecea68598644d68afa75d4edb89 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -1650,14 +1649,14 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
 #define MAX98088_RATES SNDRV_PCM_RATE_8000_96000
 #define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops max98088_dai1_ops = {
+static const struct snd_soc_dai_ops max98088_dai1_ops = {
        .set_sysclk = max98088_dai_set_sysclk,
        .set_fmt = max98088_dai1_set_fmt,
        .hw_params = max98088_dai1_hw_params,
        .digital_mute = max98088_dai1_digital_mute,
 };
 
-static struct snd_soc_dai_ops max98088_dai2_ops = {
+static const struct snd_soc_dai_ops max98088_dai2_ops = {
        .set_sysclk = max98088_dai_set_sysclk,
        .set_fmt = max98088_dai2_set_fmt,
        .hw_params = max98088_dai2_hw_params,
index 26d7b089fb9c27836c2a6721dceec1350bc5300f..01f4ad725149e68845beba7f6acc3a1ab75715bc 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -1782,19 +1781,19 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
 #define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
 #define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops max98095_dai1_ops = {
+static const struct snd_soc_dai_ops max98095_dai1_ops = {
        .set_sysclk = max98095_dai_set_sysclk,
        .set_fmt = max98095_dai1_set_fmt,
        .hw_params = max98095_dai1_hw_params,
 };
 
-static struct snd_soc_dai_ops max98095_dai2_ops = {
+static const struct snd_soc_dai_ops max98095_dai2_ops = {
        .set_sysclk = max98095_dai_set_sysclk,
        .set_fmt = max98095_dai2_set_fmt,
        .hw_params = max98095_dai2_hw_params,
 };
 
-static struct snd_soc_dai_ops max98095_dai3_ops = {
+static const struct snd_soc_dai_ops max98095_dai3_ops = {
        .set_sysclk = max98095_dai_set_sysclk,
        .set_fmt = max98095_dai3_set_fmt,
        .hw_params = max98095_dai3_hw_params,
index 208d2ee618558c980df83b9ad0b35de9920bd145..94c2b586ed5dbf12a645384c7d8e55470416acae 100644 (file)
@@ -254,7 +254,7 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
 #define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops max9850_dai_ops = {
+static const struct snd_soc_dai_ops max9850_dai_ops = {
        .hw_params      = max9850_hw_params,
        .set_sysclk     = max9850_set_dai_sysclk,
        .set_fmt        = max9850_set_dai_fmt,
index f7316519432c42dcdb6122bd17009672217ad72f..b12d01f67990a5591a6700b01b75d535b0382145 100644 (file)
@@ -172,17 +172,7 @@ static struct platform_driver pcm3008_codec_driver = {
        },
 };
 
-static int __init pcm3008_modinit(void)
-{
-       return platform_driver_register(&pcm3008_codec_driver);
-}
-module_init(pcm3008_modinit);
-
-static void __exit pcm3008_exit(void)
-{
-       platform_driver_unregister(&pcm3008_codec_driver);
-}
-module_exit(pcm3008_exit);
+module_platform_driver(pcm3008_codec_driver);
 
 MODULE_DESCRIPTION("Soc PCM3008 driver");
 MODULE_AUTHOR("Hugo Villeneuve");
index 4646e808b90a334e0d59935a1e93244672d276be..9fd50bd77c491bdf28b10270b1429358932b41a9 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -1664,7 +1663,7 @@ static int rt5631_resume(struct snd_soc_codec *codec)
                        SNDRV_PCM_FMTBIT_S24_LE | \
                        SNDRV_PCM_FMTBIT_S8)
 
-static struct snd_soc_dai_ops rt5631_ops = {
+static const struct snd_soc_dai_ops rt5631_ops = {
        .hw_params = rt5631_hifi_pcm_params,
        .set_fmt = rt5631_hifi_codec_set_dai_fmt,
        .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
index bbcf921166f7470fad24577d2aa52d1cf85258f4..ff0a1079efec278a6edadd518b8e8f8d8743528d 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/clk.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/consumer.h>
@@ -923,7 +922,7 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
                        SNDRV_PCM_FMTBIT_S24_LE |\
                        SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops sgtl5000_ops = {
+static const struct snd_soc_dai_ops sgtl5000_ops = {
        .hw_params = sgtl5000_pcm_hw_params,
        .digital_mute = sgtl5000_digital_mute,
        .set_fmt = sgtl5000_set_dai_fmt,
index 887d618f4a639720b7e0698e086333f203175a7a..f99baa0b8c39133b5cbc342368b4ac98f79cb365 100644 (file)
@@ -698,21 +698,21 @@ static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
 }
 
 /* Codec DAI section */
-static struct snd_soc_dai_ops sn95031_headset_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_headset_dai_ops = {
        .digital_mute   = sn95031_pcm_hs_mute,
        .hw_params      = sn95031_pcm_hw_params,
 };
 
-static struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
        .digital_mute   = sn95031_pcm_spkr_mute,
        .hw_params      = sn95031_pcm_hw_params,
 };
 
-static struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
        .hw_params      = sn95031_pcm_hw_params,
 };
 
-static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
+static const struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
        .hw_params      = sn95031_pcm_hw_params,
 };
 
@@ -920,19 +920,7 @@ static struct platform_driver sn95031_codec_driver = {
        .remove         = __devexit_p(sn95031_device_remove),
 };
 
-static int __init sn95031_init(void)
-{
-       pr_debug("driver init called\n");
-       return platform_driver_register(&sn95031_codec_driver);
-}
-module_init(sn95031_init);
-
-static void __exit sn95031_exit(void)
-{
-       pr_debug("driver exit called\n");
-       platform_driver_unregister(&sn95031_codec_driver);
-}
-module_exit(sn95031_exit);
+module_platform_driver(sn95031_codec_driver);
 
 MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
index 6a1a7e705cd767ffd11365252c88b70fe7c98ad1..112a49d66e3967847517b495872baa606a967189 100644 (file)
@@ -61,18 +61,7 @@ static struct platform_driver spdif_dit_driver = {
        },
 };
 
-static int __init dit_modinit(void)
-{
-       return platform_driver_register(&spdif_dit_driver);
-}
-
-static void __exit dit_exit(void)
-{
-       platform_driver_unregister(&spdif_dit_driver);
-}
-
-module_init(dit_modinit);
-module_exit(dit_exit);
+module_platform_driver(spdif_dit_driver);
 
 MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
 MODULE_DESCRIPTION("SPDIF dummy codec driver");
index 3cb3271c5fe2019501cde20e9f1b73f872476282..0d43e4b4a5868475004f0dac39dd30edc23e09e0 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -498,7 +497,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
 #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops ssm2602_dai_ops = {
+static const struct snd_soc_dai_ops ssm2602_dai_ops = {
        .startup        = ssm2602_startup,
        .hw_params      = ssm2602_hw_params,
        .shutdown       = ssm2602_shutdown,
index d2f37152f940cebc67f93a5bff140e64a67a07e7..b3d1c78e361f4cc47320db29b72947b09456416d 100644 (file)
@@ -24,9 +24,9 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -35,6 +35,7 @@
 #include <sound/initval.h>
 #include <sound/tlv.h>
 
+#include <sound/sta32x.h>
 #include "sta32x.h"
 
 #define STA32X_RATES (SNDRV_PCM_RATE_32000 | \
@@ -73,11 +74,14 @@ static const char *sta32x_supply_names[] = {
 struct sta32x_priv {
        struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
        struct snd_soc_codec *codec;
+       struct sta32x_platform_data *pdata;
 
        unsigned int mclk;
        unsigned int format;
 
        u32 coef_shadow[STA32X_COEF_COUNT];
+       struct delayed_work watchdog_work;
+       int shutdown;
 };
 
 static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
@@ -260,7 +264,7 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
+static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
 {
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
        unsigned int cfud;
@@ -285,7 +289,7 @@ int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
        return 0;
 }
 
-int sta32x_cache_sync(struct snd_soc_codec *codec)
+static int sta32x_cache_sync(struct snd_soc_codec *codec)
 {
        unsigned int mute;
        int rc;
@@ -302,6 +306,46 @@ int sta32x_cache_sync(struct snd_soc_codec *codec)
        return rc;
 }
 
+/* work around ESD issue where sta32x resets and loses all configuration */
+static void sta32x_watchdog(struct work_struct *work)
+{
+       struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv,
+                                                 watchdog_work.work);
+       struct snd_soc_codec *codec = sta32x->codec;
+       unsigned int confa, confa_cached;
+
+       /* check if sta32x has reset itself */
+       confa_cached = snd_soc_read(codec, STA32X_CONFA);
+       codec->cache_bypass = 1;
+       confa = snd_soc_read(codec, STA32X_CONFA);
+       codec->cache_bypass = 0;
+       if (confa != confa_cached) {
+               codec->cache_sync = 1;
+               sta32x_cache_sync(codec);
+       }
+
+       if (!sta32x->shutdown)
+               schedule_delayed_work(&sta32x->watchdog_work,
+                                     round_jiffies_relative(HZ));
+}
+
+static void sta32x_watchdog_start(struct sta32x_priv *sta32x)
+{
+       if (sta32x->pdata->needs_esd_watchdog) {
+               sta32x->shutdown = 0;
+               schedule_delayed_work(&sta32x->watchdog_work,
+                                     round_jiffies_relative(HZ));
+       }
+}
+
+static void sta32x_watchdog_stop(struct sta32x_priv *sta32x)
+{
+       if (sta32x->pdata->needs_esd_watchdog) {
+               sta32x->shutdown = 1;
+               cancel_delayed_work_sync(&sta32x->watchdog_work);
+       }
+}
+
 #define SINGLE_COEF(xname, index) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
        .info = sta32x_coefficient_info, \
@@ -712,6 +756,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
                        }
 
                        sta32x_cache_sync(codec);
+                       sta32x_watchdog_start(sta32x);
                }
 
                /* Power up to mute */
@@ -728,7 +773,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
                                    STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
                                    STA32X_CONFF_PWDN);
                msleep(300);
-
+               sta32x_watchdog_stop(sta32x);
                regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
                                       sta32x->supplies);
                break;
@@ -737,7 +782,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static struct snd_soc_dai_ops sta32x_dai_ops = {
+static const struct snd_soc_dai_ops sta32x_dai_ops = {
        .hw_params      = sta32x_hw_params,
        .set_sysclk     = sta32x_set_dai_sysclk,
        .set_fmt        = sta32x_set_dai_fmt,
@@ -775,9 +820,10 @@ static int sta32x_resume(struct snd_soc_codec *codec)
 static int sta32x_probe(struct snd_soc_codec *codec)
 {
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
-       int i, ret = 0;
+       int i, ret = 0, thermal = 0;
 
        sta32x->codec = codec;
+       sta32x->pdata = dev_get_platdata(codec->dev);
 
        /* regulators */
        for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
@@ -820,25 +866,34 @@ static int sta32x_probe(struct snd_soc_codec *codec)
        snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
        snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
 
-       /* FIXME enable thermal warning adjustment and recovery  */
+       /* set thermal warning adjustment and recovery */
+       if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
+               thermal |= STA32X_CONFA_TWAB;
+       if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
+               thermal |= STA32X_CONFA_TWRB;
        snd_soc_update_bits(codec, STA32X_CONFA,
-                           STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, 0);
+                           STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
+                           thermal);
 
-       /* FIXME select 2.1 mode  */
+       /* select output configuration  */
        snd_soc_update_bits(codec, STA32X_CONFF,
                            STA32X_CONFF_OCFG_MASK,
-                           1 << STA32X_CONFF_OCFG_SHIFT);
+                           sta32x->pdata->output_conf
+                           << STA32X_CONFF_OCFG_SHIFT);
 
-       /* FIXME channel to output mapping */
+       /* channel to output mapping */
        snd_soc_update_bits(codec, STA32X_C1CFG,
                            STA32X_CxCFG_OM_MASK,
-                           0 << STA32X_CxCFG_OM_SHIFT);
+                           sta32x->pdata->ch1_output_mapping
+                           << STA32X_CxCFG_OM_SHIFT);
        snd_soc_update_bits(codec, STA32X_C2CFG,
                            STA32X_CxCFG_OM_MASK,
-                           1 << STA32X_CxCFG_OM_SHIFT);
+                           sta32x->pdata->ch2_output_mapping
+                           << STA32X_CxCFG_OM_SHIFT);
        snd_soc_update_bits(codec, STA32X_C3CFG,
                            STA32X_CxCFG_OM_MASK,
-                           2 << STA32X_CxCFG_OM_SHIFT);
+                           sta32x->pdata->ch3_output_mapping
+                           << STA32X_CxCFG_OM_SHIFT);
 
        /* initialize coefficient shadow RAM with reset values */
        for (i = 4; i <= 49; i += 5)
@@ -851,6 +906,9 @@ static int sta32x_probe(struct snd_soc_codec *codec)
        sta32x->coef_shadow[60] = 0x400000;
        sta32x->coef_shadow[61] = 0x400000;
 
+       if (sta32x->pdata->needs_esd_watchdog)
+               INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
+
        sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
        /* Bias level configuration will have done an extra enable */
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
@@ -867,6 +925,7 @@ static int sta32x_remove(struct snd_soc_codec *codec)
 {
        struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
 
+       sta32x_watchdog_stop(sta32x);
        sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
        regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
        regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
index 78b2b50271e25893ade9c8b0ce3b0f0be6ab4e92..55819537b6776c0f3cc9569c9337cb43a97d86b1 100644 (file)
@@ -286,11 +286,11 @@ reset:
        return 0;
 }
 
-static struct snd_soc_dai_ops stac9766_dai_ops_analog = {
+static const struct snd_soc_dai_ops stac9766_dai_ops_analog = {
        .prepare = ac97_analog_prepare,
 };
 
-static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
+static const struct snd_soc_dai_ops stac9766_dai_ops_digital = {
        .prepare = ac97_digital_prepare,
 };
 
@@ -408,17 +408,7 @@ static struct platform_driver stac9766_codec_driver = {
        .remove = __devexit_p(stac9766_remove),
 };
 
-static int __init stac9766_init(void)
-{
-       return platform_driver_register(&stac9766_codec_driver);
-}
-module_init(stac9766_init);
-
-static void __exit stac9766_exit(void)
-{
-       platform_driver_unregister(&stac9766_codec_driver);
-}
-module_exit(stac9766_exit);
+module_platform_driver(stac9766_codec_driver);
 
 MODULE_DESCRIPTION("ASoC stac9766 driver");
 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
index 336de8f69a026e9a6da20af04f3b821d5ba69a33..cba798e1a07e92071f2d44f8d3ca0b97d61f574d 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -503,7 +502,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
 #define AIC23_FORMATS  (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
                         SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops tlv320aic23_dai_ops = {
+static const struct snd_soc_dai_ops tlv320aic23_dai_ops = {
        .prepare        = tlv320aic23_pcm_prepare,
        .hw_params      = tlv320aic23_hw_params,
        .shutdown       = tlv320aic23_shutdown,
index 7859bdcc93db4064cad1474a8fe2533e19026f1e..86d1fa38ed2e7d8afcf0d19f8eb8786232505c8e 100644 (file)
@@ -275,7 +275,7 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 #define AIC26_FORMATS  (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_BE |\
                         SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
 
-static struct snd_soc_dai_ops aic26_dai_ops = {
+static const struct snd_soc_dai_ops aic26_dai_ops = {
        .hw_params      = aic26_hw_params,
        .digital_mute   = aic26_mute,
        .set_sysclk     = aic26_set_sysclk,
index b21c610051c0f53c03ab2f6c42bf9b12ef20dda9..f553375673792c359a8883e77e0a6040e6e12c4b 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/cdev.h>
 #include <linux/slab.h>
 
@@ -597,7 +596,7 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
 #define AIC32X4_FORMATS        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
                         | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops aic32x4_ops = {
+static const struct snd_soc_dai_ops aic32x4_ops = {
        .hw_params = aic32x4_hw_params,
        .digital_mute = aic32x4_mute,
        .set_fmt = aic32x4_set_dai_fmt,
index 87d5ef188e29484fe303931c71cc45ac30005cce..21625dddde23a41c95d1742c0cffc61aa9d1c5b9 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -833,7 +832,6 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
        int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
        u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
        u16 d, pll_d = 1;
-       u8 reg;
        int clk;
 
        /* select data word length */
@@ -869,14 +867,13 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
                snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
                snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
                /* disable PLL if it is bypassed */
-               reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
-               snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE);
+               snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
 
        } else {
                snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
                /* enable PLL when it is used */
-               reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
-               snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
+               snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+                                   PLL_ENABLE, PLL_ENABLE);
        }
 
        /* Route Left DAC to left channel input and
@@ -1156,7 +1153,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
                                enum snd_soc_bias_level level)
 {
        struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-       u8 reg;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -1165,9 +1161,8 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
                if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
                    aic3x->master) {
                        /* enable pll */
-                       reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
-                       snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
-                                     reg | PLL_ENABLE);
+                       snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+                                           PLL_ENABLE, PLL_ENABLE);
                }
                break;
        case SND_SOC_BIAS_STANDBY:
@@ -1176,9 +1171,8 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
                if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
                    aic3x->master) {
                        /* disable pll */
-                       reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
-                       snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
-                                     reg & ~PLL_ENABLE);
+                       snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
+                                           PLL_ENABLE, 0);
                }
                break;
        case SND_SOC_BIAS_OFF:
@@ -1249,7 +1243,7 @@ EXPORT_SYMBOL_GPL(aic3x_button_pressed);
 #define AIC3X_FORMATS  (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
                         SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops aic3x_dai_ops = {
+static const struct snd_soc_dai_ops aic3x_dai_ops = {
        .hw_params      = aic3x_hw_params,
        .digital_mute   = aic3x_mute,
        .set_sysclk     = aic3x_set_dai_sysclk,
@@ -1295,7 +1289,6 @@ static int aic3x_resume(struct snd_soc_codec *codec)
 static int aic3x_init(struct snd_soc_codec *codec)
 {
        struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
-       int reg;
 
        snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
        snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
@@ -1317,20 +1310,13 @@ static int aic3x_init(struct snd_soc_codec *codec)
        snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
 
        /* unmute all outputs */
-       reg = snd_soc_read(codec, LLOPM_CTRL);
-       snd_soc_write(codec, LLOPM_CTRL, reg | UNMUTE);
-       reg = snd_soc_read(codec, RLOPM_CTRL);
-       snd_soc_write(codec, RLOPM_CTRL, reg | UNMUTE);
-       reg = snd_soc_read(codec, MONOLOPM_CTRL);
-       snd_soc_write(codec, MONOLOPM_CTRL, reg | UNMUTE);
-       reg = snd_soc_read(codec, HPLOUT_CTRL);
-       snd_soc_write(codec, HPLOUT_CTRL, reg | UNMUTE);
-       reg = snd_soc_read(codec, HPROUT_CTRL);
-       snd_soc_write(codec, HPROUT_CTRL, reg | UNMUTE);
-       reg = snd_soc_read(codec, HPLCOM_CTRL);
-       snd_soc_write(codec, HPLCOM_CTRL, reg | UNMUTE);
-       reg = snd_soc_read(codec, HPRCOM_CTRL);
-       snd_soc_write(codec, HPRCOM_CTRL, reg | UNMUTE);
+       snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
+       snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE);
+       snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
+       snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE);
 
        /* ADC default volume and unmute */
        snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
@@ -1494,7 +1480,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
        .resume = aic3x_resume,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 /*
  * AIC3X 2 wire address can be up to 4 devices with device addresses
  * 0x18, 0x19, 0x1A, 0x1B
@@ -1561,27 +1546,22 @@ static struct i2c_driver aic3x_i2c_driver = {
        .remove = aic3x_i2c_remove,
        .id_table = aic3x_i2c_id,
 };
-#endif
 
 static int __init aic3x_modinit(void)
 {
        int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
        ret = i2c_add_driver(&aic3x_i2c_driver);
        if (ret != 0) {
                printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
                       ret);
        }
-#endif
        return ret;
 }
 module_init(aic3x_modinit);
 
 static void __exit aic3x_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
        i2c_del_driver(&aic3x_i2c_driver);
-#endif
 }
 module_exit(aic3x_exit);
 
index dc8a2b2bdc1ce73b939cc0455f7ba4931c153c2e..6b0f0e220f85466ac1334f4483cdcd73e676c3f1 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
@@ -1499,7 +1498,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
                         SNDRV_PCM_RATE_48000)
 #define DAC33_FORMATS  (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops dac33_dai_ops = {
+static const struct snd_soc_dai_ops dac33_dai_ops = {
        .startup        = dac33_startup,
        .shutdown       = dac33_shutdown,
        .hw_params      = dac33_hw_params,
index f798247ac1b2071e7316200be605734ed87faf6d..61d8a9065ff3cb8f779e8aa1be9c9cd3f47ea3b1 100644 (file)
@@ -2149,7 +2149,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
 #define TWL4030_RATES   (SNDRV_PCM_RATE_8000_48000)
 #define TWL4030_FORMATS         (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
+static const struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
        .startup        = twl4030_startup,
        .shutdown       = twl4030_shutdown,
        .hw_params      = twl4030_hw_params,
@@ -2158,7 +2158,7 @@ static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
        .set_tristate   = twl4030_set_tristate,
 };
 
-static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
+static const struct snd_soc_dai_ops twl4030_dai_voice_ops = {
        .startup        = twl4030_voice_startup,
        .shutdown       = twl4030_voice_shutdown,
        .hw_params      = twl4030_voice_hw_params,
@@ -2294,17 +2294,7 @@ static struct platform_driver twl4030_codec_driver = {
        },
 };
 
-static int __init twl4030_modinit(void)
-{
-       return platform_driver_register(&twl4030_codec_driver);
-}
-module_init(twl4030_modinit);
-
-static void __exit twl4030_exit(void)
-{
-       platform_driver_unregister(&twl4030_codec_driver);
-}
-module_exit(twl4030_exit);
+module_platform_driver(twl4030_codec_driver);
 
 MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
 MODULE_AUTHOR("Steve Sakoman");
index 73e11f022dedc944c1010064435b17402b96194c..a4a65dc9e33afaa69fe85d1a26d3f6b60fd035d5 100644 (file)
@@ -1397,7 +1397,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
        return 0;
 }
 
-static struct snd_soc_dai_ops twl6040_dai_ops = {
+static const struct snd_soc_dai_ops twl6040_dai_ops = {
        .startup        = twl6040_startup,
        .hw_params      = twl6040_hw_params,
        .prepare        = twl6040_prepare,
@@ -1620,17 +1620,7 @@ static struct platform_driver twl6040_codec_driver = {
        .remove = __devexit_p(twl6040_codec_remove),
 };
 
-static int __init twl6040_codec_init(void)
-{
-       return platform_driver_register(&twl6040_codec_driver);
-}
-module_init(twl6040_codec_init);
-
-static void __exit twl6040_codec_exit(void)
-{
-       platform_driver_unregister(&twl6040_codec_driver);
-}
-module_exit(twl6040_codec_exit);
+module_platform_driver(twl6040_codec_driver);
 
 MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
 MODULE_AUTHOR("Misael Lopez Cruz");
index a7b8f301bad39b3ef7a691273d4d3ba4bf4b9097..d0f9d904ce8f8420161166a981f8767d886f553e 100644 (file)
@@ -452,7 +452,7 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
 };
 
-static struct snd_soc_dai_ops uda134x_dai_ops = {
+static const struct snd_soc_dai_ops uda134x_dai_ops = {
        .startup        = uda134x_startup,
        .shutdown       = uda134x_shutdown,
        .hw_params      = uda134x_hw_params,
@@ -625,17 +625,7 @@ static struct platform_driver uda134x_codec_driver = {
        .remove = __devexit_p(uda134x_codec_remove),
 };
 
-static int __init uda134x_codec_init(void)
-{
-       return platform_driver_register(&uda134x_codec_driver);
-}
-module_init(uda134x_codec_init);
-
-static void __exit uda134x_codec_exit(void)
-{
-       platform_driver_unregister(&uda134x_codec_driver);
-}
-module_exit(uda134x_codec_exit);
+module_platform_driver(uda134x_codec_driver);
 
 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
index c5ca8cfea60f80f8de27cc5d12ad55f69bd900f2..6b933efc7ed3bfbe6c1d1e012e26caa4aca02261 100644 (file)
@@ -643,21 +643,21 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
                       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
                       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_dai_ops uda1380_dai_ops = {
+static const struct snd_soc_dai_ops uda1380_dai_ops = {
        .hw_params      = uda1380_pcm_hw_params,
        .shutdown       = uda1380_pcm_shutdown,
        .trigger        = uda1380_trigger,
        .set_fmt        = uda1380_set_dai_fmt_both,
 };
 
-static struct snd_soc_dai_ops uda1380_dai_ops_playback = {
+static const struct snd_soc_dai_ops uda1380_dai_ops_playback = {
        .hw_params      = uda1380_pcm_hw_params,
        .shutdown       = uda1380_pcm_shutdown,
        .trigger        = uda1380_trigger,
        .set_fmt        = uda1380_set_dai_fmt_playback,
 };
 
-static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
+static const struct snd_soc_dai_ops uda1380_dai_ops_capture = {
        .hw_params      = uda1380_pcm_hw_params,
        .shutdown       = uda1380_pcm_shutdown,
        .trigger        = uda1380_trigger,
index a854989829911a62eae6fdf3cf3336b917f748c4..44aacf927ba99d6a533524b39859eac9d565c265 100644 (file)
@@ -386,7 +386,7 @@ static int wl1273_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops wl1273_dai_ops = {
+static const struct snd_soc_dai_ops wl1273_dai_ops = {
        .startup        = wl1273_startup,
        .hw_params      = wl1273_hw_params,
 };
@@ -510,17 +510,7 @@ static struct platform_driver wl1273_platform_driver = {
        .remove         = __devexit_p(wl1273_platform_remove),
 };
 
-static int __init wl1273_init(void)
-{
-       return platform_driver_register(&wl1273_platform_driver);
-}
-module_init(wl1273_init);
-
-static void __exit wl1273_exit(void)
-{
-       platform_driver_unregister(&wl1273_platform_driver);
-}
-module_exit(wl1273_exit);
+module_platform_driver(wl1273_platform_driver);
 
 MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
 MODULE_DESCRIPTION("ASoC WL1273 codec driver");
index cd0ec0fd1dbab536579b296884275cc14828326a..aefb4f89be0eb23b108e01581e86a52299961904 100644 (file)
@@ -116,7 +116,7 @@ static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c)
        if (!pdata)
                return 0;
 
-       wm1250 = kzalloc(sizeof(*wm1250), GFP_KERNEL);
+       wm1250 = devm_kzalloc(&i2c->dev, sizeof(*wm1250), GFP_KERNEL);
        if (!wm1250) {
                dev_err(&i2c->dev, "Unable to allocate private data\n");
                ret = -ENOMEM;
@@ -134,15 +134,13 @@ static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c)
        ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
        if (ret != 0) {
                dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret);
-               goto err_alloc;
+               goto err;
        }
 
        dev_set_drvdata(&i2c->dev, wm1250);
 
        return ret;
 
-err_alloc:
-       kfree(wm1250);
 err:
        return ret;
 }
@@ -151,10 +149,8 @@ static void wm1250_ev1_free(struct i2c_client *i2c)
 {
        struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev);
 
-       if (wm1250) {
+       if (wm1250)
                gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
-               kfree(wm1250);
-       }
 }
 
 static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
index a3b9cbb20ee9bc07ca849fbe4f7af593048da9c8..01b1abe7a36b1a801abe2f8cd78bc51d36f0bb8c 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
 #include <sound/core.h>
index e9ce81a57b856af0d4cc57f510195f75bba8c7c7..9a18fae68204f790a19c75e7fc527e1b25d3a1f5 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "wm5100.h"
 
-int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+bool wm5100_volatile_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM5100_SOFTWARE_RESET:
@@ -36,7 +36,7 @@ int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
        }
 }
 
-int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg)
+bool wm5100_readable_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM5100_SOFTWARE_RESET:
@@ -85,6 +85,7 @@ int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg)
        case WM5100_MIC_DETECT_1:
        case WM5100_MIC_DETECT_2:
        case WM5100_MIC_DETECT_3:
+       case WM5100_MISC_CONTROL:
        case WM5100_INPUT_ENABLES:
        case WM5100_INPUT_ENABLES_STATUS:
        case WM5100_IN1L_CONTROL:
@@ -696,836 +697,668 @@ int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg)
        case WM5100_HPLPF3_2:
        case WM5100_HPLPF4_1:
        case WM5100_HPLPF4_2:
-       case WM5100_DSP1_DM_0:
-       case WM5100_DSP1_DM_1:
-       case WM5100_DSP1_DM_2:
-       case WM5100_DSP1_DM_3:
-       case WM5100_DSP1_DM_508:
-       case WM5100_DSP1_DM_509:
-       case WM5100_DSP1_DM_510:
-       case WM5100_DSP1_DM_511:
-       case WM5100_DSP1_PM_0:
-       case WM5100_DSP1_PM_1:
-       case WM5100_DSP1_PM_2:
-       case WM5100_DSP1_PM_3:
-       case WM5100_DSP1_PM_4:
-       case WM5100_DSP1_PM_5:
-       case WM5100_DSP1_PM_1530:
-       case WM5100_DSP1_PM_1531:
-       case WM5100_DSP1_PM_1532:
-       case WM5100_DSP1_PM_1533:
-       case WM5100_DSP1_PM_1534:
-       case WM5100_DSP1_PM_1535:
-       case WM5100_DSP1_ZM_0:
-       case WM5100_DSP1_ZM_1:
-       case WM5100_DSP1_ZM_2:
-       case WM5100_DSP1_ZM_3:
-       case WM5100_DSP1_ZM_2044:
-       case WM5100_DSP1_ZM_2045:
-       case WM5100_DSP1_ZM_2046:
-       case WM5100_DSP1_ZM_2047:
-       case WM5100_DSP2_DM_0:
-       case WM5100_DSP2_DM_1:
-       case WM5100_DSP2_DM_2:
-       case WM5100_DSP2_DM_3:
-       case WM5100_DSP2_DM_508:
-       case WM5100_DSP2_DM_509:
-       case WM5100_DSP2_DM_510:
-       case WM5100_DSP2_DM_511:
-       case WM5100_DSP2_PM_0:
-       case WM5100_DSP2_PM_1:
-       case WM5100_DSP2_PM_2:
-       case WM5100_DSP2_PM_3:
-       case WM5100_DSP2_PM_4:
-       case WM5100_DSP2_PM_5:
-       case WM5100_DSP2_PM_1530:
-       case WM5100_DSP2_PM_1531:
-       case WM5100_DSP2_PM_1532:
-       case WM5100_DSP2_PM_1533:
-       case WM5100_DSP2_PM_1534:
-       case WM5100_DSP2_PM_1535:
-       case WM5100_DSP2_ZM_0:
-       case WM5100_DSP2_ZM_1:
-       case WM5100_DSP2_ZM_2:
-       case WM5100_DSP2_ZM_3:
-       case WM5100_DSP2_ZM_2044:
-       case WM5100_DSP2_ZM_2045:
-       case WM5100_DSP2_ZM_2046:
-       case WM5100_DSP2_ZM_2047:
-       case WM5100_DSP3_DM_0:
-       case WM5100_DSP3_DM_1:
-       case WM5100_DSP3_DM_2:
-       case WM5100_DSP3_DM_3:
-       case WM5100_DSP3_DM_508:
-       case WM5100_DSP3_DM_509:
-       case WM5100_DSP3_DM_510:
-       case WM5100_DSP3_DM_511:
-       case WM5100_DSP3_PM_0:
-       case WM5100_DSP3_PM_1:
-       case WM5100_DSP3_PM_2:
-       case WM5100_DSP3_PM_3:
-       case WM5100_DSP3_PM_4:
-       case WM5100_DSP3_PM_5:
-       case WM5100_DSP3_PM_1530:
-       case WM5100_DSP3_PM_1531:
-       case WM5100_DSP3_PM_1532:
-       case WM5100_DSP3_PM_1533:
-       case WM5100_DSP3_PM_1534:
-       case WM5100_DSP3_PM_1535:
-       case WM5100_DSP3_ZM_0:
-       case WM5100_DSP3_ZM_1:
-       case WM5100_DSP3_ZM_2:
-       case WM5100_DSP3_ZM_3:
-       case WM5100_DSP3_ZM_2044:
-       case WM5100_DSP3_ZM_2045:
-       case WM5100_DSP3_ZM_2046:
-       case WM5100_DSP3_ZM_2047:
                return 1;
        default:
                return 0;
        }
 }
 
-u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1] = {
-       [0x0000] = 0x0000,     /* R0     - software reset */
-       [0x0001] = 0x0000,     /* R1     - Device Revision */
-       [0x0010] = 0x0801,     /* R16    - Ctrl IF 1 */
-       [0x0020] = 0x0000,     /* R32    - Tone Generator 1 */
-       [0x0030] = 0x0000,     /* R48    - PWM Drive 1 */
-       [0x0031] = 0x0100,     /* R49    - PWM Drive 2 */
-       [0x0032] = 0x0100,     /* R50    - PWM Drive 3 */
-       [0x0100] = 0x0002,     /* R256   - Clocking 1 */
-       [0x0101] = 0x0000,     /* R257   - Clocking 3 */
-       [0x0102] = 0x0011,     /* R258   - Clocking 4 */
-       [0x0103] = 0x0011,     /* R259   - Clocking 5 */
-       [0x0104] = 0x0011,     /* R260   - Clocking 6 */
-       [0x0107] = 0x0000,     /* R263   - Clocking 7 */
-       [0x0108] = 0x0000,     /* R264   - Clocking 8 */
-       [0x0120] = 0x0000,     /* R288   - ASRC_ENABLE */
-       [0x0121] = 0x0000,     /* R289   - ASRC_STATUS */
-       [0x0122] = 0x0000,     /* R290   - ASRC_RATE1 */
-       [0x0141] = 0x8000,     /* R321   - ISRC 1 CTRL 1 */
-       [0x0142] = 0x0000,     /* R322   - ISRC 1 CTRL 2 */
-       [0x0143] = 0x8000,     /* R323   - ISRC 2 CTRL1 */
-       [0x0144] = 0x0000,     /* R324   - ISRC 2 CTRL 2 */
-       [0x0182] = 0x0000,     /* R386   - FLL1 Control 1 */
-       [0x0183] = 0x0000,     /* R387   - FLL1 Control 2 */
-       [0x0184] = 0x0000,     /* R388   - FLL1 Control 3 */
-       [0x0186] = 0x0177,     /* R390   - FLL1 Control 5 */
-       [0x0187] = 0x0001,     /* R391   - FLL1 Control 6 */
-       [0x0188] = 0x0000,     /* R392   - FLL1 EFS 1 */
-       [0x01A2] = 0x0000,     /* R418   - FLL2 Control 1 */
-       [0x01A3] = 0x0000,     /* R419   - FLL2 Control 2 */
-       [0x01A4] = 0x0000,     /* R420   - FLL2 Control 3 */
-       [0x01A6] = 0x0177,     /* R422   - FLL2 Control 5 */
-       [0x01A7] = 0x0001,     /* R423   - FLL2 Control 6 */
-       [0x01A8] = 0x0000,     /* R424   - FLL2 EFS 1 */
-       [0x0200] = 0x0020,     /* R512   - Mic Charge Pump 1 */
-       [0x0201] = 0xB084,     /* R513   - Mic Charge Pump 2 */
-       [0x0202] = 0xBBDE,     /* R514   - HP Charge Pump 1 */
-       [0x0211] = 0x20D4,     /* R529   - LDO1 Control */
-       [0x0215] = 0x0062,     /* R533   - Mic Bias Ctrl 1 */
-       [0x0216] = 0x0062,     /* R534   - Mic Bias Ctrl 2 */
-       [0x0217] = 0x0062,     /* R535   - Mic Bias Ctrl 3 */
-       [0x0280] = 0x0004,     /* R640   - Accessory Detect Mode 1 */
-       [0x0288] = 0x0020,     /* R648   - Headphone Detect 1 */
-       [0x0289] = 0x0000,     /* R649   - Headphone Detect 2 */
-       [0x0290] = 0x1100,     /* R656   - Mic Detect 1 */
-       [0x0291] = 0x009F,     /* R657   - Mic Detect 2 */
-       [0x0292] = 0x0000,     /* R658   - Mic Detect 3 */
-       [0x0301] = 0x0000,     /* R769   - Input Enables */
-       [0x0302] = 0x0000,     /* R770   - Input Enables Status */
-       [0x0310] = 0x2280,     /* R784   - Status */
-       [0x0311] = 0x0080,     /* R785   - IN1R Control */
-       [0x0312] = 0x2280,     /* R786   - IN2L Control */
-       [0x0313] = 0x0080,     /* R787   - IN2R Control */
-       [0x0314] = 0x2280,     /* R788   - IN3L Control */
-       [0x0315] = 0x0080,     /* R789   - IN3R Control */
-       [0x0316] = 0x2280,     /* R790   - IN4L Control */
-       [0x0317] = 0x0080,     /* R791   - IN4R Control */
-       [0x0318] = 0x0000,     /* R792   - RXANC_SRC */
-       [0x0319] = 0x0022,     /* R793   - Input Volume Ramp */
-       [0x0320] = 0x0180,     /* R800   - ADC Digital Volume 1L */
-       [0x0321] = 0x0180,     /* R801   - ADC Digital Volume 1R */
-       [0x0322] = 0x0180,     /* R802   - ADC Digital Volume 2L */
-       [0x0323] = 0x0180,     /* R803   - ADC Digital Volume 2R */
-       [0x0324] = 0x0180,     /* R804   - ADC Digital Volume 3L */
-       [0x0325] = 0x0180,     /* R805   - ADC Digital Volume 3R */
-       [0x0326] = 0x0180,     /* R806   - ADC Digital Volume 4L */
-       [0x0327] = 0x0180,     /* R807   - ADC Digital Volume 4R */
-       [0x0401] = 0x0000,     /* R1025  - Output Enables 2 */
-       [0x0402] = 0x0000,     /* R1026  - Output Status 1 */
-       [0x0403] = 0x0000,     /* R1027  - Output Status 2 */
-       [0x0408] = 0x0000,     /* R1032  - Channel Enables 1 */
-       [0x0410] = 0x0080,     /* R1040  - Out Volume 1L */
-       [0x0411] = 0x0080,     /* R1041  - Out Volume 1R */
-       [0x0412] = 0x0080,     /* R1042  - DAC Volume Limit 1L */
-       [0x0413] = 0x0080,     /* R1043  - DAC Volume Limit 1R */
-       [0x0414] = 0x0080,     /* R1044  - Out Volume 2L */
-       [0x0415] = 0x0080,     /* R1045  - Out Volume 2R */
-       [0x0416] = 0x0080,     /* R1046  - DAC Volume Limit 2L */
-       [0x0417] = 0x0080,     /* R1047  - DAC Volume Limit 2R */
-       [0x0418] = 0x0080,     /* R1048  - Out Volume 3L */
-       [0x0419] = 0x0080,     /* R1049  - Out Volume 3R */
-       [0x041A] = 0x0080,     /* R1050  - DAC Volume Limit 3L */
-       [0x041B] = 0x0080,     /* R1051  - DAC Volume Limit 3R */
-       [0x041C] = 0x0080,     /* R1052  - Out Volume 4L */
-       [0x041D] = 0x0080,     /* R1053  - Out Volume 4R */
-       [0x041E] = 0x0080,     /* R1054  - DAC Volume Limit 5L */
-       [0x041F] = 0x0080,     /* R1055  - DAC Volume Limit 5R */
-       [0x0420] = 0x0080,     /* R1056  - DAC Volume Limit 6L */
-       [0x0421] = 0x0080,     /* R1057  - DAC Volume Limit 6R */
-       [0x0440] = 0x0000,     /* R1088  - DAC AEC Control 1 */
-       [0x0441] = 0x0022,     /* R1089  - Output Volume Ramp */
-       [0x0480] = 0x0180,     /* R1152  - DAC Digital Volume 1L */
-       [0x0481] = 0x0180,     /* R1153  - DAC Digital Volume 1R */
-       [0x0482] = 0x0180,     /* R1154  - DAC Digital Volume 2L */
-       [0x0483] = 0x0180,     /* R1155  - DAC Digital Volume 2R */
-       [0x0484] = 0x0180,     /* R1156  - DAC Digital Volume 3L */
-       [0x0485] = 0x0180,     /* R1157  - DAC Digital Volume 3R */
-       [0x0486] = 0x0180,     /* R1158  - DAC Digital Volume 4L */
-       [0x0487] = 0x0180,     /* R1159  - DAC Digital Volume 4R */
-       [0x0488] = 0x0180,     /* R1160  - DAC Digital Volume 5L */
-       [0x0489] = 0x0180,     /* R1161  - DAC Digital Volume 5R */
-       [0x048A] = 0x0180,     /* R1162  - DAC Digital Volume 6L */
-       [0x048B] = 0x0180,     /* R1163  - DAC Digital Volume 6R */
-       [0x04C0] = 0x0069,     /* R1216  - PDM SPK1 CTRL 1 */
-       [0x04C1] = 0x0000,     /* R1217  - PDM SPK1 CTRL 2 */
-       [0x04C2] = 0x0069,     /* R1218  - PDM SPK2 CTRL 1 */
-       [0x04C3] = 0x0000,     /* R1219  - PDM SPK2 CTRL 2 */
-       [0x0500] = 0x000C,     /* R1280  - Audio IF 1_1 */
-       [0x0501] = 0x0008,     /* R1281  - Audio IF 1_2 */
-       [0x0502] = 0x0000,     /* R1282  - Audio IF 1_3 */
-       [0x0503] = 0x0000,     /* R1283  - Audio IF 1_4 */
-       [0x0504] = 0x0000,     /* R1284  - Audio IF 1_5 */
-       [0x0505] = 0x0300,     /* R1285  - Audio IF 1_6 */
-       [0x0506] = 0x0300,     /* R1286  - Audio IF 1_7 */
-       [0x0507] = 0x1820,     /* R1287  - Audio IF 1_8 */
-       [0x0508] = 0x1820,     /* R1288  - Audio IF 1_9 */
-       [0x0509] = 0x0000,     /* R1289  - Audio IF 1_10 */
-       [0x050A] = 0x0001,     /* R1290  - Audio IF 1_11 */
-       [0x050B] = 0x0002,     /* R1291  - Audio IF 1_12 */
-       [0x050C] = 0x0003,     /* R1292  - Audio IF 1_13 */
-       [0x050D] = 0x0004,     /* R1293  - Audio IF 1_14 */
-       [0x050E] = 0x0005,     /* R1294  - Audio IF 1_15 */
-       [0x050F] = 0x0006,     /* R1295  - Audio IF 1_16 */
-       [0x0510] = 0x0007,     /* R1296  - Audio IF 1_17 */
-       [0x0511] = 0x0000,     /* R1297  - Audio IF 1_18 */
-       [0x0512] = 0x0001,     /* R1298  - Audio IF 1_19 */
-       [0x0513] = 0x0002,     /* R1299  - Audio IF 1_20 */
-       [0x0514] = 0x0003,     /* R1300  - Audio IF 1_21 */
-       [0x0515] = 0x0004,     /* R1301  - Audio IF 1_22 */
-       [0x0516] = 0x0005,     /* R1302  - Audio IF 1_23 */
-       [0x0517] = 0x0006,     /* R1303  - Audio IF 1_24 */
-       [0x0518] = 0x0007,     /* R1304  - Audio IF 1_25 */
-       [0x0519] = 0x0000,     /* R1305  - Audio IF 1_26 */
-       [0x051A] = 0x0000,     /* R1306  - Audio IF 1_27 */
-       [0x0540] = 0x000C,     /* R1344  - Audio IF 2_1 */
-       [0x0541] = 0x0008,     /* R1345  - Audio IF 2_2 */
-       [0x0542] = 0x0000,     /* R1346  - Audio IF 2_3 */
-       [0x0543] = 0x0000,     /* R1347  - Audio IF 2_4 */
-       [0x0544] = 0x0000,     /* R1348  - Audio IF 2_5 */
-       [0x0545] = 0x0300,     /* R1349  - Audio IF 2_6 */
-       [0x0546] = 0x0300,     /* R1350  - Audio IF 2_7 */
-       [0x0547] = 0x1820,     /* R1351  - Audio IF 2_8 */
-       [0x0548] = 0x1820,     /* R1352  - Audio IF 2_9 */
-       [0x0549] = 0x0000,     /* R1353  - Audio IF 2_10 */
-       [0x054A] = 0x0001,     /* R1354  - Audio IF 2_11 */
-       [0x0551] = 0x0000,     /* R1361  - Audio IF 2_18 */
-       [0x0552] = 0x0001,     /* R1362  - Audio IF 2_19 */
-       [0x0559] = 0x0000,     /* R1369  - Audio IF 2_26 */
-       [0x055A] = 0x0000,     /* R1370  - Audio IF 2_27 */
-       [0x0580] = 0x000C,     /* R1408  - Audio IF 3_1 */
-       [0x0581] = 0x0008,     /* R1409  - Audio IF 3_2 */
-       [0x0582] = 0x0000,     /* R1410  - Audio IF 3_3 */
-       [0x0583] = 0x0000,     /* R1411  - Audio IF 3_4 */
-       [0x0584] = 0x0000,     /* R1412  - Audio IF 3_5 */
-       [0x0585] = 0x0300,     /* R1413  - Audio IF 3_6 */
-       [0x0586] = 0x0300,     /* R1414  - Audio IF 3_7 */
-       [0x0587] = 0x1820,     /* R1415  - Audio IF 3_8 */
-       [0x0588] = 0x1820,     /* R1416  - Audio IF 3_9 */
-       [0x0589] = 0x0000,     /* R1417  - Audio IF 3_10 */
-       [0x058A] = 0x0001,     /* R1418  - Audio IF 3_11 */
-       [0x0591] = 0x0000,     /* R1425  - Audio IF 3_18 */
-       [0x0592] = 0x0001,     /* R1426  - Audio IF 3_19 */
-       [0x0599] = 0x0000,     /* R1433  - Audio IF 3_26 */
-       [0x059A] = 0x0000,     /* R1434  - Audio IF 3_27 */
-       [0x0640] = 0x0000,     /* R1600  - PWM1MIX Input 1 Source */
-       [0x0641] = 0x0080,     /* R1601  - PWM1MIX Input 1 Volume */
-       [0x0642] = 0x0000,     /* R1602  - PWM1MIX Input 2 Source */
-       [0x0643] = 0x0080,     /* R1603  - PWM1MIX Input 2 Volume */
-       [0x0644] = 0x0000,     /* R1604  - PWM1MIX Input 3 Source */
-       [0x0645] = 0x0080,     /* R1605  - PWM1MIX Input 3 Volume */
-       [0x0646] = 0x0000,     /* R1606  - PWM1MIX Input 4 Source */
-       [0x0647] = 0x0080,     /* R1607  - PWM1MIX Input 4 Volume */
-       [0x0648] = 0x0000,     /* R1608  - PWM2MIX Input 1 Source */
-       [0x0649] = 0x0080,     /* R1609  - PWM2MIX Input 1 Volume */
-       [0x064A] = 0x0000,     /* R1610  - PWM2MIX Input 2 Source */
-       [0x064B] = 0x0080,     /* R1611  - PWM2MIX Input 2 Volume */
-       [0x064C] = 0x0000,     /* R1612  - PWM2MIX Input 3 Source */
-       [0x064D] = 0x0080,     /* R1613  - PWM2MIX Input 3 Volume */
-       [0x064E] = 0x0000,     /* R1614  - PWM2MIX Input 4 Source */
-       [0x064F] = 0x0080,     /* R1615  - PWM2MIX Input 4 Volume */
-       [0x0680] = 0x0000,     /* R1664  - OUT1LMIX Input 1 Source */
-       [0x0681] = 0x0080,     /* R1665  - OUT1LMIX Input 1 Volume */
-       [0x0682] = 0x0000,     /* R1666  - OUT1LMIX Input 2 Source */
-       [0x0683] = 0x0080,     /* R1667  - OUT1LMIX Input 2 Volume */
-       [0x0684] = 0x0000,     /* R1668  - OUT1LMIX Input 3 Source */
-       [0x0685] = 0x0080,     /* R1669  - OUT1LMIX Input 3 Volume */
-       [0x0686] = 0x0000,     /* R1670  - OUT1LMIX Input 4 Source */
-       [0x0687] = 0x0080,     /* R1671  - OUT1LMIX Input 4 Volume */
-       [0x0688] = 0x0000,     /* R1672  - OUT1RMIX Input 1 Source */
-       [0x0689] = 0x0080,     /* R1673  - OUT1RMIX Input 1 Volume */
-       [0x068A] = 0x0000,     /* R1674  - OUT1RMIX Input 2 Source */
-       [0x068B] = 0x0080,     /* R1675  - OUT1RMIX Input 2 Volume */
-       [0x068C] = 0x0000,     /* R1676  - OUT1RMIX Input 3 Source */
-       [0x068D] = 0x0080,     /* R1677  - OUT1RMIX Input 3 Volume */
-       [0x068E] = 0x0000,     /* R1678  - OUT1RMIX Input 4 Source */
-       [0x068F] = 0x0080,     /* R1679  - OUT1RMIX Input 4 Volume */
-       [0x0690] = 0x0000,     /* R1680  - OUT2LMIX Input 1 Source */
-       [0x0691] = 0x0080,     /* R1681  - OUT2LMIX Input 1 Volume */
-       [0x0692] = 0x0000,     /* R1682  - OUT2LMIX Input 2 Source */
-       [0x0693] = 0x0080,     /* R1683  - OUT2LMIX Input 2 Volume */
-       [0x0694] = 0x0000,     /* R1684  - OUT2LMIX Input 3 Source */
-       [0x0695] = 0x0080,     /* R1685  - OUT2LMIX Input 3 Volume */
-       [0x0696] = 0x0000,     /* R1686  - OUT2LMIX Input 4 Source */
-       [0x0697] = 0x0080,     /* R1687  - OUT2LMIX Input 4 Volume */
-       [0x0698] = 0x0000,     /* R1688  - OUT2RMIX Input 1 Source */
-       [0x0699] = 0x0080,     /* R1689  - OUT2RMIX Input 1 Volume */
-       [0x069A] = 0x0000,     /* R1690  - OUT2RMIX Input 2 Source */
-       [0x069B] = 0x0080,     /* R1691  - OUT2RMIX Input 2 Volume */
-       [0x069C] = 0x0000,     /* R1692  - OUT2RMIX Input 3 Source */
-       [0x069D] = 0x0080,     /* R1693  - OUT2RMIX Input 3 Volume */
-       [0x069E] = 0x0000,     /* R1694  - OUT2RMIX Input 4 Source */
-       [0x069F] = 0x0080,     /* R1695  - OUT2RMIX Input 4 Volume */
-       [0x06A0] = 0x0000,     /* R1696  - OUT3LMIX Input 1 Source */
-       [0x06A1] = 0x0080,     /* R1697  - OUT3LMIX Input 1 Volume */
-       [0x06A2] = 0x0000,     /* R1698  - OUT3LMIX Input 2 Source */
-       [0x06A3] = 0x0080,     /* R1699  - OUT3LMIX Input 2 Volume */
-       [0x06A4] = 0x0000,     /* R1700  - OUT3LMIX Input 3 Source */
-       [0x06A5] = 0x0080,     /* R1701  - OUT3LMIX Input 3 Volume */
-       [0x06A6] = 0x0000,     /* R1702  - OUT3LMIX Input 4 Source */
-       [0x06A7] = 0x0080,     /* R1703  - OUT3LMIX Input 4 Volume */
-       [0x06A8] = 0x0000,     /* R1704  - OUT3RMIX Input 1 Source */
-       [0x06A9] = 0x0080,     /* R1705  - OUT3RMIX Input 1 Volume */
-       [0x06AA] = 0x0000,     /* R1706  - OUT3RMIX Input 2 Source */
-       [0x06AB] = 0x0080,     /* R1707  - OUT3RMIX Input 2 Volume */
-       [0x06AC] = 0x0000,     /* R1708  - OUT3RMIX Input 3 Source */
-       [0x06AD] = 0x0080,     /* R1709  - OUT3RMIX Input 3 Volume */
-       [0x06AE] = 0x0000,     /* R1710  - OUT3RMIX Input 4 Source */
-       [0x06AF] = 0x0080,     /* R1711  - OUT3RMIX Input 4 Volume */
-       [0x06B0] = 0x0000,     /* R1712  - OUT4LMIX Input 1 Source */
-       [0x06B1] = 0x0080,     /* R1713  - OUT4LMIX Input 1 Volume */
-       [0x06B2] = 0x0000,     /* R1714  - OUT4LMIX Input 2 Source */
-       [0x06B3] = 0x0080,     /* R1715  - OUT4LMIX Input 2 Volume */
-       [0x06B4] = 0x0000,     /* R1716  - OUT4LMIX Input 3 Source */
-       [0x06B5] = 0x0080,     /* R1717  - OUT4LMIX Input 3 Volume */
-       [0x06B6] = 0x0000,     /* R1718  - OUT4LMIX Input 4 Source */
-       [0x06B7] = 0x0080,     /* R1719  - OUT4LMIX Input 4 Volume */
-       [0x06B8] = 0x0000,     /* R1720  - OUT4RMIX Input 1 Source */
-       [0x06B9] = 0x0080,     /* R1721  - OUT4RMIX Input 1 Volume */
-       [0x06BA] = 0x0000,     /* R1722  - OUT4RMIX Input 2 Source */
-       [0x06BB] = 0x0080,     /* R1723  - OUT4RMIX Input 2 Volume */
-       [0x06BC] = 0x0000,     /* R1724  - OUT4RMIX Input 3 Source */
-       [0x06BD] = 0x0080,     /* R1725  - OUT4RMIX Input 3 Volume */
-       [0x06BE] = 0x0000,     /* R1726  - OUT4RMIX Input 4 Source */
-       [0x06BF] = 0x0080,     /* R1727  - OUT4RMIX Input 4 Volume */
-       [0x06C0] = 0x0000,     /* R1728  - OUT5LMIX Input 1 Source */
-       [0x06C1] = 0x0080,     /* R1729  - OUT5LMIX Input 1 Volume */
-       [0x06C2] = 0x0000,     /* R1730  - OUT5LMIX Input 2 Source */
-       [0x06C3] = 0x0080,     /* R1731  - OUT5LMIX Input 2 Volume */
-       [0x06C4] = 0x0000,     /* R1732  - OUT5LMIX Input 3 Source */
-       [0x06C5] = 0x0080,     /* R1733  - OUT5LMIX Input 3 Volume */
-       [0x06C6] = 0x0000,     /* R1734  - OUT5LMIX Input 4 Source */
-       [0x06C7] = 0x0080,     /* R1735  - OUT5LMIX Input 4 Volume */
-       [0x06C8] = 0x0000,     /* R1736  - OUT5RMIX Input 1 Source */
-       [0x06C9] = 0x0080,     /* R1737  - OUT5RMIX Input 1 Volume */
-       [0x06CA] = 0x0000,     /* R1738  - OUT5RMIX Input 2 Source */
-       [0x06CB] = 0x0080,     /* R1739  - OUT5RMIX Input 2 Volume */
-       [0x06CC] = 0x0000,     /* R1740  - OUT5RMIX Input 3 Source */
-       [0x06CD] = 0x0080,     /* R1741  - OUT5RMIX Input 3 Volume */
-       [0x06CE] = 0x0000,     /* R1742  - OUT5RMIX Input 4 Source */
-       [0x06CF] = 0x0080,     /* R1743  - OUT5RMIX Input 4 Volume */
-       [0x06D0] = 0x0000,     /* R1744  - OUT6LMIX Input 1 Source */
-       [0x06D1] = 0x0080,     /* R1745  - OUT6LMIX Input 1 Volume */
-       [0x06D2] = 0x0000,     /* R1746  - OUT6LMIX Input 2 Source */
-       [0x06D3] = 0x0080,     /* R1747  - OUT6LMIX Input 2 Volume */
-       [0x06D4] = 0x0000,     /* R1748  - OUT6LMIX Input 3 Source */
-       [0x06D5] = 0x0080,     /* R1749  - OUT6LMIX Input 3 Volume */
-       [0x06D6] = 0x0000,     /* R1750  - OUT6LMIX Input 4 Source */
-       [0x06D7] = 0x0080,     /* R1751  - OUT6LMIX Input 4 Volume */
-       [0x06D8] = 0x0000,     /* R1752  - OUT6RMIX Input 1 Source */
-       [0x06D9] = 0x0080,     /* R1753  - OUT6RMIX Input 1 Volume */
-       [0x06DA] = 0x0000,     /* R1754  - OUT6RMIX Input 2 Source */
-       [0x06DB] = 0x0080,     /* R1755  - OUT6RMIX Input 2 Volume */
-       [0x06DC] = 0x0000,     /* R1756  - OUT6RMIX Input 3 Source */
-       [0x06DD] = 0x0080,     /* R1757  - OUT6RMIX Input 3 Volume */
-       [0x06DE] = 0x0000,     /* R1758  - OUT6RMIX Input 4 Source */
-       [0x06DF] = 0x0080,     /* R1759  - OUT6RMIX Input 4 Volume */
-       [0x0700] = 0x0000,     /* R1792  - AIF1TX1MIX Input 1 Source */
-       [0x0701] = 0x0080,     /* R1793  - AIF1TX1MIX Input 1 Volume */
-       [0x0702] = 0x0000,     /* R1794  - AIF1TX1MIX Input 2 Source */
-       [0x0703] = 0x0080,     /* R1795  - AIF1TX1MIX Input 2 Volume */
-       [0x0704] = 0x0000,     /* R1796  - AIF1TX1MIX Input 3 Source */
-       [0x0705] = 0x0080,     /* R1797  - AIF1TX1MIX Input 3 Volume */
-       [0x0706] = 0x0000,     /* R1798  - AIF1TX1MIX Input 4 Source */
-       [0x0707] = 0x0080,     /* R1799  - AIF1TX1MIX Input 4 Volume */
-       [0x0708] = 0x0000,     /* R1800  - AIF1TX2MIX Input 1 Source */
-       [0x0709] = 0x0080,     /* R1801  - AIF1TX2MIX Input 1 Volume */
-       [0x070A] = 0x0000,     /* R1802  - AIF1TX2MIX Input 2 Source */
-       [0x070B] = 0x0080,     /* R1803  - AIF1TX2MIX Input 2 Volume */
-       [0x070C] = 0x0000,     /* R1804  - AIF1TX2MIX Input 3 Source */
-       [0x070D] = 0x0080,     /* R1805  - AIF1TX2MIX Input 3 Volume */
-       [0x070E] = 0x0000,     /* R1806  - AIF1TX2MIX Input 4 Source */
-       [0x070F] = 0x0080,     /* R1807  - AIF1TX2MIX Input 4 Volume */
-       [0x0710] = 0x0000,     /* R1808  - AIF1TX3MIX Input 1 Source */
-       [0x0711] = 0x0080,     /* R1809  - AIF1TX3MIX Input 1 Volume */
-       [0x0712] = 0x0000,     /* R1810  - AIF1TX3MIX Input 2 Source */
-       [0x0713] = 0x0080,     /* R1811  - AIF1TX3MIX Input 2 Volume */
-       [0x0714] = 0x0000,     /* R1812  - AIF1TX3MIX Input 3 Source */
-       [0x0715] = 0x0080,     /* R1813  - AIF1TX3MIX Input 3 Volume */
-       [0x0716] = 0x0000,     /* R1814  - AIF1TX3MIX Input 4 Source */
-       [0x0717] = 0x0080,     /* R1815  - AIF1TX3MIX Input 4 Volume */
-       [0x0718] = 0x0000,     /* R1816  - AIF1TX4MIX Input 1 Source */
-       [0x0719] = 0x0080,     /* R1817  - AIF1TX4MIX Input 1 Volume */
-       [0x071A] = 0x0000,     /* R1818  - AIF1TX4MIX Input 2 Source */
-       [0x071B] = 0x0080,     /* R1819  - AIF1TX4MIX Input 2 Volume */
-       [0x071C] = 0x0000,     /* R1820  - AIF1TX4MIX Input 3 Source */
-       [0x071D] = 0x0080,     /* R1821  - AIF1TX4MIX Input 3 Volume */
-       [0x071E] = 0x0000,     /* R1822  - AIF1TX4MIX Input 4 Source */
-       [0x071F] = 0x0080,     /* R1823  - AIF1TX4MIX Input 4 Volume */
-       [0x0720] = 0x0000,     /* R1824  - AIF1TX5MIX Input 1 Source */
-       [0x0721] = 0x0080,     /* R1825  - AIF1TX5MIX Input 1 Volume */
-       [0x0722] = 0x0000,     /* R1826  - AIF1TX5MIX Input 2 Source */
-       [0x0723] = 0x0080,     /* R1827  - AIF1TX5MIX Input 2 Volume */
-       [0x0724] = 0x0000,     /* R1828  - AIF1TX5MIX Input 3 Source */
-       [0x0725] = 0x0080,     /* R1829  - AIF1TX5MIX Input 3 Volume */
-       [0x0726] = 0x0000,     /* R1830  - AIF1TX5MIX Input 4 Source */
-       [0x0727] = 0x0080,     /* R1831  - AIF1TX5MIX Input 4 Volume */
-       [0x0728] = 0x0000,     /* R1832  - AIF1TX6MIX Input 1 Source */
-       [0x0729] = 0x0080,     /* R1833  - AIF1TX6MIX Input 1 Volume */
-       [0x072A] = 0x0000,     /* R1834  - AIF1TX6MIX Input 2 Source */
-       [0x072B] = 0x0080,     /* R1835  - AIF1TX6MIX Input 2 Volume */
-       [0x072C] = 0x0000,     /* R1836  - AIF1TX6MIX Input 3 Source */
-       [0x072D] = 0x0080,     /* R1837  - AIF1TX6MIX Input 3 Volume */
-       [0x072E] = 0x0000,     /* R1838  - AIF1TX6MIX Input 4 Source */
-       [0x072F] = 0x0080,     /* R1839  - AIF1TX6MIX Input 4 Volume */
-       [0x0730] = 0x0000,     /* R1840  - AIF1TX7MIX Input 1 Source */
-       [0x0731] = 0x0080,     /* R1841  - AIF1TX7MIX Input 1 Volume */
-       [0x0732] = 0x0000,     /* R1842  - AIF1TX7MIX Input 2 Source */
-       [0x0733] = 0x0080,     /* R1843  - AIF1TX7MIX Input 2 Volume */
-       [0x0734] = 0x0000,     /* R1844  - AIF1TX7MIX Input 3 Source */
-       [0x0735] = 0x0080,     /* R1845  - AIF1TX7MIX Input 3 Volume */
-       [0x0736] = 0x0000,     /* R1846  - AIF1TX7MIX Input 4 Source */
-       [0x0737] = 0x0080,     /* R1847  - AIF1TX7MIX Input 4 Volume */
-       [0x0738] = 0x0000,     /* R1848  - AIF1TX8MIX Input 1 Source */
-       [0x0739] = 0x0080,     /* R1849  - AIF1TX8MIX Input 1 Volume */
-       [0x073A] = 0x0000,     /* R1850  - AIF1TX8MIX Input 2 Source */
-       [0x073B] = 0x0080,     /* R1851  - AIF1TX8MIX Input 2 Volume */
-       [0x073C] = 0x0000,     /* R1852  - AIF1TX8MIX Input 3 Source */
-       [0x073D] = 0x0080,     /* R1853  - AIF1TX8MIX Input 3 Volume */
-       [0x073E] = 0x0000,     /* R1854  - AIF1TX8MIX Input 4 Source */
-       [0x073F] = 0x0080,     /* R1855  - AIF1TX8MIX Input 4 Volume */
-       [0x0740] = 0x0000,     /* R1856  - AIF2TX1MIX Input 1 Source */
-       [0x0741] = 0x0080,     /* R1857  - AIF2TX1MIX Input 1 Volume */
-       [0x0742] = 0x0000,     /* R1858  - AIF2TX1MIX Input 2 Source */
-       [0x0743] = 0x0080,     /* R1859  - AIF2TX1MIX Input 2 Volume */
-       [0x0744] = 0x0000,     /* R1860  - AIF2TX1MIX Input 3 Source */
-       [0x0745] = 0x0080,     /* R1861  - AIF2TX1MIX Input 3 Volume */
-       [0x0746] = 0x0000,     /* R1862  - AIF2TX1MIX Input 4 Source */
-       [0x0747] = 0x0080,     /* R1863  - AIF2TX1MIX Input 4 Volume */
-       [0x0748] = 0x0000,     /* R1864  - AIF2TX2MIX Input 1 Source */
-       [0x0749] = 0x0080,     /* R1865  - AIF2TX2MIX Input 1 Volume */
-       [0x074A] = 0x0000,     /* R1866  - AIF2TX2MIX Input 2 Source */
-       [0x074B] = 0x0080,     /* R1867  - AIF2TX2MIX Input 2 Volume */
-       [0x074C] = 0x0000,     /* R1868  - AIF2TX2MIX Input 3 Source */
-       [0x074D] = 0x0080,     /* R1869  - AIF2TX2MIX Input 3 Volume */
-       [0x074E] = 0x0000,     /* R1870  - AIF2TX2MIX Input 4 Source */
-       [0x074F] = 0x0080,     /* R1871  - AIF2TX2MIX Input 4 Volume */
-       [0x0780] = 0x0000,     /* R1920  - AIF3TX1MIX Input 1 Source */
-       [0x0781] = 0x0080,     /* R1921  - AIF3TX1MIX Input 1 Volume */
-       [0x0782] = 0x0000,     /* R1922  - AIF3TX1MIX Input 2 Source */
-       [0x0783] = 0x0080,     /* R1923  - AIF3TX1MIX Input 2 Volume */
-       [0x0784] = 0x0000,     /* R1924  - AIF3TX1MIX Input 3 Source */
-       [0x0785] = 0x0080,     /* R1925  - AIF3TX1MIX Input 3 Volume */
-       [0x0786] = 0x0000,     /* R1926  - AIF3TX1MIX Input 4 Source */
-       [0x0787] = 0x0080,     /* R1927  - AIF3TX1MIX Input 4 Volume */
-       [0x0788] = 0x0000,     /* R1928  - AIF3TX2MIX Input 1 Source */
-       [0x0789] = 0x0080,     /* R1929  - AIF3TX2MIX Input 1 Volume */
-       [0x078A] = 0x0000,     /* R1930  - AIF3TX2MIX Input 2 Source */
-       [0x078B] = 0x0080,     /* R1931  - AIF3TX2MIX Input 2 Volume */
-       [0x078C] = 0x0000,     /* R1932  - AIF3TX2MIX Input 3 Source */
-       [0x078D] = 0x0080,     /* R1933  - AIF3TX2MIX Input 3 Volume */
-       [0x078E] = 0x0000,     /* R1934  - AIF3TX2MIX Input 4 Source */
-       [0x078F] = 0x0080,     /* R1935  - AIF3TX2MIX Input 4 Volume */
-       [0x0880] = 0x0000,     /* R2176  - EQ1MIX Input 1 Source */
-       [0x0881] = 0x0080,     /* R2177  - EQ1MIX Input 1 Volume */
-       [0x0882] = 0x0000,     /* R2178  - EQ1MIX Input 2 Source */
-       [0x0883] = 0x0080,     /* R2179  - EQ1MIX Input 2 Volume */
-       [0x0884] = 0x0000,     /* R2180  - EQ1MIX Input 3 Source */
-       [0x0885] = 0x0080,     /* R2181  - EQ1MIX Input 3 Volume */
-       [0x0886] = 0x0000,     /* R2182  - EQ1MIX Input 4 Source */
-       [0x0887] = 0x0080,     /* R2183  - EQ1MIX Input 4 Volume */
-       [0x0888] = 0x0000,     /* R2184  - EQ2MIX Input 1 Source */
-       [0x0889] = 0x0080,     /* R2185  - EQ2MIX Input 1 Volume */
-       [0x088A] = 0x0000,     /* R2186  - EQ2MIX Input 2 Source */
-       [0x088B] = 0x0080,     /* R2187  - EQ2MIX Input 2 Volume */
-       [0x088C] = 0x0000,     /* R2188  - EQ2MIX Input 3 Source */
-       [0x088D] = 0x0080,     /* R2189  - EQ2MIX Input 3 Volume */
-       [0x088E] = 0x0000,     /* R2190  - EQ2MIX Input 4 Source */
-       [0x088F] = 0x0080,     /* R2191  - EQ2MIX Input 4 Volume */
-       [0x0890] = 0x0000,     /* R2192  - EQ3MIX Input 1 Source */
-       [0x0891] = 0x0080,     /* R2193  - EQ3MIX Input 1 Volume */
-       [0x0892] = 0x0000,     /* R2194  - EQ3MIX Input 2 Source */
-       [0x0893] = 0x0080,     /* R2195  - EQ3MIX Input 2 Volume */
-       [0x0894] = 0x0000,     /* R2196  - EQ3MIX Input 3 Source */
-       [0x0895] = 0x0080,     /* R2197  - EQ3MIX Input 3 Volume */
-       [0x0896] = 0x0000,     /* R2198  - EQ3MIX Input 4 Source */
-       [0x0897] = 0x0080,     /* R2199  - EQ3MIX Input 4 Volume */
-       [0x0898] = 0x0000,     /* R2200  - EQ4MIX Input 1 Source */
-       [0x0899] = 0x0080,     /* R2201  - EQ4MIX Input 1 Volume */
-       [0x089A] = 0x0000,     /* R2202  - EQ4MIX Input 2 Source */
-       [0x089B] = 0x0080,     /* R2203  - EQ4MIX Input 2 Volume */
-       [0x089C] = 0x0000,     /* R2204  - EQ4MIX Input 3 Source */
-       [0x089D] = 0x0080,     /* R2205  - EQ4MIX Input 3 Volume */
-       [0x089E] = 0x0000,     /* R2206  - EQ4MIX Input 4 Source */
-       [0x089F] = 0x0080,     /* R2207  - EQ4MIX Input 4 Volume */
-       [0x08C0] = 0x0000,     /* R2240  - DRC1LMIX Input 1 Source */
-       [0x08C1] = 0x0080,     /* R2241  - DRC1LMIX Input 1 Volume */
-       [0x08C2] = 0x0000,     /* R2242  - DRC1LMIX Input 2 Source */
-       [0x08C3] = 0x0080,     /* R2243  - DRC1LMIX Input 2 Volume */
-       [0x08C4] = 0x0000,     /* R2244  - DRC1LMIX Input 3 Source */
-       [0x08C5] = 0x0080,     /* R2245  - DRC1LMIX Input 3 Volume */
-       [0x08C6] = 0x0000,     /* R2246  - DRC1LMIX Input 4 Source */
-       [0x08C7] = 0x0080,     /* R2247  - DRC1LMIX Input 4 Volume */
-       [0x08C8] = 0x0000,     /* R2248  - DRC1RMIX Input 1 Source */
-       [0x08C9] = 0x0080,     /* R2249  - DRC1RMIX Input 1 Volume */
-       [0x08CA] = 0x0000,     /* R2250  - DRC1RMIX Input 2 Source */
-       [0x08CB] = 0x0080,     /* R2251  - DRC1RMIX Input 2 Volume */
-       [0x08CC] = 0x0000,     /* R2252  - DRC1RMIX Input 3 Source */
-       [0x08CD] = 0x0080,     /* R2253  - DRC1RMIX Input 3 Volume */
-       [0x08CE] = 0x0000,     /* R2254  - DRC1RMIX Input 4 Source */
-       [0x08CF] = 0x0080,     /* R2255  - DRC1RMIX Input 4 Volume */
-       [0x0900] = 0x0000,     /* R2304  - HPLP1MIX Input 1 Source */
-       [0x0901] = 0x0080,     /* R2305  - HPLP1MIX Input 1 Volume */
-       [0x0902] = 0x0000,     /* R2306  - HPLP1MIX Input 2 Source */
-       [0x0903] = 0x0080,     /* R2307  - HPLP1MIX Input 2 Volume */
-       [0x0904] = 0x0000,     /* R2308  - HPLP1MIX Input 3 Source */
-       [0x0905] = 0x0080,     /* R2309  - HPLP1MIX Input 3 Volume */
-       [0x0906] = 0x0000,     /* R2310  - HPLP1MIX Input 4 Source */
-       [0x0907] = 0x0080,     /* R2311  - HPLP1MIX Input 4 Volume */
-       [0x0908] = 0x0000,     /* R2312  - HPLP2MIX Input 1 Source */
-       [0x0909] = 0x0080,     /* R2313  - HPLP2MIX Input 1 Volume */
-       [0x090A] = 0x0000,     /* R2314  - HPLP2MIX Input 2 Source */
-       [0x090B] = 0x0080,     /* R2315  - HPLP2MIX Input 2 Volume */
-       [0x090C] = 0x0000,     /* R2316  - HPLP2MIX Input 3 Source */
-       [0x090D] = 0x0080,     /* R2317  - HPLP2MIX Input 3 Volume */
-       [0x090E] = 0x0000,     /* R2318  - HPLP2MIX Input 4 Source */
-       [0x090F] = 0x0080,     /* R2319  - HPLP2MIX Input 4 Volume */
-       [0x0910] = 0x0000,     /* R2320  - HPLP3MIX Input 1 Source */
-       [0x0911] = 0x0080,     /* R2321  - HPLP3MIX Input 1 Volume */
-       [0x0912] = 0x0000,     /* R2322  - HPLP3MIX Input 2 Source */
-       [0x0913] = 0x0080,     /* R2323  - HPLP3MIX Input 2 Volume */
-       [0x0914] = 0x0000,     /* R2324  - HPLP3MIX Input 3 Source */
-       [0x0915] = 0x0080,     /* R2325  - HPLP3MIX Input 3 Volume */
-       [0x0916] = 0x0000,     /* R2326  - HPLP3MIX Input 4 Source */
-       [0x0917] = 0x0080,     /* R2327  - HPLP3MIX Input 4 Volume */
-       [0x0918] = 0x0000,     /* R2328  - HPLP4MIX Input 1 Source */
-       [0x0919] = 0x0080,     /* R2329  - HPLP4MIX Input 1 Volume */
-       [0x091A] = 0x0000,     /* R2330  - HPLP4MIX Input 2 Source */
-       [0x091B] = 0x0080,     /* R2331  - HPLP4MIX Input 2 Volume */
-       [0x091C] = 0x0000,     /* R2332  - HPLP4MIX Input 3 Source */
-       [0x091D] = 0x0080,     /* R2333  - HPLP4MIX Input 3 Volume */
-       [0x091E] = 0x0000,     /* R2334  - HPLP4MIX Input 4 Source */
-       [0x091F] = 0x0080,     /* R2335  - HPLP4MIX Input 4 Volume */
-       [0x0940] = 0x0000,     /* R2368  - DSP1LMIX Input 1 Source */
-       [0x0941] = 0x0080,     /* R2369  - DSP1LMIX Input 1 Volume */
-       [0x0942] = 0x0000,     /* R2370  - DSP1LMIX Input 2 Source */
-       [0x0943] = 0x0080,     /* R2371  - DSP1LMIX Input 2 Volume */
-       [0x0944] = 0x0000,     /* R2372  - DSP1LMIX Input 3 Source */
-       [0x0945] = 0x0080,     /* R2373  - DSP1LMIX Input 3 Volume */
-       [0x0946] = 0x0000,     /* R2374  - DSP1LMIX Input 4 Source */
-       [0x0947] = 0x0080,     /* R2375  - DSP1LMIX Input 4 Volume */
-       [0x0948] = 0x0000,     /* R2376  - DSP1RMIX Input 1 Source */
-       [0x0949] = 0x0080,     /* R2377  - DSP1RMIX Input 1 Volume */
-       [0x094A] = 0x0000,     /* R2378  - DSP1RMIX Input 2 Source */
-       [0x094B] = 0x0080,     /* R2379  - DSP1RMIX Input 2 Volume */
-       [0x094C] = 0x0000,     /* R2380  - DSP1RMIX Input 3 Source */
-       [0x094D] = 0x0080,     /* R2381  - DSP1RMIX Input 3 Volume */
-       [0x094E] = 0x0000,     /* R2382  - DSP1RMIX Input 4 Source */
-       [0x094F] = 0x0080,     /* R2383  - DSP1RMIX Input 4 Volume */
-       [0x0950] = 0x0000,     /* R2384  - DSP1AUX1MIX Input 1 Source */
-       [0x0958] = 0x0000,     /* R2392  - DSP1AUX2MIX Input 1 Source */
-       [0x0960] = 0x0000,     /* R2400  - DSP1AUX3MIX Input 1 Source */
-       [0x0968] = 0x0000,     /* R2408  - DSP1AUX4MIX Input 1 Source */
-       [0x0970] = 0x0000,     /* R2416  - DSP1AUX5MIX Input 1 Source */
-       [0x0978] = 0x0000,     /* R2424  - DSP1AUX6MIX Input 1 Source */
-       [0x0980] = 0x0000,     /* R2432  - DSP2LMIX Input 1 Source */
-       [0x0981] = 0x0080,     /* R2433  - DSP2LMIX Input 1 Volume */
-       [0x0982] = 0x0000,     /* R2434  - DSP2LMIX Input 2 Source */
-       [0x0983] = 0x0080,     /* R2435  - DSP2LMIX Input 2 Volume */
-       [0x0984] = 0x0000,     /* R2436  - DSP2LMIX Input 3 Source */
-       [0x0985] = 0x0080,     /* R2437  - DSP2LMIX Input 3 Volume */
-       [0x0986] = 0x0000,     /* R2438  - DSP2LMIX Input 4 Source */
-       [0x0987] = 0x0080,     /* R2439  - DSP2LMIX Input 4 Volume */
-       [0x0988] = 0x0000,     /* R2440  - DSP2RMIX Input 1 Source */
-       [0x0989] = 0x0080,     /* R2441  - DSP2RMIX Input 1 Volume */
-       [0x098A] = 0x0000,     /* R2442  - DSP2RMIX Input 2 Source */
-       [0x098B] = 0x0080,     /* R2443  - DSP2RMIX Input 2 Volume */
-       [0x098C] = 0x0000,     /* R2444  - DSP2RMIX Input 3 Source */
-       [0x098D] = 0x0080,     /* R2445  - DSP2RMIX Input 3 Volume */
-       [0x098E] = 0x0000,     /* R2446  - DSP2RMIX Input 4 Source */
-       [0x098F] = 0x0080,     /* R2447  - DSP2RMIX Input 4 Volume */
-       [0x0990] = 0x0000,     /* R2448  - DSP2AUX1MIX Input 1 Source */
-       [0x0998] = 0x0000,     /* R2456  - DSP2AUX2MIX Input 1 Source */
-       [0x09A0] = 0x0000,     /* R2464  - DSP2AUX3MIX Input 1 Source */
-       [0x09A8] = 0x0000,     /* R2472  - DSP2AUX4MIX Input 1 Source */
-       [0x09B0] = 0x0000,     /* R2480  - DSP2AUX5MIX Input 1 Source */
-       [0x09B8] = 0x0000,     /* R2488  - DSP2AUX6MIX Input 1 Source */
-       [0x09C0] = 0x0000,     /* R2496  - DSP3LMIX Input 1 Source */
-       [0x09C1] = 0x0080,     /* R2497  - DSP3LMIX Input 1 Volume */
-       [0x09C2] = 0x0000,     /* R2498  - DSP3LMIX Input 2 Source */
-       [0x09C3] = 0x0080,     /* R2499  - DSP3LMIX Input 2 Volume */
-       [0x09C4] = 0x0000,     /* R2500  - DSP3LMIX Input 3 Source */
-       [0x09C5] = 0x0080,     /* R2501  - DSP3LMIX Input 3 Volume */
-       [0x09C6] = 0x0000,     /* R2502  - DSP3LMIX Input 4 Source */
-       [0x09C7] = 0x0080,     /* R2503  - DSP3LMIX Input 4 Volume */
-       [0x09C8] = 0x0000,     /* R2504  - DSP3RMIX Input 1 Source */
-       [0x09C9] = 0x0080,     /* R2505  - DSP3RMIX Input 1 Volume */
-       [0x09CA] = 0x0000,     /* R2506  - DSP3RMIX Input 2 Source */
-       [0x09CB] = 0x0080,     /* R2507  - DSP3RMIX Input 2 Volume */
-       [0x09CC] = 0x0000,     /* R2508  - DSP3RMIX Input 3 Source */
-       [0x09CD] = 0x0080,     /* R2509  - DSP3RMIX Input 3 Volume */
-       [0x09CE] = 0x0000,     /* R2510  - DSP3RMIX Input 4 Source */
-       [0x09CF] = 0x0080,     /* R2511  - DSP3RMIX Input 4 Volume */
-       [0x09D0] = 0x0000,     /* R2512  - DSP3AUX1MIX Input 1 Source */
-       [0x09D8] = 0x0000,     /* R2520  - DSP3AUX2MIX Input 1 Source */
-       [0x09E0] = 0x0000,     /* R2528  - DSP3AUX3MIX Input 1 Source */
-       [0x09E8] = 0x0000,     /* R2536  - DSP3AUX4MIX Input 1 Source */
-       [0x09F0] = 0x0000,     /* R2544  - DSP3AUX5MIX Input 1 Source */
-       [0x09F8] = 0x0000,     /* R2552  - DSP3AUX6MIX Input 1 Source */
-       [0x0A80] = 0x0000,     /* R2688  - ASRC1LMIX Input 1 Source */
-       [0x0A88] = 0x0000,     /* R2696  - ASRC1RMIX Input 1 Source */
-       [0x0A90] = 0x0000,     /* R2704  - ASRC2LMIX Input 1 Source */
-       [0x0A98] = 0x0000,     /* R2712  - ASRC2RMIX Input 1 Source */
-       [0x0B00] = 0x0000,     /* R2816  - ISRC1DEC1MIX Input 1 Source */
-       [0x0B08] = 0x0000,     /* R2824  - ISRC1DEC2MIX Input 1 Source */
-       [0x0B10] = 0x0000,     /* R2832  - ISRC1DEC3MIX Input 1 Source */
-       [0x0B18] = 0x0000,     /* R2840  - ISRC1DEC4MIX Input 1 Source */
-       [0x0B20] = 0x0000,     /* R2848  - ISRC1INT1MIX Input 1 Source */
-       [0x0B28] = 0x0000,     /* R2856  - ISRC1INT2MIX Input 1 Source */
-       [0x0B30] = 0x0000,     /* R2864  - ISRC1INT3MIX Input 1 Source */
-       [0x0B38] = 0x0000,     /* R2872  - ISRC1INT4MIX Input 1 Source */
-       [0x0B40] = 0x0000,     /* R2880  - ISRC2DEC1MIX Input 1 Source */
-       [0x0B48] = 0x0000,     /* R2888  - ISRC2DEC2MIX Input 1 Source */
-       [0x0B50] = 0x0000,     /* R2896  - ISRC2DEC3MIX Input 1 Source */
-       [0x0B58] = 0x0000,     /* R2904  - ISRC2DEC4MIX Input 1 Source */
-       [0x0B60] = 0x0000,     /* R2912  - ISRC2INT1MIX Input 1 Source */
-       [0x0B68] = 0x0000,     /* R2920  - ISRC2INT2MIX Input 1 Source */
-       [0x0B70] = 0x0000,     /* R2928  - ISRC2INT3MIX Input 1 Source */
-       [0x0B78] = 0x0000,     /* R2936  - ISRC2INT4MIX Input 1 Source */
-       [0x0C00] = 0xA001,     /* R3072  - GPIO CTRL 1 */
-       [0x0C01] = 0xA001,     /* R3073  - GPIO CTRL 2 */
-       [0x0C02] = 0xA001,     /* R3074  - GPIO CTRL 3 */
-       [0x0C03] = 0xA001,     /* R3075  - GPIO CTRL 4 */
-       [0x0C04] = 0xA001,     /* R3076  - GPIO CTRL 5 */
-       [0x0C05] = 0xA001,     /* R3077  - GPIO CTRL 6 */
-       [0x0C23] = 0x4003,     /* R3107  - Misc Pad Ctrl 1 */
-       [0x0C24] = 0x0000,     /* R3108  - Misc Pad Ctrl 2 */
-       [0x0C25] = 0x0000,     /* R3109  - Misc Pad Ctrl 3 */
-       [0x0C26] = 0x0000,     /* R3110  - Misc Pad Ctrl 4 */
-       [0x0C27] = 0x0000,     /* R3111  - Misc Pad Ctrl 5 */
-       [0x0C28] = 0x0000,     /* R3112  - Misc GPIO 1 */
-       [0x0D00] = 0x0000,     /* R3328  - Interrupt Status 1 */
-       [0x0D01] = 0x0000,     /* R3329  - Interrupt Status 2 */
-       [0x0D02] = 0x0000,     /* R3330  - Interrupt Status 3 */
-       [0x0D03] = 0x0000,     /* R3331  - Interrupt Status 4 */
-       [0x0D04] = 0x0000,     /* R3332  - Interrupt Raw Status 2 */
-       [0x0D05] = 0x0000,     /* R3333  - Interrupt Raw Status 3 */
-       [0x0D06] = 0x0000,     /* R3334  - Interrupt Raw Status 4 */
-       [0x0D07] = 0xFFFF,     /* R3335  - Interrupt Status 1 Mask */
-       [0x0D08] = 0xFFFF,     /* R3336  - Interrupt Status 2 Mask */
-       [0x0D09] = 0xFFFF,     /* R3337  - Interrupt Status 3 Mask */
-       [0x0D0A] = 0xFFFF,     /* R3338  - Interrupt Status 4 Mask */
-       [0x0D1F] = 0x0000,     /* R3359  - Interrupt Control */
-       [0x0D20] = 0xFFFF,     /* R3360  - IRQ Debounce 1 */
-       [0x0D21] = 0xFFFF,     /* R3361  - IRQ Debounce 2 */
-       [0x0E00] = 0x0000,     /* R3584  - FX_Ctrl */
-       [0x0E10] = 0x6318,     /* R3600  - EQ1_1 */
-       [0x0E11] = 0x6300,     /* R3601  - EQ1_2 */
-       [0x0E12] = 0x0FC8,     /* R3602  - EQ1_3 */
-       [0x0E13] = 0x03FE,     /* R3603  - EQ1_4 */
-       [0x0E14] = 0x00E0,     /* R3604  - EQ1_5 */
-       [0x0E15] = 0x1EC4,     /* R3605  - EQ1_6 */
-       [0x0E16] = 0xF136,     /* R3606  - EQ1_7 */
-       [0x0E17] = 0x0409,     /* R3607  - EQ1_8 */
-       [0x0E18] = 0x04CC,     /* R3608  - EQ1_9 */
-       [0x0E19] = 0x1C9B,     /* R3609  - EQ1_10 */
-       [0x0E1A] = 0xF337,     /* R3610  - EQ1_11 */
-       [0x0E1B] = 0x040B,     /* R3611  - EQ1_12 */
-       [0x0E1C] = 0x0CBB,     /* R3612  - EQ1_13 */
-       [0x0E1D] = 0x16F8,     /* R3613  - EQ1_14 */
-       [0x0E1E] = 0xF7D9,     /* R3614  - EQ1_15 */
-       [0x0E1F] = 0x040A,     /* R3615  - EQ1_16 */
-       [0x0E20] = 0x1F14,     /* R3616  - EQ1_17 */
-       [0x0E21] = 0x058C,     /* R3617  - EQ1_18 */
-       [0x0E22] = 0x0563,     /* R3618  - EQ1_19 */
-       [0x0E23] = 0x4000,     /* R3619  - EQ1_20 */
-       [0x0E26] = 0x6318,     /* R3622  - EQ2_1 */
-       [0x0E27] = 0x6300,     /* R3623  - EQ2_2 */
-       [0x0E28] = 0x0FC8,     /* R3624  - EQ2_3 */
-       [0x0E29] = 0x03FE,     /* R3625  - EQ2_4 */
-       [0x0E2A] = 0x00E0,     /* R3626  - EQ2_5 */
-       [0x0E2B] = 0x1EC4,     /* R3627  - EQ2_6 */
-       [0x0E2C] = 0xF136,     /* R3628  - EQ2_7 */
-       [0x0E2D] = 0x0409,     /* R3629  - EQ2_8 */
-       [0x0E2E] = 0x04CC,     /* R3630  - EQ2_9 */
-       [0x0E2F] = 0x1C9B,     /* R3631  - EQ2_10 */
-       [0x0E30] = 0xF337,     /* R3632  - EQ2_11 */
-       [0x0E31] = 0x040B,     /* R3633  - EQ2_12 */
-       [0x0E32] = 0x0CBB,     /* R3634  - EQ2_13 */
-       [0x0E33] = 0x16F8,     /* R3635  - EQ2_14 */
-       [0x0E34] = 0xF7D9,     /* R3636  - EQ2_15 */
-       [0x0E35] = 0x040A,     /* R3637  - EQ2_16 */
-       [0x0E36] = 0x1F14,     /* R3638  - EQ2_17 */
-       [0x0E37] = 0x058C,     /* R3639  - EQ2_18 */
-       [0x0E38] = 0x0563,     /* R3640  - EQ2_19 */
-       [0x0E39] = 0x4000,     /* R3641  - EQ2_20 */
-       [0x0E3C] = 0x6318,     /* R3644  - EQ3_1 */
-       [0x0E3D] = 0x6300,     /* R3645  - EQ3_2 */
-       [0x0E3E] = 0x0FC8,     /* R3646  - EQ3_3 */
-       [0x0E3F] = 0x03FE,     /* R3647  - EQ3_4 */
-       [0x0E40] = 0x00E0,     /* R3648  - EQ3_5 */
-       [0x0E41] = 0x1EC4,     /* R3649  - EQ3_6 */
-       [0x0E42] = 0xF136,     /* R3650  - EQ3_7 */
-       [0x0E43] = 0x0409,     /* R3651  - EQ3_8 */
-       [0x0E44] = 0x04CC,     /* R3652  - EQ3_9 */
-       [0x0E45] = 0x1C9B,     /* R3653  - EQ3_10 */
-       [0x0E46] = 0xF337,     /* R3654  - EQ3_11 */
-       [0x0E47] = 0x040B,     /* R3655  - EQ3_12 */
-       [0x0E48] = 0x0CBB,     /* R3656  - EQ3_13 */
-       [0x0E49] = 0x16F8,     /* R3657  - EQ3_14 */
-       [0x0E4A] = 0xF7D9,     /* R3658  - EQ3_15 */
-       [0x0E4B] = 0x040A,     /* R3659  - EQ3_16 */
-       [0x0E4C] = 0x1F14,     /* R3660  - EQ3_17 */
-       [0x0E4D] = 0x058C,     /* R3661  - EQ3_18 */
-       [0x0E4E] = 0x0563,     /* R3662  - EQ3_19 */
-       [0x0E4F] = 0x4000,     /* R3663  - EQ3_20 */
-       [0x0E52] = 0x6318,     /* R3666  - EQ4_1 */
-       [0x0E53] = 0x6300,     /* R3667  - EQ4_2 */
-       [0x0E54] = 0x0FC8,     /* R3668  - EQ4_3 */
-       [0x0E55] = 0x03FE,     /* R3669  - EQ4_4 */
-       [0x0E56] = 0x00E0,     /* R3670  - EQ4_5 */
-       [0x0E57] = 0x1EC4,     /* R3671  - EQ4_6 */
-       [0x0E58] = 0xF136,     /* R3672  - EQ4_7 */
-       [0x0E59] = 0x0409,     /* R3673  - EQ4_8 */
-       [0x0E5A] = 0x04CC,     /* R3674  - EQ4_9 */
-       [0x0E5B] = 0x1C9B,     /* R3675  - EQ4_10 */
-       [0x0E5C] = 0xF337,     /* R3676  - EQ4_11 */
-       [0x0E5D] = 0x040B,     /* R3677  - EQ4_12 */
-       [0x0E5E] = 0x0CBB,     /* R3678  - EQ4_13 */
-       [0x0E5F] = 0x16F8,     /* R3679  - EQ4_14 */
-       [0x0E60] = 0xF7D9,     /* R3680  - EQ4_15 */
-       [0x0E61] = 0x040A,     /* R3681  - EQ4_16 */
-       [0x0E62] = 0x1F14,     /* R3682  - EQ4_17 */
-       [0x0E63] = 0x058C,     /* R3683  - EQ4_18 */
-       [0x0E64] = 0x0563,     /* R3684  - EQ4_19 */
-       [0x0E65] = 0x4000,     /* R3685  - EQ4_20 */
-       [0x0E80] = 0x0018,     /* R3712  - DRC1 ctrl1 */
-       [0x0E81] = 0x0933,     /* R3713  - DRC1 ctrl2 */
-       [0x0E82] = 0x0018,     /* R3714  - DRC1 ctrl3 */
-       [0x0E83] = 0x0000,     /* R3715  - DRC1 ctrl4 */
-       [0x0E84] = 0x0000,     /* R3716  - DRC1 ctrl5 */
-       [0x0EC0] = 0x0000,     /* R3776  - HPLPF1_1 */
-       [0x0EC1] = 0x0000,     /* R3777  - HPLPF1_2 */
-       [0x0EC4] = 0x0000,     /* R3780  - HPLPF2_1 */
-       [0x0EC5] = 0x0000,     /* R3781  - HPLPF2_2 */
-       [0x0EC8] = 0x0000,     /* R3784  - HPLPF3_1 */
-       [0x0EC9] = 0x0000,     /* R3785  - HPLPF3_2 */
-       [0x0ECC] = 0x0000,     /* R3788  - HPLPF4_1 */
-       [0x0ECD] = 0x0000,     /* R3789  - HPLPF4_2 */
-       [0x4000] = 0x0000,     /* R16384 - DSP1 DM 0 */
-       [0x4001] = 0x0000,     /* R16385 - DSP1 DM 1 */
-       [0x4002] = 0x0000,     /* R16386 - DSP1 DM 2 */
-       [0x4003] = 0x0000,     /* R16387 - DSP1 DM 3 */
-       [0x41FC] = 0x0000,     /* R16892 - DSP1 DM 508 */
-       [0x41FD] = 0x0000,     /* R16893 - DSP1 DM 509 */
-       [0x41FE] = 0x0000,     /* R16894 - DSP1 DM 510 */
-       [0x41FF] = 0x0000,     /* R16895 - DSP1 DM 511 */
-       [0x4800] = 0x0000,     /* R18432 - DSP1 PM 0 */
-       [0x4801] = 0x0000,     /* R18433 - DSP1 PM 1 */
-       [0x4802] = 0x0000,     /* R18434 - DSP1 PM 2 */
-       [0x4803] = 0x0000,     /* R18435 - DSP1 PM 3 */
-       [0x4804] = 0x0000,     /* R18436 - DSP1 PM 4 */
-       [0x4805] = 0x0000,     /* R18437 - DSP1 PM 5 */
-       [0x4DFA] = 0x0000,     /* R19962 - DSP1 PM 1530 */
-       [0x4DFB] = 0x0000,     /* R19963 - DSP1 PM 1531 */
-       [0x4DFC] = 0x0000,     /* R19964 - DSP1 PM 1532 */
-       [0x4DFD] = 0x0000,     /* R19965 - DSP1 PM 1533 */
-       [0x4DFE] = 0x0000,     /* R19966 - DSP1 PM 1534 */
-       [0x4DFF] = 0x0000,     /* R19967 - DSP1 PM 1535 */
-       [0x5000] = 0x0000,     /* R20480 - DSP1 ZM 0 */
-       [0x5001] = 0x0000,     /* R20481 - DSP1 ZM 1 */
-       [0x5002] = 0x0000,     /* R20482 - DSP1 ZM 2 */
-       [0x5003] = 0x0000,     /* R20483 - DSP1 ZM 3 */
-       [0x57FC] = 0x0000,     /* R22524 - DSP1 ZM 2044 */
-       [0x57FD] = 0x0000,     /* R22525 - DSP1 ZM 2045 */
-       [0x57FE] = 0x0000,     /* R22526 - DSP1 ZM 2046 */
-       [0x57FF] = 0x0000,     /* R22527 - DSP1 ZM 2047 */
-       [0x6000] = 0x0000,     /* R24576 - DSP2 DM 0 */
-       [0x6001] = 0x0000,     /* R24577 - DSP2 DM 1 */
-       [0x6002] = 0x0000,     /* R24578 - DSP2 DM 2 */
-       [0x6003] = 0x0000,     /* R24579 - DSP2 DM 3 */
-       [0x61FC] = 0x0000,     /* R25084 - DSP2 DM 508 */
-       [0x61FD] = 0x0000,     /* R25085 - DSP2 DM 509 */
-       [0x61FE] = 0x0000,     /* R25086 - DSP2 DM 510 */
-       [0x61FF] = 0x0000,     /* R25087 - DSP2 DM 511 */
-       [0x6800] = 0x0000,     /* R26624 - DSP2 PM 0 */
-       [0x6801] = 0x0000,     /* R26625 - DSP2 PM 1 */
-       [0x6802] = 0x0000,     /* R26626 - DSP2 PM 2 */
-       [0x6803] = 0x0000,     /* R26627 - DSP2 PM 3 */
-       [0x6804] = 0x0000,     /* R26628 - DSP2 PM 4 */
-       [0x6805] = 0x0000,     /* R26629 - DSP2 PM 5 */
-       [0x6DFA] = 0x0000,     /* R28154 - DSP2 PM 1530 */
-       [0x6DFB] = 0x0000,     /* R28155 - DSP2 PM 1531 */
-       [0x6DFC] = 0x0000,     /* R28156 - DSP2 PM 1532 */
-       [0x6DFD] = 0x0000,     /* R28157 - DSP2 PM 1533 */
-       [0x6DFE] = 0x0000,     /* R28158 - DSP2 PM 1534 */
-       [0x6DFF] = 0x0000,     /* R28159 - DSP2 PM 1535 */
-       [0x7000] = 0x0000,     /* R28672 - DSP2 ZM 0 */
-       [0x7001] = 0x0000,     /* R28673 - DSP2 ZM 1 */
-       [0x7002] = 0x0000,     /* R28674 - DSP2 ZM 2 */
-       [0x7003] = 0x0000,     /* R28675 - DSP2 ZM 3 */
-       [0x77FC] = 0x0000,     /* R30716 - DSP2 ZM 2044 */
-       [0x77FD] = 0x0000,     /* R30717 - DSP2 ZM 2045 */
-       [0x77FE] = 0x0000,     /* R30718 - DSP2 ZM 2046 */
-       [0x77FF] = 0x0000,     /* R30719 - DSP2 ZM 2047 */
-       [0x8000] = 0x0000,     /* R32768 - DSP3 DM 0 */
-       [0x8001] = 0x0000,     /* R32769 - DSP3 DM 1 */
-       [0x8002] = 0x0000,     /* R32770 - DSP3 DM 2 */
-       [0x8003] = 0x0000,     /* R32771 - DSP3 DM 3 */
-       [0x81FC] = 0x0000,     /* R33276 - DSP3 DM 508 */
-       [0x81FD] = 0x0000,     /* R33277 - DSP3 DM 509 */
-       [0x81FE] = 0x0000,     /* R33278 - DSP3 DM 510 */
-       [0x81FF] = 0x0000,     /* R33279 - DSP3 DM 511 */
-       [0x8800] = 0x0000,     /* R34816 - DSP3 PM 0 */
-       [0x8801] = 0x0000,     /* R34817 - DSP3 PM 1 */
-       [0x8802] = 0x0000,     /* R34818 - DSP3 PM 2 */
-       [0x8803] = 0x0000,     /* R34819 - DSP3 PM 3 */
-       [0x8804] = 0x0000,     /* R34820 - DSP3 PM 4 */
-       [0x8805] = 0x0000,     /* R34821 - DSP3 PM 5 */
-       [0x8DFA] = 0x0000,     /* R36346 - DSP3 PM 1530 */
-       [0x8DFB] = 0x0000,     /* R36347 - DSP3 PM 1531 */
-       [0x8DFC] = 0x0000,     /* R36348 - DSP3 PM 1532 */
-       [0x8DFD] = 0x0000,     /* R36349 - DSP3 PM 1533 */
-       [0x8DFE] = 0x0000,     /* R36350 - DSP3 PM 1534 */
-       [0x8DFF] = 0x0000,     /* R36351 - DSP3 PM 1535 */
-       [0x9000] = 0x0000,     /* R36864 - DSP3 ZM 0 */
-       [0x9001] = 0x0000,     /* R36865 - DSP3 ZM 1 */
-       [0x9002] = 0x0000,     /* R36866 - DSP3 ZM 2 */
-       [0x9003] = 0x0000,     /* R36867 - DSP3 ZM 3 */
-       [0x97FC] = 0x0000,     /* R38908 - DSP3 ZM 2044 */
-       [0x97FD] = 0x0000,     /* R38909 - DSP3 ZM 2045 */
-       [0x97FE] = 0x0000,     /* R38910 - DSP3 ZM 2046 */
-       [0x97FF] = 0x0000      /* R38911 - DSP3 ZM 2047 */
+struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT] = {
+       { 0x0000, 0x0000 },  /* R0     - software reset */
+       { 0x0001, 0x0000 },  /* R1     - Device Revision */
+       { 0x0010, 0x0801 },  /* R16    - Ctrl IF 1 */
+       { 0x0020, 0x0000 },  /* R32    - Tone Generator 1 */
+       { 0x0030, 0x0000 },  /* R48    - PWM Drive 1 */
+       { 0x0031, 0x0100 },  /* R49    - PWM Drive 2 */
+       { 0x0032, 0x0100 },  /* R50    - PWM Drive 3 */
+       { 0x0100, 0x0002 },  /* R256   - Clocking 1 */
+       { 0x0101, 0x0000 },  /* R257   - Clocking 3 */
+       { 0x0102, 0x0011 },  /* R258   - Clocking 4 */
+       { 0x0103, 0x0011 },  /* R259   - Clocking 5 */
+       { 0x0104, 0x0011 },  /* R260   - Clocking 6 */
+       { 0x0107, 0x0000 },  /* R263   - Clocking 7 */
+       { 0x0108, 0x0000 },  /* R264   - Clocking 8 */
+       { 0x0120, 0x0000 },  /* R288   - ASRC_ENABLE */
+       { 0x0121, 0x0000 },  /* R289   - ASRC_STATUS */
+       { 0x0122, 0x0000 },  /* R290   - ASRC_RATE1 */
+       { 0x0141, 0x8000 },  /* R321   - ISRC 1 CTRL 1 */
+       { 0x0142, 0x0000 },  /* R322   - ISRC 1 CTRL 2 */
+       { 0x0143, 0x8000 },  /* R323   - ISRC 2 CTRL1 */
+       { 0x0144, 0x0000 },  /* R324   - ISRC 2 CTRL 2 */
+       { 0x0182, 0x0000 },  /* R386   - FLL1 Control 1 */
+       { 0x0183, 0x0000 },  /* R387   - FLL1 Control 2 */
+       { 0x0184, 0x0000 },  /* R388   - FLL1 Control 3 */
+       { 0x0186, 0x0177 },  /* R390   - FLL1 Control 5 */
+       { 0x0187, 0x0001 },  /* R391   - FLL1 Control 6 */
+       { 0x0188, 0x0000 },  /* R392   - FLL1 EFS 1 */
+       { 0x01A2, 0x0000 },  /* R418   - FLL2 Control 1 */
+       { 0x01A3, 0x0000 },  /* R419   - FLL2 Control 2 */
+       { 0x01A4, 0x0000 },  /* R420   - FLL2 Control 3 */
+       { 0x01A6, 0x0177 },  /* R422   - FLL2 Control 5 */
+       { 0x01A7, 0x0001 },  /* R423   - FLL2 Control 6 */
+       { 0x01A8, 0x0000 },  /* R424   - FLL2 EFS 1 */
+       { 0x0200, 0x0020 },  /* R512   - Mic Charge Pump 1 */
+       { 0x0201, 0xB084 },  /* R513   - Mic Charge Pump 2 */
+       { 0x0202, 0xBBDE },  /* R514   - HP Charge Pump 1 */
+       { 0x0211, 0x20D4 },  /* R529   - LDO1 Control */
+       { 0x0215, 0x0062 },  /* R533   - Mic Bias Ctrl 1 */
+       { 0x0216, 0x0062 },  /* R534   - Mic Bias Ctrl 2 */
+       { 0x0217, 0x0062 },  /* R535   - Mic Bias Ctrl 3 */
+       { 0x0280, 0x0004 },  /* R640   - Accessory Detect Mode 1 */
+       { 0x0288, 0x0020 },  /* R648   - Headphone Detect 1 */
+       { 0x0289, 0x0000 },  /* R649   - Headphone Detect 2 */
+       { 0x0290, 0x1100 },  /* R656   - Mic Detect 1 */
+       { 0x0291, 0x009F },  /* R657   - Mic Detect 2 */
+       { 0x0292, 0x0000 },  /* R658   - Mic Detect 3 */
+       { 0x0301, 0x0000 },  /* R769   - Input Enables */
+       { 0x0302, 0x0000 },  /* R770   - Input Enables Status */
+       { 0x0310, 0x2280 },  /* R784   - Status */
+       { 0x0311, 0x0080 },  /* R785   - IN1R Control */
+       { 0x0312, 0x2280 },  /* R786   - IN2L Control */
+       { 0x0313, 0x0080 },  /* R787   - IN2R Control */
+       { 0x0314, 0x2280 },  /* R788   - IN3L Control */
+       { 0x0315, 0x0080 },  /* R789   - IN3R Control */
+       { 0x0316, 0x2280 },  /* R790   - IN4L Control */
+       { 0x0317, 0x0080 },  /* R791   - IN4R Control */
+       { 0x0318, 0x0000 },  /* R792   - RXANC_SRC */
+       { 0x0319, 0x0022 },  /* R793   - Input Volume Ramp */
+       { 0x0320, 0x0180 },  /* R800   - ADC Digital Volume 1L */
+       { 0x0321, 0x0180 },  /* R801   - ADC Digital Volume 1R */
+       { 0x0322, 0x0180 },  /* R802   - ADC Digital Volume 2L */
+       { 0x0323, 0x0180 },  /* R803   - ADC Digital Volume 2R */
+       { 0x0324, 0x0180 },  /* R804   - ADC Digital Volume 3L */
+       { 0x0325, 0x0180 },  /* R805   - ADC Digital Volume 3R */
+       { 0x0326, 0x0180 },  /* R806   - ADC Digital Volume 4L */
+       { 0x0327, 0x0180 },  /* R807   - ADC Digital Volume 4R */
+       { 0x0401, 0x0000 },  /* R1025  - Output Enables 2 */
+       { 0x0402, 0x0000 },  /* R1026  - Output Status 1 */
+       { 0x0403, 0x0000 },  /* R1027  - Output Status 2 */
+       { 0x0408, 0x0000 },  /* R1032  - Channel Enables 1 */
+       { 0x0410, 0x0080 },  /* R1040  - Out Volume 1L */
+       { 0x0411, 0x0080 },  /* R1041  - Out Volume 1R */
+       { 0x0412, 0x0080 },  /* R1042  - DAC Volume Limit 1L */
+       { 0x0413, 0x0080 },  /* R1043  - DAC Volume Limit 1R */
+       { 0x0414, 0x0080 },  /* R1044  - Out Volume 2L */
+       { 0x0415, 0x0080 },  /* R1045  - Out Volume 2R */
+       { 0x0416, 0x0080 },  /* R1046  - DAC Volume Limit 2L */
+       { 0x0417, 0x0080 },  /* R1047  - DAC Volume Limit 2R */
+       { 0x0418, 0x0080 },  /* R1048  - Out Volume 3L */
+       { 0x0419, 0x0080 },  /* R1049  - Out Volume 3R */
+       { 0x041A, 0x0080 },  /* R1050  - DAC Volume Limit 3L */
+       { 0x041B, 0x0080 },  /* R1051  - DAC Volume Limit 3R */
+       { 0x041C, 0x0080 },  /* R1052  - Out Volume 4L */
+       { 0x041D, 0x0080 },  /* R1053  - Out Volume 4R */
+       { 0x041E, 0x0080 },  /* R1054  - DAC Volume Limit 5L */
+       { 0x041F, 0x0080 },  /* R1055  - DAC Volume Limit 5R */
+       { 0x0420, 0x0080 },  /* R1056  - DAC Volume Limit 6L */
+       { 0x0421, 0x0080 },  /* R1057  - DAC Volume Limit 6R */
+       { 0x0440, 0x0000 },  /* R1088  - DAC AEC Control 1 */
+       { 0x0441, 0x0022 },  /* R1089  - Output Volume Ramp */
+       { 0x0480, 0x0180 },  /* R1152  - DAC Digital Volume 1L */
+       { 0x0481, 0x0180 },  /* R1153  - DAC Digital Volume 1R */
+       { 0x0482, 0x0180 },  /* R1154  - DAC Digital Volume 2L */
+       { 0x0483, 0x0180 },  /* R1155  - DAC Digital Volume 2R */
+       { 0x0484, 0x0180 },  /* R1156  - DAC Digital Volume 3L */
+       { 0x0485, 0x0180 },  /* R1157  - DAC Digital Volume 3R */
+       { 0x0486, 0x0180 },  /* R1158  - DAC Digital Volume 4L */
+       { 0x0487, 0x0180 },  /* R1159  - DAC Digital Volume 4R */
+       { 0x0488, 0x0180 },  /* R1160  - DAC Digital Volume 5L */
+       { 0x0489, 0x0180 },  /* R1161  - DAC Digital Volume 5R */
+       { 0x048A, 0x0180 },  /* R1162  - DAC Digital Volume 6L */
+       { 0x048B, 0x0180 },  /* R1163  - DAC Digital Volume 6R */
+       { 0x04C0, 0x0069 },  /* R1216  - PDM SPK1 CTRL 1 */
+       { 0x04C1, 0x0000 },  /* R1217  - PDM SPK1 CTRL 2 */
+       { 0x04C2, 0x0069 },  /* R1218  - PDM SPK2 CTRL 1 */
+       { 0x04C3, 0x0000 },  /* R1219  - PDM SPK2 CTRL 2 */
+       { 0x0500, 0x000C },  /* R1280  - Audio IF 1_1 */
+       { 0x0501, 0x0008 },  /* R1281  - Audio IF 1_2 */
+       { 0x0502, 0x0000 },  /* R1282  - Audio IF 1_3 */
+       { 0x0503, 0x0000 },  /* R1283  - Audio IF 1_4 */
+       { 0x0504, 0x0000 },  /* R1284  - Audio IF 1_5 */
+       { 0x0505, 0x0300 },  /* R1285  - Audio IF 1_6 */
+       { 0x0506, 0x0300 },  /* R1286  - Audio IF 1_7 */
+       { 0x0507, 0x1820 },  /* R1287  - Audio IF 1_8 */
+       { 0x0508, 0x1820 },  /* R1288  - Audio IF 1_9 */
+       { 0x0509, 0x0000 },  /* R1289  - Audio IF 1_10 */
+       { 0x050A, 0x0001 },  /* R1290  - Audio IF 1_11 */
+       { 0x050B, 0x0002 },  /* R1291  - Audio IF 1_12 */
+       { 0x050C, 0x0003 },  /* R1292  - Audio IF 1_13 */
+       { 0x050D, 0x0004 },  /* R1293  - Audio IF 1_14 */
+       { 0x050E, 0x0005 },  /* R1294  - Audio IF 1_15 */
+       { 0x050F, 0x0006 },  /* R1295  - Audio IF 1_16 */
+       { 0x0510, 0x0007 },  /* R1296  - Audio IF 1_17 */
+       { 0x0511, 0x0000 },  /* R1297  - Audio IF 1_18 */
+       { 0x0512, 0x0001 },  /* R1298  - Audio IF 1_19 */
+       { 0x0513, 0x0002 },  /* R1299  - Audio IF 1_20 */
+       { 0x0514, 0x0003 },  /* R1300  - Audio IF 1_21 */
+       { 0x0515, 0x0004 },  /* R1301  - Audio IF 1_22 */
+       { 0x0516, 0x0005 },  /* R1302  - Audio IF 1_23 */
+       { 0x0517, 0x0006 },  /* R1303  - Audio IF 1_24 */
+       { 0x0518, 0x0007 },  /* R1304  - Audio IF 1_25 */
+       { 0x0519, 0x0000 },  /* R1305  - Audio IF 1_26 */
+       { 0x051A, 0x0000 },  /* R1306  - Audio IF 1_27 */
+       { 0x0540, 0x000C },  /* R1344  - Audio IF 2_1 */
+       { 0x0541, 0x0008 },  /* R1345  - Audio IF 2_2 */
+       { 0x0542, 0x0000 },  /* R1346  - Audio IF 2_3 */
+       { 0x0543, 0x0000 },  /* R1347  - Audio IF 2_4 */
+       { 0x0544, 0x0000 },  /* R1348  - Audio IF 2_5 */
+       { 0x0545, 0x0300 },  /* R1349  - Audio IF 2_6 */
+       { 0x0546, 0x0300 },  /* R1350  - Audio IF 2_7 */
+       { 0x0547, 0x1820 },  /* R1351  - Audio IF 2_8 */
+       { 0x0548, 0x1820 },  /* R1352  - Audio IF 2_9 */
+       { 0x0549, 0x0000 },  /* R1353  - Audio IF 2_10 */
+       { 0x054A, 0x0001 },  /* R1354  - Audio IF 2_11 */
+       { 0x0551, 0x0000 },  /* R1361  - Audio IF 2_18 */
+       { 0x0552, 0x0001 },  /* R1362  - Audio IF 2_19 */
+       { 0x0559, 0x0000 },  /* R1369  - Audio IF 2_26 */
+       { 0x055A, 0x0000 },  /* R1370  - Audio IF 2_27 */
+       { 0x0580, 0x000C },  /* R1408  - Audio IF 3_1 */
+       { 0x0581, 0x0008 },  /* R1409  - Audio IF 3_2 */
+       { 0x0582, 0x0000 },  /* R1410  - Audio IF 3_3 */
+       { 0x0583, 0x0000 },  /* R1411  - Audio IF 3_4 */
+       { 0x0584, 0x0000 },  /* R1412  - Audio IF 3_5 */
+       { 0x0585, 0x0300 },  /* R1413  - Audio IF 3_6 */
+       { 0x0586, 0x0300 },  /* R1414  - Audio IF 3_7 */
+       { 0x0587, 0x1820 },  /* R1415  - Audio IF 3_8 */
+       { 0x0588, 0x1820 },  /* R1416  - Audio IF 3_9 */
+       { 0x0589, 0x0000 },  /* R1417  - Audio IF 3_10 */
+       { 0x058A, 0x0001 },  /* R1418  - Audio IF 3_11 */
+       { 0x0591, 0x0000 },  /* R1425  - Audio IF 3_18 */
+       { 0x0592, 0x0001 },  /* R1426  - Audio IF 3_19 */
+       { 0x0599, 0x0000 },  /* R1433  - Audio IF 3_26 */
+       { 0x059A, 0x0000 },  /* R1434  - Audio IF 3_27 */
+       { 0x0640, 0x0000 },  /* R1600  - PWM1MIX Input 1 Source */
+       { 0x0641, 0x0080 },  /* R1601  - PWM1MIX Input 1 Volume */
+       { 0x0642, 0x0000 },  /* R1602  - PWM1MIX Input 2 Source */
+       { 0x0643, 0x0080 },  /* R1603  - PWM1MIX Input 2 Volume */
+       { 0x0644, 0x0000 },  /* R1604  - PWM1MIX Input 3 Source */
+       { 0x0645, 0x0080 },  /* R1605  - PWM1MIX Input 3 Volume */
+       { 0x0646, 0x0000 },  /* R1606  - PWM1MIX Input 4 Source */
+       { 0x0647, 0x0080 },  /* R1607  - PWM1MIX Input 4 Volume */
+       { 0x0648, 0x0000 },  /* R1608  - PWM2MIX Input 1 Source */
+       { 0x0649, 0x0080 },  /* R1609  - PWM2MIX Input 1 Volume */
+       { 0x064A, 0x0000 },  /* R1610  - PWM2MIX Input 2 Source */
+       { 0x064B, 0x0080 },  /* R1611  - PWM2MIX Input 2 Volume */
+       { 0x064C, 0x0000 },  /* R1612  - PWM2MIX Input 3 Source */
+       { 0x064D, 0x0080 },  /* R1613  - PWM2MIX Input 3 Volume */
+       { 0x064E, 0x0000 },  /* R1614  - PWM2MIX Input 4 Source */
+       { 0x064F, 0x0080 },  /* R1615  - PWM2MIX Input 4 Volume */
+       { 0x0680, 0x0000 },  /* R1664  - OUT1LMIX Input 1 Source */
+       { 0x0681, 0x0080 },  /* R1665  - OUT1LMIX Input 1 Volume */
+       { 0x0682, 0x0000 },  /* R1666  - OUT1LMIX Input 2 Source */
+       { 0x0683, 0x0080 },  /* R1667  - OUT1LMIX Input 2 Volume */
+       { 0x0684, 0x0000 },  /* R1668  - OUT1LMIX Input 3 Source */
+       { 0x0685, 0x0080 },  /* R1669  - OUT1LMIX Input 3 Volume */
+       { 0x0686, 0x0000 },  /* R1670  - OUT1LMIX Input 4 Source */
+       { 0x0687, 0x0080 },  /* R1671  - OUT1LMIX Input 4 Volume */
+       { 0x0688, 0x0000 },  /* R1672  - OUT1RMIX Input 1 Source */
+       { 0x0689, 0x0080 },  /* R1673  - OUT1RMIX Input 1 Volume */
+       { 0x068A, 0x0000 },  /* R1674  - OUT1RMIX Input 2 Source */
+       { 0x068B, 0x0080 },  /* R1675  - OUT1RMIX Input 2 Volume */
+       { 0x068C, 0x0000 },  /* R1676  - OUT1RMIX Input 3 Source */
+       { 0x068D, 0x0080 },  /* R1677  - OUT1RMIX Input 3 Volume */
+       { 0x068E, 0x0000 },  /* R1678  - OUT1RMIX Input 4 Source */
+       { 0x068F, 0x0080 },  /* R1679  - OUT1RMIX Input 4 Volume */
+       { 0x0690, 0x0000 },  /* R1680  - OUT2LMIX Input 1 Source */
+       { 0x0691, 0x0080 },  /* R1681  - OUT2LMIX Input 1 Volume */
+       { 0x0692, 0x0000 },  /* R1682  - OUT2LMIX Input 2 Source */
+       { 0x0693, 0x0080 },  /* R1683  - OUT2LMIX Input 2 Volume */
+       { 0x0694, 0x0000 },  /* R1684  - OUT2LMIX Input 3 Source */
+       { 0x0695, 0x0080 },  /* R1685  - OUT2LMIX Input 3 Volume */
+       { 0x0696, 0x0000 },  /* R1686  - OUT2LMIX Input 4 Source */
+       { 0x0697, 0x0080 },  /* R1687  - OUT2LMIX Input 4 Volume */
+       { 0x0698, 0x0000 },  /* R1688  - OUT2RMIX Input 1 Source */
+       { 0x0699, 0x0080 },  /* R1689  - OUT2RMIX Input 1 Volume */
+       { 0x069A, 0x0000 },  /* R1690  - OUT2RMIX Input 2 Source */
+       { 0x069B, 0x0080 },  /* R1691  - OUT2RMIX Input 2 Volume */
+       { 0x069C, 0x0000 },  /* R1692  - OUT2RMIX Input 3 Source */
+       { 0x069D, 0x0080 },  /* R1693  - OUT2RMIX Input 3 Volume */
+       { 0x069E, 0x0000 },  /* R1694  - OUT2RMIX Input 4 Source */
+       { 0x069F, 0x0080 },  /* R1695  - OUT2RMIX Input 4 Volume */
+       { 0x06A0, 0x0000 },  /* R1696  - OUT3LMIX Input 1 Source */
+       { 0x06A1, 0x0080 },  /* R1697  - OUT3LMIX Input 1 Volume */
+       { 0x06A2, 0x0000 },  /* R1698  - OUT3LMIX Input 2 Source */
+       { 0x06A3, 0x0080 },  /* R1699  - OUT3LMIX Input 2 Volume */
+       { 0x06A4, 0x0000 },  /* R1700  - OUT3LMIX Input 3 Source */
+       { 0x06A5, 0x0080 },  /* R1701  - OUT3LMIX Input 3 Volume */
+       { 0x06A6, 0x0000 },  /* R1702  - OUT3LMIX Input 4 Source */
+       { 0x06A7, 0x0080 },  /* R1703  - OUT3LMIX Input 4 Volume */
+       { 0x06A8, 0x0000 },  /* R1704  - OUT3RMIX Input 1 Source */
+       { 0x06A9, 0x0080 },  /* R1705  - OUT3RMIX Input 1 Volume */
+       { 0x06AA, 0x0000 },  /* R1706  - OUT3RMIX Input 2 Source */
+       { 0x06AB, 0x0080 },  /* R1707  - OUT3RMIX Input 2 Volume */
+       { 0x06AC, 0x0000 },  /* R1708  - OUT3RMIX Input 3 Source */
+       { 0x06AD, 0x0080 },  /* R1709  - OUT3RMIX Input 3 Volume */
+       { 0x06AE, 0x0000 },  /* R1710  - OUT3RMIX Input 4 Source */
+       { 0x06AF, 0x0080 },  /* R1711  - OUT3RMIX Input 4 Volume */
+       { 0x06B0, 0x0000 },  /* R1712  - OUT4LMIX Input 1 Source */
+       { 0x06B1, 0x0080 },  /* R1713  - OUT4LMIX Input 1 Volume */
+       { 0x06B2, 0x0000 },  /* R1714  - OUT4LMIX Input 2 Source */
+       { 0x06B3, 0x0080 },  /* R1715  - OUT4LMIX Input 2 Volume */
+       { 0x06B4, 0x0000 },  /* R1716  - OUT4LMIX Input 3 Source */
+       { 0x06B5, 0x0080 },  /* R1717  - OUT4LMIX Input 3 Volume */
+       { 0x06B6, 0x0000 },  /* R1718  - OUT4LMIX Input 4 Source */
+       { 0x06B7, 0x0080 },  /* R1719  - OUT4LMIX Input 4 Volume */
+       { 0x06B8, 0x0000 },  /* R1720  - OUT4RMIX Input 1 Source */
+       { 0x06B9, 0x0080 },  /* R1721  - OUT4RMIX Input 1 Volume */
+       { 0x06BA, 0x0000 },  /* R1722  - OUT4RMIX Input 2 Source */
+       { 0x06BB, 0x0080 },  /* R1723  - OUT4RMIX Input 2 Volume */
+       { 0x06BC, 0x0000 },  /* R1724  - OUT4RMIX Input 3 Source */
+       { 0x06BD, 0x0080 },  /* R1725  - OUT4RMIX Input 3 Volume */
+       { 0x06BE, 0x0000 },  /* R1726  - OUT4RMIX Input 4 Source */
+       { 0x06BF, 0x0080 },  /* R1727  - OUT4RMIX Input 4 Volume */
+       { 0x06C0, 0x0000 },  /* R1728  - OUT5LMIX Input 1 Source */
+       { 0x06C1, 0x0080 },  /* R1729  - OUT5LMIX Input 1 Volume */
+       { 0x06C2, 0x0000 },  /* R1730  - OUT5LMIX Input 2 Source */
+       { 0x06C3, 0x0080 },  /* R1731  - OUT5LMIX Input 2 Volume */
+       { 0x06C4, 0x0000 },  /* R1732  - OUT5LMIX Input 3 Source */
+       { 0x06C5, 0x0080 },  /* R1733  - OUT5LMIX Input 3 Volume */
+       { 0x06C6, 0x0000 },  /* R1734  - OUT5LMIX Input 4 Source */
+       { 0x06C7, 0x0080 },  /* R1735  - OUT5LMIX Input 4 Volume */
+       { 0x06C8, 0x0000 },  /* R1736  - OUT5RMIX Input 1 Source */
+       { 0x06C9, 0x0080 },  /* R1737  - OUT5RMIX Input 1 Volume */
+       { 0x06CA, 0x0000 },  /* R1738  - OUT5RMIX Input 2 Source */
+       { 0x06CB, 0x0080 },  /* R1739  - OUT5RMIX Input 2 Volume */
+       { 0x06CC, 0x0000 },  /* R1740  - OUT5RMIX Input 3 Source */
+       { 0x06CD, 0x0080 },  /* R1741  - OUT5RMIX Input 3 Volume */
+       { 0x06CE, 0x0000 },  /* R1742  - OUT5RMIX Input 4 Source */
+       { 0x06CF, 0x0080 },  /* R1743  - OUT5RMIX Input 4 Volume */
+       { 0x06D0, 0x0000 },  /* R1744  - OUT6LMIX Input 1 Source */
+       { 0x06D1, 0x0080 },  /* R1745  - OUT6LMIX Input 1 Volume */
+       { 0x06D2, 0x0000 },  /* R1746  - OUT6LMIX Input 2 Source */
+       { 0x06D3, 0x0080 },  /* R1747  - OUT6LMIX Input 2 Volume */
+       { 0x06D4, 0x0000 },  /* R1748  - OUT6LMIX Input 3 Source */
+       { 0x06D5, 0x0080 },  /* R1749  - OUT6LMIX Input 3 Volume */
+       { 0x06D6, 0x0000 },  /* R1750  - OUT6LMIX Input 4 Source */
+       { 0x06D7, 0x0080 },  /* R1751  - OUT6LMIX Input 4 Volume */
+       { 0x06D8, 0x0000 },  /* R1752  - OUT6RMIX Input 1 Source */
+       { 0x06D9, 0x0080 },  /* R1753  - OUT6RMIX Input 1 Volume */
+       { 0x06DA, 0x0000 },  /* R1754  - OUT6RMIX Input 2 Source */
+       { 0x06DB, 0x0080 },  /* R1755  - OUT6RMIX Input 2 Volume */
+       { 0x06DC, 0x0000 },  /* R1756  - OUT6RMIX Input 3 Source */
+       { 0x06DD, 0x0080 },  /* R1757  - OUT6RMIX Input 3 Volume */
+       { 0x06DE, 0x0000 },  /* R1758  - OUT6RMIX Input 4 Source */
+       { 0x06DF, 0x0080 },  /* R1759  - OUT6RMIX Input 4 Volume */
+       { 0x0700, 0x0000 },  /* R1792  - AIF1TX1MIX Input 1 Source */
+       { 0x0701, 0x0080 },  /* R1793  - AIF1TX1MIX Input 1 Volume */
+       { 0x0702, 0x0000 },  /* R1794  - AIF1TX1MIX Input 2 Source */
+       { 0x0703, 0x0080 },  /* R1795  - AIF1TX1MIX Input 2 Volume */
+       { 0x0704, 0x0000 },  /* R1796  - AIF1TX1MIX Input 3 Source */
+       { 0x0705, 0x0080 },  /* R1797  - AIF1TX1MIX Input 3 Volume */
+       { 0x0706, 0x0000 },  /* R1798  - AIF1TX1MIX Input 4 Source */
+       { 0x0707, 0x0080 },  /* R1799  - AIF1TX1MIX Input 4 Volume */
+       { 0x0708, 0x0000 },  /* R1800  - AIF1TX2MIX Input 1 Source */
+       { 0x0709, 0x0080 },  /* R1801  - AIF1TX2MIX Input 1 Volume */
+       { 0x070A, 0x0000 },  /* R1802  - AIF1TX2MIX Input 2 Source */
+       { 0x070B, 0x0080 },  /* R1803  - AIF1TX2MIX Input 2 Volume */
+       { 0x070C, 0x0000 },  /* R1804  - AIF1TX2MIX Input 3 Source */
+       { 0x070D, 0x0080 },  /* R1805  - AIF1TX2MIX Input 3 Volume */
+       { 0x070E, 0x0000 },  /* R1806  - AIF1TX2MIX Input 4 Source */
+       { 0x070F, 0x0080 },  /* R1807  - AIF1TX2MIX Input 4 Volume */
+       { 0x0710, 0x0000 },  /* R1808  - AIF1TX3MIX Input 1 Source */
+       { 0x0711, 0x0080 },  /* R1809  - AIF1TX3MIX Input 1 Volume */
+       { 0x0712, 0x0000 },  /* R1810  - AIF1TX3MIX Input 2 Source */
+       { 0x0713, 0x0080 },  /* R1811  - AIF1TX3MIX Input 2 Volume */
+       { 0x0714, 0x0000 },  /* R1812  - AIF1TX3MIX Input 3 Source */
+       { 0x0715, 0x0080 },  /* R1813  - AIF1TX3MIX Input 3 Volume */
+       { 0x0716, 0x0000 },  /* R1814  - AIF1TX3MIX Input 4 Source */
+       { 0x0717, 0x0080 },  /* R1815  - AIF1TX3MIX Input 4 Volume */
+       { 0x0718, 0x0000 },  /* R1816  - AIF1TX4MIX Input 1 Source */
+       { 0x0719, 0x0080 },  /* R1817  - AIF1TX4MIX Input 1 Volume */
+       { 0x071A, 0x0000 },  /* R1818  - AIF1TX4MIX Input 2 Source */
+       { 0x071B, 0x0080 },  /* R1819  - AIF1TX4MIX Input 2 Volume */
+       { 0x071C, 0x0000 },  /* R1820  - AIF1TX4MIX Input 3 Source */
+       { 0x071D, 0x0080 },  /* R1821  - AIF1TX4MIX Input 3 Volume */
+       { 0x071E, 0x0000 },  /* R1822  - AIF1TX4MIX Input 4 Source */
+       { 0x071F, 0x0080 },  /* R1823  - AIF1TX4MIX Input 4 Volume */
+       { 0x0720, 0x0000 },  /* R1824  - AIF1TX5MIX Input 1 Source */
+       { 0x0721, 0x0080 },  /* R1825  - AIF1TX5MIX Input 1 Volume */
+       { 0x0722, 0x0000 },  /* R1826  - AIF1TX5MIX Input 2 Source */
+       { 0x0723, 0x0080 },  /* R1827  - AIF1TX5MIX Input 2 Volume */
+       { 0x0724, 0x0000 },  /* R1828  - AIF1TX5MIX Input 3 Source */
+       { 0x0725, 0x0080 },  /* R1829  - AIF1TX5MIX Input 3 Volume */
+       { 0x0726, 0x0000 },  /* R1830  - AIF1TX5MIX Input 4 Source */
+       { 0x0727, 0x0080 },  /* R1831  - AIF1TX5MIX Input 4 Volume */
+       { 0x0728, 0x0000 },  /* R1832  - AIF1TX6MIX Input 1 Source */
+       { 0x0729, 0x0080 },  /* R1833  - AIF1TX6MIX Input 1 Volume */
+       { 0x072A, 0x0000 },  /* R1834  - AIF1TX6MIX Input 2 Source */
+       { 0x072B, 0x0080 },  /* R1835  - AIF1TX6MIX Input 2 Volume */
+       { 0x072C, 0x0000 },  /* R1836  - AIF1TX6MIX Input 3 Source */
+       { 0x072D, 0x0080 },  /* R1837  - AIF1TX6MIX Input 3 Volume */
+       { 0x072E, 0x0000 },  /* R1838  - AIF1TX6MIX Input 4 Source */
+       { 0x072F, 0x0080 },  /* R1839  - AIF1TX6MIX Input 4 Volume */
+       { 0x0730, 0x0000 },  /* R1840  - AIF1TX7MIX Input 1 Source */
+       { 0x0731, 0x0080 },  /* R1841  - AIF1TX7MIX Input 1 Volume */
+       { 0x0732, 0x0000 },  /* R1842  - AIF1TX7MIX Input 2 Source */
+       { 0x0733, 0x0080 },  /* R1843  - AIF1TX7MIX Input 2 Volume */
+       { 0x0734, 0x0000 },  /* R1844  - AIF1TX7MIX Input 3 Source */
+       { 0x0735, 0x0080 },  /* R1845  - AIF1TX7MIX Input 3 Volume */
+       { 0x0736, 0x0000 },  /* R1846  - AIF1TX7MIX Input 4 Source */
+       { 0x0737, 0x0080 },  /* R1847  - AIF1TX7MIX Input 4 Volume */
+       { 0x0738, 0x0000 },  /* R1848  - AIF1TX8MIX Input 1 Source */
+       { 0x0739, 0x0080 },  /* R1849  - AIF1TX8MIX Input 1 Volume */
+       { 0x073A, 0x0000 },  /* R1850  - AIF1TX8MIX Input 2 Source */
+       { 0x073B, 0x0080 },  /* R1851  - AIF1TX8MIX Input 2 Volume */
+       { 0x073C, 0x0000 },  /* R1852  - AIF1TX8MIX Input 3 Source */
+       { 0x073D, 0x0080 },  /* R1853  - AIF1TX8MIX Input 3 Volume */
+       { 0x073E, 0x0000 },  /* R1854  - AIF1TX8MIX Input 4 Source */
+       { 0x073F, 0x0080 },  /* R1855  - AIF1TX8MIX Input 4 Volume */
+       { 0x0740, 0x0000 },  /* R1856  - AIF2TX1MIX Input 1 Source */
+       { 0x0741, 0x0080 },  /* R1857  - AIF2TX1MIX Input 1 Volume */
+       { 0x0742, 0x0000 },  /* R1858  - AIF2TX1MIX Input 2 Source */
+       { 0x0743, 0x0080 },  /* R1859  - AIF2TX1MIX Input 2 Volume */
+       { 0x0744, 0x0000 },  /* R1860  - AIF2TX1MIX Input 3 Source */
+       { 0x0745, 0x0080 },  /* R1861  - AIF2TX1MIX Input 3 Volume */
+       { 0x0746, 0x0000 },  /* R1862  - AIF2TX1MIX Input 4 Source */
+       { 0x0747, 0x0080 },  /* R1863  - AIF2TX1MIX Input 4 Volume */
+       { 0x0748, 0x0000 },  /* R1864  - AIF2TX2MIX Input 1 Source */
+       { 0x0749, 0x0080 },  /* R1865  - AIF2TX2MIX Input 1 Volume */
+       { 0x074A, 0x0000 },  /* R1866  - AIF2TX2MIX Input 2 Source */
+       { 0x074B, 0x0080 },  /* R1867  - AIF2TX2MIX Input 2 Volume */
+       { 0x074C, 0x0000 },  /* R1868  - AIF2TX2MIX Input 3 Source */
+       { 0x074D, 0x0080 },  /* R1869  - AIF2TX2MIX Input 3 Volume */
+       { 0x074E, 0x0000 },  /* R1870  - AIF2TX2MIX Input 4 Source */
+       { 0x074F, 0x0080 },  /* R1871  - AIF2TX2MIX Input 4 Volume */
+       { 0x0780, 0x0000 },  /* R1920  - AIF3TX1MIX Input 1 Source */
+       { 0x0781, 0x0080 },  /* R1921  - AIF3TX1MIX Input 1 Volume */
+       { 0x0782, 0x0000 },  /* R1922  - AIF3TX1MIX Input 2 Source */
+       { 0x0783, 0x0080 },  /* R1923  - AIF3TX1MIX Input 2 Volume */
+       { 0x0784, 0x0000 },  /* R1924  - AIF3TX1MIX Input 3 Source */
+       { 0x0785, 0x0080 },  /* R1925  - AIF3TX1MIX Input 3 Volume */
+       { 0x0786, 0x0000 },  /* R1926  - AIF3TX1MIX Input 4 Source */
+       { 0x0787, 0x0080 },  /* R1927  - AIF3TX1MIX Input 4 Volume */
+       { 0x0788, 0x0000 },  /* R1928  - AIF3TX2MIX Input 1 Source */
+       { 0x0789, 0x0080 },  /* R1929  - AIF3TX2MIX Input 1 Volume */
+       { 0x078A, 0x0000 },  /* R1930  - AIF3TX2MIX Input 2 Source */
+       { 0x078B, 0x0080 },  /* R1931  - AIF3TX2MIX Input 2 Volume */
+       { 0x078C, 0x0000 },  /* R1932  - AIF3TX2MIX Input 3 Source */
+       { 0x078D, 0x0080 },  /* R1933  - AIF3TX2MIX Input 3 Volume */
+       { 0x078E, 0x0000 },  /* R1934  - AIF3TX2MIX Input 4 Source */
+       { 0x078F, 0x0080 },  /* R1935  - AIF3TX2MIX Input 4 Volume */
+       { 0x0880, 0x0000 },  /* R2176  - EQ1MIX Input 1 Source */
+       { 0x0881, 0x0080 },  /* R2177  - EQ1MIX Input 1 Volume */
+       { 0x0882, 0x0000 },  /* R2178  - EQ1MIX Input 2 Source */
+       { 0x0883, 0x0080 },  /* R2179  - EQ1MIX Input 2 Volume */
+       { 0x0884, 0x0000 },  /* R2180  - EQ1MIX Input 3 Source */
+       { 0x0885, 0x0080 },  /* R2181  - EQ1MIX Input 3 Volume */
+       { 0x0886, 0x0000 },  /* R2182  - EQ1MIX Input 4 Source */
+       { 0x0887, 0x0080 },  /* R2183  - EQ1MIX Input 4 Volume */
+       { 0x0888, 0x0000 },  /* R2184  - EQ2MIX Input 1 Source */
+       { 0x0889, 0x0080 },  /* R2185  - EQ2MIX Input 1 Volume */
+       { 0x088A, 0x0000 },  /* R2186  - EQ2MIX Input 2 Source */
+       { 0x088B, 0x0080 },  /* R2187  - EQ2MIX Input 2 Volume */
+       { 0x088C, 0x0000 },  /* R2188  - EQ2MIX Input 3 Source */
+       { 0x088D, 0x0080 },  /* R2189  - EQ2MIX Input 3 Volume */
+       { 0x088E, 0x0000 },  /* R2190  - EQ2MIX Input 4 Source */
+       { 0x088F, 0x0080 },  /* R2191  - EQ2MIX Input 4 Volume */
+       { 0x0890, 0x0000 },  /* R2192  - EQ3MIX Input 1 Source */
+       { 0x0891, 0x0080 },  /* R2193  - EQ3MIX Input 1 Volume */
+       { 0x0892, 0x0000 },  /* R2194  - EQ3MIX Input 2 Source */
+       { 0x0893, 0x0080 },  /* R2195  - EQ3MIX Input 2 Volume */
+       { 0x0894, 0x0000 },  /* R2196  - EQ3MIX Input 3 Source */
+       { 0x0895, 0x0080 },  /* R2197  - EQ3MIX Input 3 Volume */
+       { 0x0896, 0x0000 },  /* R2198  - EQ3MIX Input 4 Source */
+       { 0x0897, 0x0080 },  /* R2199  - EQ3MIX Input 4 Volume */
+       { 0x0898, 0x0000 },  /* R2200  - EQ4MIX Input 1 Source */
+       { 0x0899, 0x0080 },  /* R2201  - EQ4MIX Input 1 Volume */
+       { 0x089A, 0x0000 },  /* R2202  - EQ4MIX Input 2 Source */
+       { 0x089B, 0x0080 },  /* R2203  - EQ4MIX Input 2 Volume */
+       { 0x089C, 0x0000 },  /* R2204  - EQ4MIX Input 3 Source */
+       { 0x089D, 0x0080 },  /* R2205  - EQ4MIX Input 3 Volume */
+       { 0x089E, 0x0000 },  /* R2206  - EQ4MIX Input 4 Source */
+       { 0x089F, 0x0080 },  /* R2207  - EQ4MIX Input 4 Volume */
+       { 0x08C0, 0x0000 },  /* R2240  - DRC1LMIX Input 1 Source */
+       { 0x08C1, 0x0080 },  /* R2241  - DRC1LMIX Input 1 Volume */
+       { 0x08C2, 0x0000 },  /* R2242  - DRC1LMIX Input 2 Source */
+       { 0x08C3, 0x0080 },  /* R2243  - DRC1LMIX Input 2 Volume */
+       { 0x08C4, 0x0000 },  /* R2244  - DRC1LMIX Input 3 Source */
+       { 0x08C5, 0x0080 },  /* R2245  - DRC1LMIX Input 3 Volume */
+       { 0x08C6, 0x0000 },  /* R2246  - DRC1LMIX Input 4 Source */
+       { 0x08C7, 0x0080 },  /* R2247  - DRC1LMIX Input 4 Volume */
+       { 0x08C8, 0x0000 },  /* R2248  - DRC1RMIX Input 1 Source */
+       { 0x08C9, 0x0080 },  /* R2249  - DRC1RMIX Input 1 Volume */
+       { 0x08CA, 0x0000 },  /* R2250  - DRC1RMIX Input 2 Source */
+       { 0x08CB, 0x0080 },  /* R2251  - DRC1RMIX Input 2 Volume */
+       { 0x08CC, 0x0000 },  /* R2252  - DRC1RMIX Input 3 Source */
+       { 0x08CD, 0x0080 },  /* R2253  - DRC1RMIX Input 3 Volume */
+       { 0x08CE, 0x0000 },  /* R2254  - DRC1RMIX Input 4 Source */
+       { 0x08CF, 0x0080 },  /* R2255  - DRC1RMIX Input 4 Volume */
+       { 0x0900, 0x0000 },  /* R2304  - HPLP1MIX Input 1 Source */
+       { 0x0901, 0x0080 },  /* R2305  - HPLP1MIX Input 1 Volume */
+       { 0x0902, 0x0000 },  /* R2306  - HPLP1MIX Input 2 Source */
+       { 0x0903, 0x0080 },  /* R2307  - HPLP1MIX Input 2 Volume */
+       { 0x0904, 0x0000 },  /* R2308  - HPLP1MIX Input 3 Source */
+       { 0x0905, 0x0080 },  /* R2309  - HPLP1MIX Input 3 Volume */
+       { 0x0906, 0x0000 },  /* R2310  - HPLP1MIX Input 4 Source */
+       { 0x0907, 0x0080 },  /* R2311  - HPLP1MIX Input 4 Volume */
+       { 0x0908, 0x0000 },  /* R2312  - HPLP2MIX Input 1 Source */
+       { 0x0909, 0x0080 },  /* R2313  - HPLP2MIX Input 1 Volume */
+       { 0x090A, 0x0000 },  /* R2314  - HPLP2MIX Input 2 Source */
+       { 0x090B, 0x0080 },  /* R2315  - HPLP2MIX Input 2 Volume */
+       { 0x090C, 0x0000 },  /* R2316  - HPLP2MIX Input 3 Source */
+       { 0x090D, 0x0080 },  /* R2317  - HPLP2MIX Input 3 Volume */
+       { 0x090E, 0x0000 },  /* R2318  - HPLP2MIX Input 4 Source */
+       { 0x090F, 0x0080 },  /* R2319  - HPLP2MIX Input 4 Volume */
+       { 0x0910, 0x0000 },  /* R2320  - HPLP3MIX Input 1 Source */
+       { 0x0911, 0x0080 },  /* R2321  - HPLP3MIX Input 1 Volume */
+       { 0x0912, 0x0000 },  /* R2322  - HPLP3MIX Input 2 Source */
+       { 0x0913, 0x0080 },  /* R2323  - HPLP3MIX Input 2 Volume */
+       { 0x0914, 0x0000 },  /* R2324  - HPLP3MIX Input 3 Source */
+       { 0x0915, 0x0080 },  /* R2325  - HPLP3MIX Input 3 Volume */
+       { 0x0916, 0x0000 },  /* R2326  - HPLP3MIX Input 4 Source */
+       { 0x0917, 0x0080 },  /* R2327  - HPLP3MIX Input 4 Volume */
+       { 0x0918, 0x0000 },  /* R2328  - HPLP4MIX Input 1 Source */
+       { 0x0919, 0x0080 },  /* R2329  - HPLP4MIX Input 1 Volume */
+       { 0x091A, 0x0000 },  /* R2330  - HPLP4MIX Input 2 Source */
+       { 0x091B, 0x0080 },  /* R2331  - HPLP4MIX Input 2 Volume */
+       { 0x091C, 0x0000 },  /* R2332  - HPLP4MIX Input 3 Source */
+       { 0x091D, 0x0080 },  /* R2333  - HPLP4MIX Input 3 Volume */
+       { 0x091E, 0x0000 },  /* R2334  - HPLP4MIX Input 4 Source */
+       { 0x091F, 0x0080 },  /* R2335  - HPLP4MIX Input 4 Volume */
+       { 0x0940, 0x0000 },  /* R2368  - DSP1LMIX Input 1 Source */
+       { 0x0941, 0x0080 },  /* R2369  - DSP1LMIX Input 1 Volume */
+       { 0x0942, 0x0000 },  /* R2370  - DSP1LMIX Input 2 Source */
+       { 0x0943, 0x0080 },  /* R2371  - DSP1LMIX Input 2 Volume */
+       { 0x0944, 0x0000 },  /* R2372  - DSP1LMIX Input 3 Source */
+       { 0x0945, 0x0080 },  /* R2373  - DSP1LMIX Input 3 Volume */
+       { 0x0946, 0x0000 },  /* R2374  - DSP1LMIX Input 4 Source */
+       { 0x0947, 0x0080 },  /* R2375  - DSP1LMIX Input 4 Volume */
+       { 0x0948, 0x0000 },  /* R2376  - DSP1RMIX Input 1 Source */
+       { 0x0949, 0x0080 },  /* R2377  - DSP1RMIX Input 1 Volume */
+       { 0x094A, 0x0000 },  /* R2378  - DSP1RMIX Input 2 Source */
+       { 0x094B, 0x0080 },  /* R2379  - DSP1RMIX Input 2 Volume */
+       { 0x094C, 0x0000 },  /* R2380  - DSP1RMIX Input 3 Source */
+       { 0x094D, 0x0080 },  /* R2381  - DSP1RMIX Input 3 Volume */
+       { 0x094E, 0x0000 },  /* R2382  - DSP1RMIX Input 4 Source */
+       { 0x094F, 0x0080 },  /* R2383  - DSP1RMIX Input 4 Volume */
+       { 0x0950, 0x0000 },  /* R2384  - DSP1AUX1MIX Input 1 Source */
+       { 0x0958, 0x0000 },  /* R2392  - DSP1AUX2MIX Input 1 Source */
+       { 0x0960, 0x0000 },  /* R2400  - DSP1AUX3MIX Input 1 Source */
+       { 0x0968, 0x0000 },  /* R2408  - DSP1AUX4MIX Input 1 Source */
+       { 0x0970, 0x0000 },  /* R2416  - DSP1AUX5MIX Input 1 Source */
+       { 0x0978, 0x0000 },  /* R2424  - DSP1AUX6MIX Input 1 Source */
+       { 0x0980, 0x0000 },  /* R2432  - DSP2LMIX Input 1 Source */
+       { 0x0981, 0x0080 },  /* R2433  - DSP2LMIX Input 1 Volume */
+       { 0x0982, 0x0000 },  /* R2434  - DSP2LMIX Input 2 Source */
+       { 0x0983, 0x0080 },  /* R2435  - DSP2LMIX Input 2 Volume */
+       { 0x0984, 0x0000 },  /* R2436  - DSP2LMIX Input 3 Source */
+       { 0x0985, 0x0080 },  /* R2437  - DSP2LMIX Input 3 Volume */
+       { 0x0986, 0x0000 },  /* R2438  - DSP2LMIX Input 4 Source */
+       { 0x0987, 0x0080 },  /* R2439  - DSP2LMIX Input 4 Volume */
+       { 0x0988, 0x0000 },  /* R2440  - DSP2RMIX Input 1 Source */
+       { 0x0989, 0x0080 },  /* R2441  - DSP2RMIX Input 1 Volume */
+       { 0x098A, 0x0000 },  /* R2442  - DSP2RMIX Input 2 Source */
+       { 0x098B, 0x0080 },  /* R2443  - DSP2RMIX Input 2 Volume */
+       { 0x098C, 0x0000 },  /* R2444  - DSP2RMIX Input 3 Source */
+       { 0x098D, 0x0080 },  /* R2445  - DSP2RMIX Input 3 Volume */
+       { 0x098E, 0x0000 },  /* R2446  - DSP2RMIX Input 4 Source */
+       { 0x098F, 0x0080 },  /* R2447  - DSP2RMIX Input 4 Volume */
+       { 0x0990, 0x0000 },  /* R2448  - DSP2AUX1MIX Input 1 Source */
+       { 0x0998, 0x0000 },  /* R2456  - DSP2AUX2MIX Input 1 Source */
+       { 0x09A0, 0x0000 },  /* R2464  - DSP2AUX3MIX Input 1 Source */
+       { 0x09A8, 0x0000 },  /* R2472  - DSP2AUX4MIX Input 1 Source */
+       { 0x09B0, 0x0000 },  /* R2480  - DSP2AUX5MIX Input 1 Source */
+       { 0x09B8, 0x0000 },  /* R2488  - DSP2AUX6MIX Input 1 Source */
+       { 0x09C0, 0x0000 },  /* R2496  - DSP3LMIX Input 1 Source */
+       { 0x09C1, 0x0080 },  /* R2497  - DSP3LMIX Input 1 Volume */
+       { 0x09C2, 0x0000 },  /* R2498  - DSP3LMIX Input 2 Source */
+       { 0x09C3, 0x0080 },  /* R2499  - DSP3LMIX Input 2 Volume */
+       { 0x09C4, 0x0000 },  /* R2500  - DSP3LMIX Input 3 Source */
+       { 0x09C5, 0x0080 },  /* R2501  - DSP3LMIX Input 3 Volume */
+       { 0x09C6, 0x0000 },  /* R2502  - DSP3LMIX Input 4 Source */
+       { 0x09C7, 0x0080 },  /* R2503  - DSP3LMIX Input 4 Volume */
+       { 0x09C8, 0x0000 },  /* R2504  - DSP3RMIX Input 1 Source */
+       { 0x09C9, 0x0080 },  /* R2505  - DSP3RMIX Input 1 Volume */
+       { 0x09CA, 0x0000 },  /* R2506  - DSP3RMIX Input 2 Source */
+       { 0x09CB, 0x0080 },  /* R2507  - DSP3RMIX Input 2 Volume */
+       { 0x09CC, 0x0000 },  /* R2508  - DSP3RMIX Input 3 Source */
+       { 0x09CD, 0x0080 },  /* R2509  - DSP3RMIX Input 3 Volume */
+       { 0x09CE, 0x0000 },  /* R2510  - DSP3RMIX Input 4 Source */
+       { 0x09CF, 0x0080 },  /* R2511  - DSP3RMIX Input 4 Volume */
+       { 0x09D0, 0x0000 },  /* R2512  - DSP3AUX1MIX Input 1 Source */
+       { 0x09D8, 0x0000 },  /* R2520  - DSP3AUX2MIX Input 1 Source */
+       { 0x09E0, 0x0000 },  /* R2528  - DSP3AUX3MIX Input 1 Source */
+       { 0x09E8, 0x0000 },  /* R2536  - DSP3AUX4MIX Input 1 Source */
+       { 0x09F0, 0x0000 },  /* R2544  - DSP3AUX5MIX Input 1 Source */
+       { 0x09F8, 0x0000 },  /* R2552  - DSP3AUX6MIX Input 1 Source */
+       { 0x0A80, 0x0000 },  /* R2688  - ASRC1LMIX Input 1 Source */
+       { 0x0A88, 0x0000 },  /* R2696  - ASRC1RMIX Input 1 Source */
+       { 0x0A90, 0x0000 },  /* R2704  - ASRC2LMIX Input 1 Source */
+       { 0x0A98, 0x0000 },  /* R2712  - ASRC2RMIX Input 1 Source */
+       { 0x0B00, 0x0000 },  /* R2816  - ISRC1DEC1MIX Input 1 Source */
+       { 0x0B08, 0x0000 },  /* R2824  - ISRC1DEC2MIX Input 1 Source */
+       { 0x0B10, 0x0000 },  /* R2832  - ISRC1DEC3MIX Input 1 Source */
+       { 0x0B18, 0x0000 },  /* R2840  - ISRC1DEC4MIX Input 1 Source */
+       { 0x0B20, 0x0000 },  /* R2848  - ISRC1INT1MIX Input 1 Source */
+       { 0x0B28, 0x0000 },  /* R2856  - ISRC1INT2MIX Input 1 Source */
+       { 0x0B30, 0x0000 },  /* R2864  - ISRC1INT3MIX Input 1 Source */
+       { 0x0B38, 0x0000 },  /* R2872  - ISRC1INT4MIX Input 1 Source */
+       { 0x0B40, 0x0000 },  /* R2880  - ISRC2DEC1MIX Input 1 Source */
+       { 0x0B48, 0x0000 },  /* R2888  - ISRC2DEC2MIX Input 1 Source */
+       { 0x0B50, 0x0000 },  /* R2896  - ISRC2DEC3MIX Input 1 Source */
+       { 0x0B58, 0x0000 },  /* R2904  - ISRC2DEC4MIX Input 1 Source */
+       { 0x0B60, 0x0000 },  /* R2912  - ISRC2INT1MIX Input 1 Source */
+       { 0x0B68, 0x0000 },  /* R2920  - ISRC2INT2MIX Input 1 Source */
+       { 0x0B70, 0x0000 },  /* R2928  - ISRC2INT3MIX Input 1 Source */
+       { 0x0B78, 0x0000 },  /* R2936  - ISRC2INT4MIX Input 1 Source */
+       { 0x0C00, 0xA001 },  /* R3072  - GPIO CTRL 1 */
+       { 0x0C01, 0xA001 },  /* R3073  - GPIO CTRL 2 */
+       { 0x0C02, 0xA001 },  /* R3074  - GPIO CTRL 3 */
+       { 0x0C03, 0xA001 },  /* R3075  - GPIO CTRL 4 */
+       { 0x0C04, 0xA001 },  /* R3076  - GPIO CTRL 5 */
+       { 0x0C05, 0xA001 },  /* R3077  - GPIO CTRL 6 */
+       { 0x0C23, 0x4003 },  /* R3107  - Misc Pad Ctrl 1 */
+       { 0x0C24, 0x0000 },  /* R3108  - Misc Pad Ctrl 2 */
+       { 0x0C25, 0x0000 },  /* R3109  - Misc Pad Ctrl 3 */
+       { 0x0C26, 0x0000 },  /* R3110  - Misc Pad Ctrl 4 */
+       { 0x0C27, 0x0000 },  /* R3111  - Misc Pad Ctrl 5 */
+       { 0x0C28, 0x0000 },  /* R3112  - Misc GPIO 1 */
+       { 0x0D00, 0x0000 },  /* R3328  - Interrupt Status 1 */
+       { 0x0D01, 0x0000 },  /* R3329  - Interrupt Status 2 */
+       { 0x0D02, 0x0000 },  /* R3330  - Interrupt Status 3 */
+       { 0x0D03, 0x0000 },  /* R3331  - Interrupt Status 4 */
+       { 0x0D04, 0x0000 },  /* R3332  - Interrupt Raw Status 2 */
+       { 0x0D05, 0x0000 },  /* R3333  - Interrupt Raw Status 3 */
+       { 0x0D06, 0x0000 },  /* R3334  - Interrupt Raw Status 4 */
+       { 0x0D07, 0xFFFF },  /* R3335  - Interrupt Status 1 Mask */
+       { 0x0D08, 0xFFFF },  /* R3336  - Interrupt Status 2 Mask */
+       { 0x0D09, 0xFFFF },  /* R3337  - Interrupt Status 3 Mask */
+       { 0x0D0A, 0xFFFF },  /* R3338  - Interrupt Status 4 Mask */
+       { 0x0D1F, 0x0000 },  /* R3359  - Interrupt Control */
+       { 0x0D20, 0xFFFF },  /* R3360  - IRQ Debounce 1 */
+       { 0x0D21, 0xFFFF },  /* R3361  - IRQ Debounce 2 */
+       { 0x0E00, 0x0000 },  /* R3584  - FX_Ctrl */
+       { 0x0E10, 0x6318 },  /* R3600  - EQ1_1 */
+       { 0x0E11, 0x6300 },  /* R3601  - EQ1_2 */
+       { 0x0E12, 0x0FC8 },  /* R3602  - EQ1_3 */
+       { 0x0E13, 0x03FE },  /* R3603  - EQ1_4 */
+       { 0x0E14, 0x00E0 },  /* R3604  - EQ1_5 */
+       { 0x0E15, 0x1EC4 },  /* R3605  - EQ1_6 */
+       { 0x0E16, 0xF136 },  /* R3606  - EQ1_7 */
+       { 0x0E17, 0x0409 },  /* R3607  - EQ1_8 */
+       { 0x0E18, 0x04CC },  /* R3608  - EQ1_9 */
+       { 0x0E19, 0x1C9B },  /* R3609  - EQ1_10 */
+       { 0x0E1A, 0xF337 },  /* R3610  - EQ1_11 */
+       { 0x0E1B, 0x040B },  /* R3611  - EQ1_12 */
+       { 0x0E1C, 0x0CBB },  /* R3612  - EQ1_13 */
+       { 0x0E1D, 0x16F8 },  /* R3613  - EQ1_14 */
+       { 0x0E1E, 0xF7D9 },  /* R3614  - EQ1_15 */
+       { 0x0E1F, 0x040A },  /* R3615  - EQ1_16 */
+       { 0x0E20, 0x1F14 },  /* R3616  - EQ1_17 */
+       { 0x0E21, 0x058C },  /* R3617  - EQ1_18 */
+       { 0x0E22, 0x0563 },  /* R3618  - EQ1_19 */
+       { 0x0E23, 0x4000 },  /* R3619  - EQ1_20 */
+       { 0x0E26, 0x6318 },  /* R3622  - EQ2_1 */
+       { 0x0E27, 0x6300 },  /* R3623  - EQ2_2 */
+       { 0x0E28, 0x0FC8 },  /* R3624  - EQ2_3 */
+       { 0x0E29, 0x03FE },  /* R3625  - EQ2_4 */
+       { 0x0E2A, 0x00E0 },  /* R3626  - EQ2_5 */
+       { 0x0E2B, 0x1EC4 },  /* R3627  - EQ2_6 */
+       { 0x0E2C, 0xF136 },  /* R3628  - EQ2_7 */
+       { 0x0E2D, 0x0409 },  /* R3629  - EQ2_8 */
+       { 0x0E2E, 0x04CC },  /* R3630  - EQ2_9 */
+       { 0x0E2F, 0x1C9B },  /* R3631  - EQ2_10 */
+       { 0x0E30, 0xF337 },  /* R3632  - EQ2_11 */
+       { 0x0E31, 0x040B },  /* R3633  - EQ2_12 */
+       { 0x0E32, 0x0CBB },  /* R3634  - EQ2_13 */
+       { 0x0E33, 0x16F8 },  /* R3635  - EQ2_14 */
+       { 0x0E34, 0xF7D9 },  /* R3636  - EQ2_15 */
+       { 0x0E35, 0x040A },  /* R3637  - EQ2_16 */
+       { 0x0E36, 0x1F14 },  /* R3638  - EQ2_17 */
+       { 0x0E37, 0x058C },  /* R3639  - EQ2_18 */
+       { 0x0E38, 0x0563 },  /* R3640  - EQ2_19 */
+       { 0x0E39, 0x4000 },  /* R3641  - EQ2_20 */
+       { 0x0E3C, 0x6318 },  /* R3644  - EQ3_1 */
+       { 0x0E3D, 0x6300 },  /* R3645  - EQ3_2 */
+       { 0x0E3E, 0x0FC8 },  /* R3646  - EQ3_3 */
+       { 0x0E3F, 0x03FE },  /* R3647  - EQ3_4 */
+       { 0x0E40, 0x00E0 },  /* R3648  - EQ3_5 */
+       { 0x0E41, 0x1EC4 },  /* R3649  - EQ3_6 */
+       { 0x0E42, 0xF136 },  /* R3650  - EQ3_7 */
+       { 0x0E43, 0x0409 },  /* R3651  - EQ3_8 */
+       { 0x0E44, 0x04CC },  /* R3652  - EQ3_9 */
+       { 0x0E45, 0x1C9B },  /* R3653  - EQ3_10 */
+       { 0x0E46, 0xF337 },  /* R3654  - EQ3_11 */
+       { 0x0E47, 0x040B },  /* R3655  - EQ3_12 */
+       { 0x0E48, 0x0CBB },  /* R3656  - EQ3_13 */
+       { 0x0E49, 0x16F8 },  /* R3657  - EQ3_14 */
+       { 0x0E4A, 0xF7D9 },  /* R3658  - EQ3_15 */
+       { 0x0E4B, 0x040A },  /* R3659  - EQ3_16 */
+       { 0x0E4C, 0x1F14 },  /* R3660  - EQ3_17 */
+       { 0x0E4D, 0x058C },  /* R3661  - EQ3_18 */
+       { 0x0E4E, 0x0563 },  /* R3662  - EQ3_19 */
+       { 0x0E4F, 0x4000 },  /* R3663  - EQ3_20 */
+       { 0x0E52, 0x6318 },  /* R3666  - EQ4_1 */
+       { 0x0E53, 0x6300 },  /* R3667  - EQ4_2 */
+       { 0x0E54, 0x0FC8 },  /* R3668  - EQ4_3 */
+       { 0x0E55, 0x03FE },  /* R3669  - EQ4_4 */
+       { 0x0E56, 0x00E0 },  /* R3670  - EQ4_5 */
+       { 0x0E57, 0x1EC4 },  /* R3671  - EQ4_6 */
+       { 0x0E58, 0xF136 },  /* R3672  - EQ4_7 */
+       { 0x0E59, 0x0409 },  /* R3673  - EQ4_8 */
+       { 0x0E5A, 0x04CC },  /* R3674  - EQ4_9 */
+       { 0x0E5B, 0x1C9B },  /* R3675  - EQ4_10 */
+       { 0x0E5C, 0xF337 },  /* R3676  - EQ4_11 */
+       { 0x0E5D, 0x040B },  /* R3677  - EQ4_12 */
+       { 0x0E5E, 0x0CBB },  /* R3678  - EQ4_13 */
+       { 0x0E5F, 0x16F8 },  /* R3679  - EQ4_14 */
+       { 0x0E60, 0xF7D9 },  /* R3680  - EQ4_15 */
+       { 0x0E61, 0x040A },  /* R3681  - EQ4_16 */
+       { 0x0E62, 0x1F14 },  /* R3682  - EQ4_17 */
+       { 0x0E63, 0x058C },  /* R3683  - EQ4_18 */
+       { 0x0E64, 0x0563 },  /* R3684  - EQ4_19 */
+       { 0x0E65, 0x4000 },  /* R3685  - EQ4_20 */
+       { 0x0E80, 0x0018 },  /* R3712  - DRC1 ctrl1 */
+       { 0x0E81, 0x0933 },  /* R3713  - DRC1 ctrl2 */
+       { 0x0E82, 0x0018 },  /* R3714  - DRC1 ctrl3 */
+       { 0x0E83, 0x0000 },  /* R3715  - DRC1 ctrl4 */
+       { 0x0E84, 0x0000 },  /* R3716  - DRC1 ctrl5 */
+       { 0x0EC0, 0x0000 },  /* R3776  - HPLPF1_1 */
+       { 0x0EC1, 0x0000 },  /* R3777  - HPLPF1_2 */
+       { 0x0EC4, 0x0000 },  /* R3780  - HPLPF2_1 */
+       { 0x0EC5, 0x0000 },  /* R3781  - HPLPF2_2 */
+       { 0x0EC8, 0x0000 },  /* R3784  - HPLPF3_1 */
+       { 0x0EC9, 0x0000 },  /* R3785  - HPLPF3_2 */
+       { 0x0ECC, 0x0000 },  /* R3788  - HPLPF4_1 */
+       { 0x0ECD, 0x0000 },  /* R3789  - HPLPF4_2 */
 };
index 42d9039a49e93863ba3adfb046a5b8d1f43a8515..8be5dae83caea91ed2a9b8addcf7844084ea50ea 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/gcd.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/fixed.h>
 #include <linux/slab.h>
@@ -51,6 +50,7 @@ struct wm5100_fll {
 
 /* codec private data */
 struct wm5100_priv {
+       struct regmap *regmap;
        struct snd_soc_codec *codec;
 
        struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
@@ -204,17 +204,15 @@ static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
        }
 }
 
-static int wm5100_reset(struct snd_soc_codec *codec)
+static int wm5100_reset(struct wm5100_priv *wm5100)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-
        if (wm5100->pdata.reset) {
                gpio_set_value_cansleep(wm5100->pdata.reset, 0);
                gpio_set_value_cansleep(wm5100->pdata.reset, 1);
 
                return 0;
        } else {
-               return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0);
+               return regmap_write(wm5100->regmap, WM5100_SOFTWARE_RESET, 0);
        }
 }
 
@@ -1375,7 +1373,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
                                msleep(2);
                        }
 
-                       codec->cache_only = false;
+                       regcache_cache_only(wm5100->regmap, false);
 
                        switch (wm5100->rev) {
                        case 0:
@@ -1399,7 +1397,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
                                break;
                        }
 
-                       snd_soc_cache_sync(codec);
+                       regcache_sync(wm5100->regmap);
                }
                break;
 
@@ -1662,7 +1660,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops wm5100_dai_ops = {
+static const struct snd_soc_dai_ops wm5100_dai_ops = {
        .set_fmt = wm5100_set_fmt,
        .hw_params = wm5100_hw_params,
 };
@@ -1993,6 +1991,9 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        else
                timeout = 50;
 
+       snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
+                           WM5100_SYSCLK_ENA);
+
        /* Poll for the lock; will use interrupt when we can test */
        for (i = 0; i < timeout; i++) {
                if (i2c->irq) {
@@ -2350,24 +2351,22 @@ static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
 static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-       struct snd_soc_codec *codec = wm5100->codec;
 
-       snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
-                           WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
+       regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+                          WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
 }
 
 static int wm5100_gpio_direction_out(struct gpio_chip *chip,
                                     unsigned offset, int value)
 {
        struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-       struct snd_soc_codec *codec = wm5100->codec;
        int val, ret;
 
        val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
 
-       ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
-                                 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
-                                 WM5100_GP1_LVL, val);
+       ret = regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+                                WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
+                                WM5100_GP1_LVL, val);
        if (ret < 0)
                return ret;
        else
@@ -2377,25 +2376,24 @@ static int wm5100_gpio_direction_out(struct gpio_chip *chip,
 static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-       struct snd_soc_codec *codec = wm5100->codec;
+       unsigned int reg;
        int ret;
 
-       ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
+       ret = regmap_read(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, &reg);
        if (ret < 0)
                return ret;
 
-       return (ret & WM5100_GP1_LVL) != 0;
+       return (reg & WM5100_GP1_LVL) != 0;
 }
 
 static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
 {
        struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
-       struct snd_soc_codec *codec = wm5100->codec;
 
-       return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
-                                  WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
-                                  (1 << WM5100_GP1_FN_SHIFT) |
-                                  (1 << WM5100_GP1_DIR_SHIFT));
+       return regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
+                                 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
+                                 (1 << WM5100_GP1_FN_SHIFT) |
+                                 (1 << WM5100_GP1_DIR_SHIFT));
 }
 
 static struct gpio_chip wm5100_template_chip = {
@@ -2408,14 +2406,14 @@ static struct gpio_chip wm5100_template_chip = {
        .can_sleep              = 1,
 };
 
-static void wm5100_init_gpio(struct snd_soc_codec *codec)
+static void wm5100_init_gpio(struct i2c_client *i2c)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
        int ret;
 
        wm5100->gpio_chip = wm5100_template_chip;
        wm5100->gpio_chip.ngpio = 6;
-       wm5100->gpio_chip.dev = codec->dev;
+       wm5100->gpio_chip.dev = &i2c->dev;
 
        if (wm5100->pdata.gpio_base)
                wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
@@ -2424,24 +2422,24 @@ static void wm5100_init_gpio(struct snd_soc_codec *codec)
 
        ret = gpiochip_add(&wm5100->gpio_chip);
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret);
 }
 
-static void wm5100_free_gpio(struct snd_soc_codec *codec)
+static void wm5100_free_gpio(struct i2c_client *i2c)
 {
-       struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+       struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
        int ret;
 
        ret = gpiochip_remove(&wm5100->gpio_chip);
        if (ret != 0)
-               dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+               dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret);
 }
 #else
-static void wm5100_init_gpio(struct snd_soc_codec *codec)
+static void wm5100_init_gpio(struct i2c_client *i2c)
 {
 }
 
-static void wm5100_free_gpio(struct snd_soc_codec *codec)
+static void wm5100_free_gpio(struct i2c_client *i2c)
 {
 }
 #endif
@@ -2453,131 +2451,21 @@ static int wm5100_probe(struct snd_soc_codec *codec)
        int ret, i, irq_flags;
 
        wm5100->codec = codec;
+       codec->control_data = wm5100->regmap;
 
-       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
        }
 
-       for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
-               wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
-
-       ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
-                                wm5100->core_supplies);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to request core supplies: %d\n",
-                       ret);
-               return ret;
-       }
-
-       wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
-       if (IS_ERR(wm5100->cpvdd)) {
-               ret = PTR_ERR(wm5100->cpvdd);
-               dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
-               goto err_core;
-       }
-
-       wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
-       if (IS_ERR(wm5100->dbvdd2)) {
-               ret = PTR_ERR(wm5100->dbvdd2);
-               dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
-               goto err_cpvdd;
-       }
-
-       wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
-       if (IS_ERR(wm5100->dbvdd3)) {
-               ret = PTR_ERR(wm5100->dbvdd3);
-               dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
-               goto err_dbvdd2;
-       }
-
-       ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
-                                   wm5100->core_supplies);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable core supplies: %d\n",
-                       ret);
-               goto err_dbvdd3;
-       }
+       regcache_cache_only(wm5100->regmap, true);
 
-       if (wm5100->pdata.ldo_ena) {
-               ret = gpio_request_one(wm5100->pdata.ldo_ena,
-                                      GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
-               if (ret < 0) {
-                       dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
-                               wm5100->pdata.ldo_ena, ret);
-                       goto err_enable;
-               }
-               msleep(2);
-       }
-
-       if (wm5100->pdata.reset) {
-               ret = gpio_request_one(wm5100->pdata.reset,
-                                      GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
-               if (ret < 0) {
-                       dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
-                               wm5100->pdata.reset, ret);
-                       goto err_ldo;
-               }
-       }
-
-       ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to read ID register\n");
-               goto err_reset;
-       }
-       switch (ret) {
-       case 0x8997:
-       case 0x5100:
-               break;
-
-       default:
-               dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
-               ret = -EINVAL;
-               goto err_reset;
-       }
-
-       ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to read revision register\n");
-               goto err_reset;
-       }
-       wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
-
-       dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
-
-       ret = wm5100_reset(codec);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
-               goto err_reset;
-       }
-
-       codec->cache_only = true;
-
-       wm5100_init_gpio(codec);
 
        for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
                snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
                                    WM5100_OUT_VU);
 
-       for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
-               snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
-                                   WM5100_IN1_MODE_MASK |
-                                   WM5100_IN1_DMIC_SUP_MASK,
-                                   (wm5100->pdata.in_mode[i] <<
-                                    WM5100_IN1_MODE_SHIFT) |
-                                   (wm5100->pdata.dmic_sup[i] <<
-                                    WM5100_IN1_DMIC_SUP_SHIFT));
-       }
-
-       for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
-               if (!wm5100->pdata.gpio_defaults[i])
-                       continue;
-
-               snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
-                             wm5100->pdata.gpio_defaults[i]);
-       }
-
        /* Don't debounce interrupts to support use of SYSCLK only */
        snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
        snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
@@ -2662,29 +2550,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
 err_gpio:
        if (i2c->irq)
                free_irq(i2c->irq, codec);
-       wm5100_free_gpio(codec);
-err_reset:
-       if (wm5100->pdata.reset) {
-               gpio_set_value_cansleep(wm5100->pdata.reset, 1);
-               gpio_free(wm5100->pdata.reset);
-       }
-err_ldo:
-       if (wm5100->pdata.ldo_ena) {
-               gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
-               gpio_free(wm5100->pdata.ldo_ena);
-       }
-err_enable:
-       regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
-                              wm5100->core_supplies);
-err_dbvdd3:
-       regulator_put(wm5100->dbvdd3);
-err_dbvdd2:
-       regulator_put(wm5100->dbvdd2);
-err_cpvdd:
-       regulator_put(wm5100->cpvdd);
-err_core:
-       regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
-                           wm5100->core_supplies);
 
        return ret;
 }
@@ -2700,20 +2565,6 @@ static int wm5100_remove(struct snd_soc_codec *codec)
        }
        if (i2c->irq)
                free_irq(i2c->irq, codec);
-       wm5100_free_gpio(codec);
-       if (wm5100->pdata.reset) {
-               gpio_set_value_cansleep(wm5100->pdata.reset, 1);
-               gpio_free(wm5100->pdata.reset);
-       }
-       if (wm5100->pdata.ldo_ena) {
-               gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
-               gpio_free(wm5100->pdata.ldo_ena);
-       }
-       regulator_put(wm5100->dbvdd3);
-       regulator_put(wm5100->dbvdd2);
-       regulator_put(wm5100->cpvdd);
-       regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
-                           wm5100->core_supplies);
        return 0;
 }
 
@@ -2733,14 +2584,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
        .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
        .dapm_routes = wm5100_dapm_routes,
        .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
+};
 
-       .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
-       .reg_word_size = sizeof(u16),
-       .compress_type = SND_SOC_RBTREE_COMPRESSION,
-       .reg_cache_default = wm5100_reg_defaults,
+static const struct regmap_config wm5100_regmap = {
+       .reg_bits = 16,
+       .val_bits = 16,
 
-       .volatile_register = wm5100_volatile_register,
-       .readable_register = wm5100_readable_register,
+       .max_register = WM5100_MAX_REGISTER,
+       .reg_defaults = wm5100_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm5100_reg_defaults),
+       .volatile_reg = wm5100_volatile_register,
+       .readable_reg = wm5100_readable_register,
+       .cache_type = REGCACHE_RBTREE,
 };
 
 static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
@@ -2748,12 +2603,22 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 {
        struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
        struct wm5100_priv *wm5100;
+       unsigned int reg;
        int ret, i;
 
-       wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
+       wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv),
+                             GFP_KERNEL);
        if (wm5100 == NULL)
                return -ENOMEM;
 
+       wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap);
+       if (IS_ERR(wm5100->regmap)) {
+               ret = PTR_ERR(wm5100->regmap);
+               dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                       ret);
+               goto err;
+       }
+
        for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
                init_completion(&wm5100->fll[i].lock);
 
@@ -2762,21 +2627,178 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, wm5100);
 
+       for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
+               wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
+
+       ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
+                                wm5100->core_supplies);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
+                       ret);
+               goto err_regmap;
+       }
+
+       wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
+       if (IS_ERR(wm5100->cpvdd)) {
+               ret = PTR_ERR(wm5100->cpvdd);
+               dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
+               goto err_core;
+       }
+
+       wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
+       if (IS_ERR(wm5100->dbvdd2)) {
+               ret = PTR_ERR(wm5100->dbvdd2);
+               dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
+               goto err_cpvdd;
+       }
+
+       wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
+       if (IS_ERR(wm5100->dbvdd3)) {
+               ret = PTR_ERR(wm5100->dbvdd3);
+               dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
+               goto err_dbvdd2;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
+                                   wm5100->core_supplies);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
+                       ret);
+               goto err_dbvdd3;
+       }
+
+       if (wm5100->pdata.ldo_ena) {
+               ret = gpio_request_one(wm5100->pdata.ldo_ena,
+                                      GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
+               if (ret < 0) {
+                       dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
+                               wm5100->pdata.ldo_ena, ret);
+                       goto err_enable;
+               }
+               msleep(2);
+       }
+
+       if (wm5100->pdata.reset) {
+               ret = gpio_request_one(wm5100->pdata.reset,
+                                      GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
+               if (ret < 0) {
+                       dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
+                               wm5100->pdata.reset, ret);
+                       goto err_ldo;
+               }
+       }
+
+       ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read ID register\n");
+               goto err_reset;
+       }
+       switch (reg) {
+       case 0x8997:
+       case 0x5100:
+               break;
+
+       default:
+               dev_err(&i2c->dev, "Device is not a WM5100, ID is %x\n", reg);
+               ret = -EINVAL;
+               goto err_reset;
+       }
+
+       ret = regmap_read(wm5100->regmap, WM5100_DEVICE_REVISION, &reg);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read revision register\n");
+               goto err_reset;
+       }
+       wm5100->rev = reg & WM5100_DEVICE_REVISION_MASK;
+
+       dev_info(&i2c->dev, "revision %c\n", wm5100->rev + 'A');
+
+       ret = wm5100_reset(wm5100);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to issue reset\n");
+               goto err_reset;
+       }
+
+       wm5100_init_gpio(i2c);
+
+       for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
+               if (!wm5100->pdata.gpio_defaults[i])
+                       continue;
+
+               regmap_write(wm5100->regmap, WM5100_GPIO_CTRL_1 + i,
+                            wm5100->pdata.gpio_defaults[i]);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
+               regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL,
+                                  WM5100_IN1_MODE_MASK |
+                                  WM5100_IN1_DMIC_SUP_MASK,
+                                  (wm5100->pdata.in_mode[i] <<
+                                   WM5100_IN1_MODE_SHIFT) |
+                                  (wm5100->pdata.dmic_sup[i] <<
+                                   WM5100_IN1_DMIC_SUP_SHIFT));
+       }
+
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm5100, wm5100_dai,
                                     ARRAY_SIZE(wm5100_dai));
        if (ret < 0) {
                dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
-               kfree(wm5100);
+               goto err_reset;
        }
 
        return ret;
+
+err_reset:
+       wm5100_free_gpio(i2c);
+       if (wm5100->pdata.reset) {
+               gpio_set_value_cansleep(wm5100->pdata.reset, 1);
+               gpio_free(wm5100->pdata.reset);
+       }
+err_ldo:
+       if (wm5100->pdata.ldo_ena) {
+               gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
+               gpio_free(wm5100->pdata.ldo_ena);
+       }
+err_enable:
+       regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
+                              wm5100->core_supplies);
+err_dbvdd3:
+       regulator_put(wm5100->dbvdd3);
+err_dbvdd2:
+       regulator_put(wm5100->dbvdd2);
+err_cpvdd:
+       regulator_put(wm5100->cpvdd);
+err_core:
+       regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
+                           wm5100->core_supplies);
+err_regmap:
+       regmap_exit(wm5100->regmap);
+err:
+       return ret;
 }
 
 static __devexit int wm5100_i2c_remove(struct i2c_client *client)
 {
+       struct wm5100_priv *wm5100 = i2c_get_clientdata(client);
+
        snd_soc_unregister_codec(&client->dev);
-       kfree(i2c_get_clientdata(client));
+       wm5100_free_gpio(client);
+       if (wm5100->pdata.reset) {
+               gpio_set_value_cansleep(wm5100->pdata.reset, 1);
+               gpio_free(wm5100->pdata.reset);
+       }
+       if (wm5100->pdata.ldo_ena) {
+               gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
+               gpio_free(wm5100->pdata.ldo_ena);
+       }
+       regulator_put(wm5100->dbvdd3);
+       regulator_put(wm5100->dbvdd2);
+       regulator_put(wm5100->cpvdd);
+       regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
+                           wm5100->core_supplies);
+       regmap_exit(wm5100->regmap);
+
        return 0;
 }
 
index 970759636bdc508b10603aa7fd8da6765043ad7c..25cb6016f9d7f37ce7eb855c66930ba27f06bd90 100644 (file)
@@ -15,6 +15,7 @@
 #define WM5100_ASOC_H
 
 #include <sound/soc.h>
+#include <linux/regmap.h>
 
 int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
 
@@ -5147,9 +5148,9 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
 #define WM5100_DSP3_ZM_END_SHIFT                     0  /* DSP3_ZM_END - [15:0] */
 #define WM5100_DSP3_ZM_END_WIDTH                    16  /* DSP3_ZM_END - [15:0] */
 
-int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg);
-int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg);
+bool wm5100_readable_register(struct device *dev, unsigned int reg);
+bool wm5100_volatile_register(struct device *dev, unsigned int reg);
 
-extern u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1];
+extern struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT];
 
 #endif
index 35f3ad83dfb6670013652772268385b75cda481a..3f1ed5f5ccf4208a147606f60bb9b66e0ac42c41 100644 (file)
@@ -1511,7 +1511,7 @@ EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
                        SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8350_dai_ops = {
+static const struct snd_soc_dai_ops wm8350_dai_ops = {
         .hw_params     = wm8350_pcm_hw_params,
         .digital_mute  = wm8350_mute,
         .trigger       = wm8350_pcm_trigger,
@@ -1711,17 +1711,7 @@ static struct platform_driver wm8350_codec_driver = {
        .remove = __devexit_p(wm8350_remove),
 };
 
-static __init int wm8350_init(void)
-{
-       return platform_driver_register(&wm8350_codec_driver);
-}
-module_init(wm8350_init);
-
-static __exit void wm8350_exit(void)
-{
-       platform_driver_unregister(&wm8350_codec_driver);
-}
-module_exit(wm8350_exit);
+module_platform_driver(wm8350_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM8350 driver");
 MODULE_AUTHOR("Liam Girdwood");
index dc13be2a09c52b64b95aee07eb9d4061485c8b56..a1173eb7936d46071d0c82bf93ff50961165532e 100644 (file)
@@ -766,8 +766,8 @@ SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0,
        NULL, 0),
 
 /* MICBIAS */
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8400_POWER_MANAGEMENT_1,
-       WM8400_MIC1BIAS_ENA_SHIFT, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8400_POWER_MANAGEMENT_1,
+                   WM8400_MIC1BIAS_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_OUTPUT("LON"),
 SND_SOC_DAPM_OUTPUT("LOP"),
@@ -1059,7 +1059,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
        wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n);
 
        reg = wm8400_read(codec, WM8400_FLL_CONTROL_4);
-       reg &= WM8400_FLL_OUTDIV_MASK;
+       reg &= ~WM8400_FLL_OUTDIV_MASK;
        reg |= factors.outdiv;
        wm8400_write(codec, WM8400_FLL_CONTROL_4, reg);
 
@@ -1316,7 +1316,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
 #define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8400_dai_ops = {
+static const struct snd_soc_dai_ops wm8400_dai_ops = {
        .hw_params = wm8400_hw_params,
        .digital_mute = wm8400_mute,
        .set_fmt = wm8400_set_dai_fmt,
@@ -1477,17 +1477,7 @@ static struct platform_driver wm8400_codec_driver = {
        .remove = __devexit_p(wm8400_remove),
 };
 
-static __init int wm8400_init(void)
-{
-       return platform_driver_register(&wm8400_codec_driver);
-}
-module_init(wm8400_init);
-
-static __exit void wm8400_exit(void)
-{
-       platform_driver_unregister(&wm8400_codec_driver);
-}
-module_exit(wm8400_exit);
+module_platform_driver(wm8400_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM8400 driver");
 MODULE_AUTHOR("Mark Brown");
index 07c9cc759e97706a308d0489bac40a0f0482fdd1..3a655719ba2c40e16098f03559b059e96ec98da5 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -509,7 +508,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
 #define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8510_dai_ops = {
+static const struct snd_soc_dai_ops wm8510_dai_ops = {
        .hw_params      = wm8510_pcm_hw_params,
        .digital_mute   = wm8510_mute,
        .set_fmt        = wm8510_set_dai_fmt,
index db7a6819499fa59a1597f5c93066149e08d3c2ac..0c89f8e2daafe9692e18545c48b119747b556173 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -365,7 +364,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
 #define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8523_dai_ops = {
+static const struct snd_soc_dai_ops wm8523_dai_ops = {
        .startup        = wm8523_startup,
        .hw_params      = wm8523_hw_params,
        .set_sysclk     = wm8523_set_dai_sysclk,
index 8212b3c8bfdd90da61cfe426344c13aa6deadae8..764b2bf80a7192dd3a3d2d48c5d97e3e1ba1f78f 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -776,7 +775,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
 #define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
+static const struct snd_soc_dai_ops wm8580_dai_ops_playback = {
        .set_sysclk     = wm8580_set_sysclk,
        .hw_params      = wm8580_paif_hw_params,
        .set_fmt        = wm8580_set_paif_dai_fmt,
@@ -785,7 +784,7 @@ static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
        .digital_mute   = wm8580_digital_mute,
 };
 
-static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
+static const struct snd_soc_dai_ops wm8580_dai_ops_capture = {
        .set_sysclk     = wm8580_set_sysclk,
        .hw_params      = wm8580_paif_hw_params,
        .set_fmt        = wm8580_set_paif_dai_fmt,
index 076bdb9930a15d6d50c4edd3d6009a7fad801089..760080e43015859e38aaa672b62aded1031f0bdd 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -318,7 +317,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
 #define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8711_ops = {
+static const struct snd_soc_dai_ops wm8711_ops = {
        .prepare = wm8711_pcm_prepare,
        .hw_params = wm8711_hw_params,
        .shutdown = wm8711_shutdown,
index 7488082851191ce120a8a66fd8704b53613b8189..fad90a35f3999cafbee0c8e683f16b6f1e35558b 100644 (file)
@@ -67,17 +67,7 @@ static struct platform_driver wm8727_codec_driver = {
        .remove = __devexit_p(wm8727_remove),
 };
 
-static int __init wm8727_init(void)
-{
-       return platform_driver_register(&wm8727_codec_driver);
-}
-module_init(wm8727_init);
-
-static void __exit wm8727_exit(void)
-{
-       platform_driver_unregister(&wm8727_codec_driver);
-}
-module_exit(wm8727_exit);
+module_platform_driver(wm8727_codec_driver);
 
 MODULE_DESCRIPTION("ASoC wm8727 driver");
 MODULE_AUTHOR("Neil Jones");
index 04b027efd5c003df25769eb92e3ff7a74317a975..085c2f81d8c2635952d97b85524664c3f047e73d 100644 (file)
@@ -196,7 +196,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
 #define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8728_dai_ops = {
+static const struct snd_soc_dai_ops wm8728_dai_ops = {
        .hw_params      = wm8728_hw_params,
        .digital_mute   = wm8728_mute,
        .set_fmt        = wm8728_set_dai_fmt,
index a7c9ae17fc7eb0e743a8dbfb27db88fea58a456e..c18dee06f29c12f1e49cd8eddb369ab816e57f4e 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/of_device.h>
@@ -465,7 +464,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8731_dai_ops = {
+static const struct snd_soc_dai_ops wm8731_dai_ops = {
        .hw_params      = wm8731_hw_params,
        .digital_mute   = wm8731_mute,
        .set_sysclk     = wm8731_set_dai_sysclk,
@@ -554,9 +553,6 @@ static int wm8731_probe(struct snd_soc_codec *codec)
        /* Disable bypass path by default */
        snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
 
-       snd_soc_add_controls(codec, wm8731_snd_controls,
-                            ARRAY_SIZE(wm8731_snd_controls));
-
        /* Regulators will have been enabled by bias management */
        regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
 
@@ -596,6 +592,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
        .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
        .dapm_routes = wm8731_intercon,
        .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
+       .controls =     wm8731_snd_controls,
+       .num_controls = ARRAY_SIZE(wm8731_snd_controls),
 };
 
 static const struct of_device_id wm8731_of_match[] = {
index f6aef58845c2dc31880529cdaa9510a96735e334..c13e4f7809cfd17632e34bd56d5a44a6a2f41d99 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
@@ -521,7 +520,7 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec,
 #define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8737_dai_ops = {
+static const struct snd_soc_dai_ops wm8737_dai_ops = {
        .hw_params      = wm8737_hw_params,
        .set_sysclk     = wm8737_set_dai_sysclk,
        .set_fmt        = wm8737_set_dai_fmt,
index 57ad22aacc516dc17e18042a98712266f761afa3..bf471dc57114db356585b06ac3c8e3642ecf8c82 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -382,7 +381,7 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
 #define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8741_dai_ops = {
+static const struct snd_soc_dai_ops wm8741_dai_ops = {
        .startup        = wm8741_startup,
        .hw_params      = wm8741_hw_params,
        .set_sysclk     = wm8741_set_dai_sysclk,
index ca75a818070804610d0b7c0d10554e48cbf2f1bd..b312fccbf67a0a4befb4cb2b84080ba43b8d6364 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -643,7 +642,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
 #define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8750_dai_ops = {
+static const struct snd_soc_dai_ops wm8750_dai_ops = {
        .hw_params      = wm8750_pcm_hw_params,
        .digital_mute   = wm8750_mute,
        .set_fmt        = wm8750_set_dai_fmt,
index 3a629d0d690ed1fbe8129f096e0edf492faf9eb2..dc3153852d8a476478330fc2c7552399699343c1 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/of_device.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -486,7 +485,7 @@ SND_SOC_DAPM_INPUT("MIC2"),
 SND_SOC_DAPM_VMID("VREF"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8753_dapm_routes[] = {
        /* left mixer */
        {"Left Mixer", "Left Playback Switch", "Left DAC"},
        {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -640,17 +639,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
        {"ACOP", NULL, "ALC Mixer"},
 };
 
-static int wm8753_add_widgets(struct snd_soc_codec *codec)
-{
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-       snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
-                                 ARRAY_SIZE(wm8753_dapm_widgets));
-       snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-       return 0;
-}
-
 /* PLL divisors */
 struct _pll_div {
        u32 div2:1;
@@ -1326,7 +1314,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
  * 3. Voice disabled - HIFI over HIFI
  * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
  */
-static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
+static const struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
        .hw_params      = wm8753_i2s_hw_params,
        .digital_mute   = wm8753_mute,
        .set_fmt        = wm8753_hifi_set_dai_fmt,
@@ -1335,7 +1323,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
        .set_sysclk     = wm8753_set_dai_sysclk,
 };
 
-static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
+static const struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
        .hw_params      = wm8753_pcm_hw_params,
        .digital_mute   = wm8753_mute,
        .set_fmt        = wm8753_voice_set_dai_fmt,
@@ -1467,10 +1455,6 @@ static int wm8753_probe(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
        snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
 
-       snd_soc_add_controls(codec, wm8753_snd_controls,
-                            ARRAY_SIZE(wm8753_snd_controls));
-       wm8753_add_widgets(codec);
-
        return 0;
 }
 
@@ -1492,6 +1476,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
        .reg_cache_size = ARRAY_SIZE(wm8753_reg),
        .reg_word_size = sizeof(u16),
        .reg_cache_default = wm8753_reg,
+
+       .controls = wm8753_snd_controls,
+       .num_controls = ARRAY_SIZE(wm8753_snd_controls),
+       .dapm_widgets = wm8753_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets),
+       .dapm_routes = wm8753_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes),
 };
 
 static const struct of_device_id wm8753_of_match[] = {
index aa05e6507f844a2ac90c970e939a92efc9de0ff7..391c385ec43ef1eda839b9b5d7d511ceca28b236 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/delay.h>
 #include <linux/of_device.h>
 #include <linux/pm.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -528,7 +527,7 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec,
 #define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8770_dai_ops = {
+static const struct snd_soc_dai_ops wm8770_dai_ops = {
        .digital_mute = wm8770_mute,
        .hw_params = wm8770_hw_params,
        .set_fmt = wm8770_set_fmt,
index bfdc52370ad02de96bd9cf1859614db91e682949..af542a2f5941410a6b6168c6e96038ba1aec30bc 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/of_device.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -327,14 +326,14 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
 #define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8776_dac_ops = {
+static const struct snd_soc_dai_ops wm8776_dac_ops = {
        .digital_mute   = wm8776_mute,
        .hw_params      = wm8776_hw_params,
        .set_fmt        = wm8776_set_fmt,
        .set_sysclk     = wm8776_set_sysclk,
 };
 
-static struct snd_soc_dai_ops wm8776_adc_ops = {
+static const struct snd_soc_dai_ops wm8776_adc_ops = {
        .hw_params      = wm8776_hw_params,
        .set_fmt        = wm8776_set_fmt,
        .set_sysclk     = wm8776_set_sysclk,
@@ -392,7 +391,6 @@ static int wm8776_resume(struct snd_soc_codec *codec)
 static int wm8776_probe(struct snd_soc_codec *codec)
 {
        struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
        int ret = 0;
 
        ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
@@ -414,12 +412,6 @@ static int wm8776_probe(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
        snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
 
-       snd_soc_add_controls(codec, wm8776_snd_controls,
-                            ARRAY_SIZE(wm8776_snd_controls));
-       snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets,
-                                 ARRAY_SIZE(wm8776_dapm_widgets));
-       snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
-
        return ret;
 }
 
@@ -439,6 +431,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
        .reg_cache_size = ARRAY_SIZE(wm8776_reg),
        .reg_word_size = sizeof(u16),
        .reg_cache_default = wm8776_reg,
+
+       .controls = wm8776_snd_controls,
+       .num_controls = ARRAY_SIZE(wm8776_snd_controls),
+       .dapm_widgets = wm8776_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets),
+       .dapm_routes = routes,
+       .num_dapm_routes = ARRAY_SIZE(routes),
 };
 
 static const struct of_device_id wm8776_of_match[] = {
index f2ced71328b0a6cc7ee073a4099fd6fd6afe5b15..3fdea98f732ec3814dd96f2150ffa5fe4c6b4349 100644 (file)
@@ -63,17 +63,7 @@ static struct platform_driver wm8782_codec_driver = {
        .remove = __devexit_p(wm8782_remove),
 };
 
-static int __init wm8782_init(void)
-{
-       return platform_driver_register(&wm8782_codec_driver);
-}
-module_init(wm8782_init);
-
-static void __exit wm8782_exit(void)
-{
-       platform_driver_unregister(&wm8782_codec_driver);
-}
-module_exit(wm8782_exit);
+module_platform_driver(wm8782_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM8782 driver");
 MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
index 9ee072b859751ac16b3163c0f5a33833e5eb878a..d99c6a0a0a2d9b5dbee79a170a00d941fe3d627b 100644 (file)
@@ -670,7 +670,7 @@ err_reg_get:
        return ret;
 }
 
-static struct snd_soc_dai_ops wm8804_dai_ops = {
+static const struct snd_soc_dai_ops wm8804_dai_ops = {
        .hw_params = wm8804_hw_params,
        .set_fmt = wm8804_set_fmt,
        .set_sysclk = wm8804_set_sysclk,
index 3d0dc1591eccda191057f2d957823ebb79f55b1e..6ac80cf80b31388cf53868862fb8ac7bb51ca1de 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -513,7 +512,7 @@ SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0,
                   wm8900_rinmix_controls,
                   ARRAY_SIZE(wm8900_rinmix_controls)),
 
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0),
+SND_SOC_DAPM_SUPPLY("Mic Bias", WM8900_REG_POWER1, 4, 0, NULL, 0),
 
 SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
 SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
@@ -987,7 +986,7 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
        (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
         SNDRV_PCM_FORMAT_S24_LE)
 
-static struct snd_soc_dai_ops wm8900_dai_ops = {
+static const struct snd_soc_dai_ops wm8900_dai_ops = {
        .hw_params      = wm8900_hw_params,
        .set_clkdiv     = wm8900_set_dai_clkdiv,
        .set_pll        = wm8900_set_dai_pll,
index 4ad8ebd290e3decbe79f181bbbd1af2a3b014d4f..70a2268c5498c31f62cd3d30e5ed07dc2dcff29b 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/gpio.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/jack.h>
@@ -839,7 +838,7 @@ SND_SOC_DAPM_OUTPUT("LON"),
 SND_SOC_DAPM_OUTPUT("ROP"),
 SND_SOC_DAPM_OUTPUT("RON"),
 
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8903_MIC_BIAS_CONTROL_0, 0, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8903_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
 SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
@@ -948,7 +947,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
 static const struct snd_soc_dapm_route wm8903_intercon[] = {
 
        { "CLK_DSP", NULL, "CLK_SYS" },
-       { "Mic Bias", NULL, "CLK_SYS" },
+       { "MICBIAS", NULL, "CLK_SYS" },
        { "HPL_DCS", NULL, "CLK_SYS" },
        { "HPR_DCS", NULL, "CLK_SYS" },
        { "LINEOUTL_DCS", NULL, "CLK_SYS" },
@@ -1732,7 +1731,7 @@ static irqreturn_t wm8903_irq(int irq, void *data)
                        SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8903_dai_ops = {
+static const struct snd_soc_dai_ops wm8903_dai_ops = {
        .hw_params      = wm8903_hw_params,
        .digital_mute   = wm8903_digital_mute,
        .set_fmt        = wm8903_set_dai_fmt,
index 285ef87e6704fd655d89170ce5e5307e25a36983..babca49c87664a78b17e0efb614fdccb03ea59eb 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -1196,7 +1195,7 @@ SND_SOC_DAPM_INPUT("IN2R"),
 SND_SOC_DAPM_INPUT("IN3L"),
 SND_SOC_DAPM_INPUT("IN3R"),
 
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
 SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
@@ -2205,7 +2204,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
 #define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8904_dai_ops = {
+static const struct snd_soc_dai_ops wm8904_dai_ops = {
        .set_sysclk = wm8904_set_sysclk,
        .set_fmt = wm8904_set_fmt,
        .set_tdm_slot = wm8904_set_tdm_slot,
index de9ec9b8b7d9ae06e98bd58f01e28ff67b08f0e1..9f1cce8d105dde94468024da48aaf9b3986e6967 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -629,8 +628,8 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
                break;
        case WM8940_OPCLKDIV:
-               reg = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFCF;
-               ret = snd_soc_write(codec, WM8940_ADDCNTRL, reg | (div << 4));
+               reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF;
+               ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4));
                break;
        }
        return ret;
@@ -644,7 +643,7 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
                        SNDRV_PCM_FMTBIT_S24_LE |                       \
                        SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8940_dai_ops = {
+static const struct snd_soc_dai_ops wm8940_dai_ops = {
        .hw_params = wm8940_i2s_hw_params,
        .set_sysclk = wm8940_set_dai_sysclk,
        .digital_mute = wm8940_mute,
index 3c7198779c3173e1408daf2403dc794a5bf4e157..ca38722bc3fe50a33a046aad5ad845f742054dea 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -859,7 +858,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 #define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8955_dai_ops = {
+static const struct snd_soc_dai_ops wm8955_dai_ops = {
        .set_sysclk = wm8955_set_sysclk,
        .set_fmt = wm8955_set_fmt,
        .hw_params = wm8955_hw_params,
index 0293763debe5811160fb3b7cc23284a91df2a94a..39e9557bdfd72d468a7fbfa53571f9e6758c6beb 100644 (file)
@@ -55,7 +55,8 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
                return 0;
 
        if (fw->size < 32) {
-               dev_err(codec->dev, "%s: firmware too short\n", name);
+               dev_err(codec->dev, "%s: firmware too short (%d bytes)\n",
+                       name, fw->size);
                goto err;
        }
 
index 2df253c185683cb0001b05e6d7c7ecd21c759147..ed2773f623ca65b990ce0213b3f10307cfb59529 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -265,7 +264,7 @@ SND_SOC_DAPM_INPUT("RINPUT2"),
 SND_SOC_DAPM_INPUT("LINPUT3"),
 SND_SOC_DAPM_INPUT("RINPUT3"),
 
-SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0),
+SND_SOC_DAPM_SUPPLY("MICB", WM8960_POWER1, 1, 0, NULL, 0),
 
 SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0,
                   wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)),
@@ -869,7 +868,7 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8960_dai_ops = {
+static const struct snd_soc_dai_ops wm8960_dai_ops = {
        .hw_params = wm8960_hw_params,
        .digital_mute = wm8960_mute,
        .set_fmt = wm8960_set_dai_fmt,
index 9568c8a49f962da10d62a11ad58a8143cfd8619d..c0587013fdfa28a452aa241363d98abc54bebfe2 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -531,7 +530,7 @@ SND_SOC_DAPM_PGA("Right Input", WM8961_PWR_MGMT_1, 4, 0, NULL, 0),
 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", WM8961_PWR_MGMT_1, 3, 0),
 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", WM8961_PWR_MGMT_1, 2, 0),
 
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8961_PWR_MGMT_1, 1, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8961_PWR_MGMT_1, 1, 0, NULL, 0),
 
 SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &dacl_mux),
 SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &dacr_mux),
@@ -929,7 +928,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8961_dai_ops = {
+static const struct snd_soc_dai_ops wm8961_dai_ops = {
        .hw_params = wm8961_hw_params,
        .set_sysclk = wm8961_set_sysclk,
        .set_fmt = wm8961_set_fmt,
index 53edd9a8c758f24943de1219b37cb45602fc11ef..8810988522ebfcb5c941048a8092eaf91d9654b3 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
-#include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
@@ -50,6 +50,7 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
 
 /* codec private data */
 struct wm8962_priv {
+       struct regmap *regmap;
        struct snd_soc_codec *codec;
 
        int sysclk;
@@ -95,7 +96,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \
        struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
                                                  disable_nb[n]); \
        if (event & REGULATOR_EVENT_DISABLE) { \
-               wm8962->codec->cache_sync = 1; \
+               regcache_cache_only(wm8962->regmap, true);      \
        } \
        return 0; \
 }
@@ -109,691 +110,691 @@ WM8962_REGULATOR_EVENT(5)
 WM8962_REGULATOR_EVENT(6)
 WM8962_REGULATOR_EVENT(7)
 
-static const u16 wm8962_reg[WM8962_MAX_REGISTER + 1] = {
-       [0] = 0x009F,     /* R0     - Left Input volume */
-       [1] = 0x049F,     /* R1     - Right Input volume */
-       [2] = 0x0000,     /* R2     - HPOUTL volume */
-       [3] = 0x0000,     /* R3     - HPOUTR volume */
-       [4] = 0x0020,     /* R4     - Clocking1 */
-       [5] = 0x0018,     /* R5     - ADC & DAC Control 1 */
-       [6] = 0x2008,     /* R6     - ADC & DAC Control 2 */
-       [7] = 0x000A,     /* R7     - Audio Interface 0 */
-       [8] = 0x01E4,     /* R8     - Clocking2 */
-       [9] = 0x0300,     /* R9     - Audio Interface 1 */
-       [10] = 0x00C0,    /* R10    - Left DAC volume */
-       [11] = 0x00C0,    /* R11    - Right DAC volume */
-
-       [14] = 0x0040,     /* R14    - Audio Interface 2 */
-       [15] = 0x6243,     /* R15    - Software Reset */
-
-       [17] = 0x007B,     /* R17    - ALC1 */
-       [18] = 0x0000,     /* R18    - ALC2 */
-       [19] = 0x1C32,     /* R19    - ALC3 */
-       [20] = 0x3200,     /* R20    - Noise Gate */
-       [21] = 0x00C0,     /* R21    - Left ADC volume */
-       [22] = 0x00C0,     /* R22    - Right ADC volume */
-       [23] = 0x0160,     /* R23    - Additional control(1) */
-       [24] = 0x0000,     /* R24    - Additional control(2) */
-       [25] = 0x0000,     /* R25    - Pwr Mgmt (1) */
-       [26] = 0x0000,     /* R26    - Pwr Mgmt (2) */
-       [27] = 0x0010,     /* R27    - Additional Control (3) */
-       [28] = 0x0000,     /* R28    - Anti-pop */
-
-       [30] = 0x005E,     /* R30    - Clocking 3 */
-       [31] = 0x0000,     /* R31    - Input mixer control (1) */
-       [32] = 0x0145,     /* R32    - Left input mixer volume */
-       [33] = 0x0145,     /* R33    - Right input mixer volume */
-       [34] = 0x0009,     /* R34    - Input mixer control (2) */
-       [35] = 0x0003,     /* R35    - Input bias control */
-       [37] = 0x0008,     /* R37    - Left input PGA control */
-       [38] = 0x0008,     /* R38    - Right input PGA control */
-
-       [40] = 0x0000,     /* R40    - SPKOUTL volume */
-       [41] = 0x0000,     /* R41    - SPKOUTR volume */
-
-       [47] = 0x0000,     /* R47    - Thermal Shutdown Status */
-       [48] = 0x8027,     /* R48    - Additional Control (4) */
-       [49] = 0x0010,     /* R49    - Class D Control 1 */
-
-       [51] = 0x0003,     /* R51    - Class D Control 2 */
-
-       [56] = 0x0506,     /* R56    - Clocking 4 */
-       [57] = 0x0000,     /* R57    - DAC DSP Mixing (1) */
-       [58] = 0x0000,     /* R58    - DAC DSP Mixing (2) */
-
-       [60] = 0x0300,     /* R60    - DC Servo 0 */
-       [61] = 0x0300,     /* R61    - DC Servo 1 */
-
-       [64] = 0x0810,     /* R64    - DC Servo 4 */
-
-       [66] = 0x0000,     /* R66    - DC Servo 6 */
-
-       [68] = 0x001B,     /* R68    - Analogue PGA Bias */
-       [69] = 0x0000,     /* R69    - Analogue HP 0 */
-
-       [71] = 0x01FB,     /* R71    - Analogue HP 2 */
-       [72] = 0x0000,     /* R72    - Charge Pump 1 */
-
-       [82] = 0x0004,     /* R82    - Charge Pump B */
-
-       [87] = 0x0000,     /* R87    - Write Sequencer Control 1 */
-
-       [90] = 0x0000,     /* R90    - Write Sequencer Control 2 */
-
-       [93] = 0x0000,     /* R93    - Write Sequencer Control 3 */
-       [94] = 0x0000,     /* R94    - Control Interface */
-
-       [99] = 0x0000,     /* R99    - Mixer Enables */
-       [100] = 0x0000,     /* R100   - Headphone Mixer (1) */
-       [101] = 0x0000,     /* R101   - Headphone Mixer (2) */
-       [102] = 0x013F,     /* R102   - Headphone Mixer (3) */
-       [103] = 0x013F,     /* R103   - Headphone Mixer (4) */
-
-       [105] = 0x0000,     /* R105   - Speaker Mixer (1) */
-       [106] = 0x0000,     /* R106   - Speaker Mixer (2) */
-       [107] = 0x013F,     /* R107   - Speaker Mixer (3) */
-       [108] = 0x013F,     /* R108   - Speaker Mixer (4) */
-       [109] = 0x0003,     /* R109   - Speaker Mixer (5) */
-       [110] = 0x0002,     /* R110   - Beep Generator (1) */
-
-       [115] = 0x0006,     /* R115   - Oscillator Trim (3) */
-       [116] = 0x0026,     /* R116   - Oscillator Trim (4) */
-
-       [119] = 0x0000,     /* R119   - Oscillator Trim (7) */
-
-       [124] = 0x0011,     /* R124   - Analogue Clocking1 */
-       [125] = 0x004B,     /* R125   - Analogue Clocking2 */
-       [126] = 0x000D,     /* R126   - Analogue Clocking3 */
-       [127] = 0x0000,     /* R127   - PLL Software Reset */
-
-       [129] = 0x0000,     /* R129   - PLL2 */
-
-       [131] = 0x0000,     /* R131   - PLL 4 */
-
-       [136] = 0x0067,     /* R136   - PLL 9 */
-       [137] = 0x001C,     /* R137   - PLL 10 */
-       [138] = 0x0071,     /* R138   - PLL 11 */
-       [139] = 0x00C7,     /* R139   - PLL 12 */
-       [140] = 0x0067,     /* R140   - PLL 13 */
-       [141] = 0x0048,     /* R141   - PLL 14 */
-       [142] = 0x0022,     /* R142   - PLL 15 */
-       [143] = 0x0097,     /* R143   - PLL 16 */
-
-       [155] = 0x000C,     /* R155   - FLL Control (1) */
-       [156] = 0x0039,     /* R156   - FLL Control (2) */
-       [157] = 0x0180,     /* R157   - FLL Control (3) */
-
-       [159] = 0x0032,     /* R159   - FLL Control (5) */
-       [160] = 0x0018,     /* R160   - FLL Control (6) */
-       [161] = 0x007D,     /* R161   - FLL Control (7) */
-       [162] = 0x0008,     /* R162   - FLL Control (8) */
-
-       [252] = 0x0005,     /* R252   - General test 1 */
-
-       [256] = 0x0000,     /* R256   - DF1 */
-       [257] = 0x0000,     /* R257   - DF2 */
-       [258] = 0x0000,     /* R258   - DF3 */
-       [259] = 0x0000,     /* R259   - DF4 */
-       [260] = 0x0000,     /* R260   - DF5 */
-       [261] = 0x0000,     /* R261   - DF6 */
-       [262] = 0x0000,     /* R262   - DF7 */
-
-       [264] = 0x0000,     /* R264   - LHPF1 */
-       [265] = 0x0000,     /* R265   - LHPF2 */
-
-       [268] = 0x0000,     /* R268   - THREED1 */
-       [269] = 0x0000,     /* R269   - THREED2 */
-       [270] = 0x0000,     /* R270   - THREED3 */
-       [271] = 0x0000,     /* R271   - THREED4 */
-
-       [276] = 0x000C,     /* R276   - DRC 1 */
-       [277] = 0x0925,     /* R277   - DRC 2 */
-       [278] = 0x0000,     /* R278   - DRC 3 */
-       [279] = 0x0000,     /* R279   - DRC 4 */
-       [280] = 0x0000,     /* R280   - DRC 5 */
-
-       [285] = 0x0000,     /* R285   - Tloopback */
-
-       [335] = 0x0004,     /* R335   - EQ1 */
-       [336] = 0x6318,     /* R336   - EQ2 */
-       [337] = 0x6300,     /* R337   - EQ3 */
-       [338] = 0x0FCA,     /* R338   - EQ4 */
-       [339] = 0x0400,     /* R339   - EQ5 */
-       [340] = 0x00D8,     /* R340   - EQ6 */
-       [341] = 0x1EB5,     /* R341   - EQ7 */
-       [342] = 0xF145,     /* R342   - EQ8 */
-       [343] = 0x0B75,     /* R343   - EQ9 */
-       [344] = 0x01C5,     /* R344   - EQ10 */
-       [345] = 0x1C58,     /* R345   - EQ11 */
-       [346] = 0xF373,     /* R346   - EQ12 */
-       [347] = 0x0A54,     /* R347   - EQ13 */
-       [348] = 0x0558,     /* R348   - EQ14 */
-       [349] = 0x168E,     /* R349   - EQ15 */
-       [350] = 0xF829,     /* R350   - EQ16 */
-       [351] = 0x07AD,     /* R351   - EQ17 */
-       [352] = 0x1103,     /* R352   - EQ18 */
-       [353] = 0x0564,     /* R353   - EQ19 */
-       [354] = 0x0559,     /* R354   - EQ20 */
-       [355] = 0x4000,     /* R355   - EQ21 */
-       [356] = 0x6318,     /* R356   - EQ22 */
-       [357] = 0x6300,     /* R357   - EQ23 */
-       [358] = 0x0FCA,     /* R358   - EQ24 */
-       [359] = 0x0400,     /* R359   - EQ25 */
-       [360] = 0x00D8,     /* R360   - EQ26 */
-       [361] = 0x1EB5,     /* R361   - EQ27 */
-       [362] = 0xF145,     /* R362   - EQ28 */
-       [363] = 0x0B75,     /* R363   - EQ29 */
-       [364] = 0x01C5,     /* R364   - EQ30 */
-       [365] = 0x1C58,     /* R365   - EQ31 */
-       [366] = 0xF373,     /* R366   - EQ32 */
-       [367] = 0x0A54,     /* R367   - EQ33 */
-       [368] = 0x0558,     /* R368   - EQ34 */
-       [369] = 0x168E,     /* R369   - EQ35 */
-       [370] = 0xF829,     /* R370   - EQ36 */
-       [371] = 0x07AD,     /* R371   - EQ37 */
-       [372] = 0x1103,     /* R372   - EQ38 */
-       [373] = 0x0564,     /* R373   - EQ39 */
-       [374] = 0x0559,     /* R374   - EQ40 */
-       [375] = 0x4000,     /* R375   - EQ41 */
-
-       [513] = 0x0000,     /* R513   - GPIO 2 */
-       [514] = 0x0000,     /* R514   - GPIO 3 */
-
-       [516] = 0x8100,     /* R516   - GPIO 5 */
-       [517] = 0x8100,     /* R517   - GPIO 6 */
-
-       [560] = 0x0000,     /* R560   - Interrupt Status 1 */
-       [561] = 0x0000,     /* R561   - Interrupt Status 2 */
-
-       [568] = 0x0030,     /* R568   - Interrupt Status 1 Mask */
-       [569] = 0xFFED,     /* R569   - Interrupt Status 2 Mask */
-
-       [576] = 0x0000,     /* R576   - Interrupt Control */
-
-       [584] = 0x002D,     /* R584   - IRQ Debounce */
-
-       [586] = 0x0000,     /* R586   -  MICINT Source Pol */
-
-       [768] = 0x1C00,     /* R768   - DSP2 Power Management */
-
-       [1037] = 0x0000,     /* R1037  - DSP2_ExecControl */
-
-       [8192] = 0x0000,     /* R8192  - DSP2 Instruction RAM 0 */
-
-       [9216] = 0x0030,     /* R9216  - DSP2 Address RAM 2 */
-       [9217] = 0x0000,     /* R9217  - DSP2 Address RAM 1 */
-       [9218] = 0x0000,     /* R9218  - DSP2 Address RAM 0 */
-
-       [12288] = 0x0000,     /* R12288 - DSP2 Data1 RAM 1 */
-       [12289] = 0x0000,     /* R12289 - DSP2 Data1 RAM 0 */
-
-       [13312] = 0x0000,     /* R13312 - DSP2 Data2 RAM 1 */
-       [13313] = 0x0000,     /* R13313 - DSP2 Data2 RAM 0 */
-
-       [14336] = 0x0000,     /* R14336 - DSP2 Data3 RAM 1 */
-       [14337] = 0x0000,     /* R14337 - DSP2 Data3 RAM 0 */
-
-       [15360] = 0x000A,     /* R15360 - DSP2 Coeff RAM 0 */
-
-       [16384] = 0x0000,     /* R16384 - RETUNEADC_SHARED_COEFF_1 */
-       [16385] = 0x0000,     /* R16385 - RETUNEADC_SHARED_COEFF_0 */
-       [16386] = 0x0000,     /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
-       [16387] = 0x0000,     /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
-       [16388] = 0x0000,     /* R16388 - SOUNDSTAGE_ENABLES_1 */
-       [16389] = 0x0000,     /* R16389 - SOUNDSTAGE_ENABLES_0 */
-
-       [16896] = 0x0002,     /* R16896 - HDBASS_AI_1 */
-       [16897] = 0xBD12,     /* R16897 - HDBASS_AI_0 */
-       [16898] = 0x007C,     /* R16898 - HDBASS_AR_1 */
-       [16899] = 0x586C,     /* R16899 - HDBASS_AR_0 */
-       [16900] = 0x0053,     /* R16900 - HDBASS_B_1 */
-       [16901] = 0x8121,     /* R16901 - HDBASS_B_0 */
-       [16902] = 0x003F,     /* R16902 - HDBASS_K_1 */
-       [16903] = 0x8BD8,     /* R16903 - HDBASS_K_0 */
-       [16904] = 0x0032,     /* R16904 - HDBASS_N1_1 */
-       [16905] = 0xF52D,     /* R16905 - HDBASS_N1_0 */
-       [16906] = 0x0065,     /* R16906 - HDBASS_N2_1 */
-       [16907] = 0xAC8C,     /* R16907 - HDBASS_N2_0 */
-       [16908] = 0x006B,     /* R16908 - HDBASS_N3_1 */
-       [16909] = 0xE087,     /* R16909 - HDBASS_N3_0 */
-       [16910] = 0x0072,     /* R16910 - HDBASS_N4_1 */
-       [16911] = 0x1483,     /* R16911 - HDBASS_N4_0 */
-       [16912] = 0x0072,     /* R16912 - HDBASS_N5_1 */
-       [16913] = 0x1483,     /* R16913 - HDBASS_N5_0 */
-       [16914] = 0x0043,     /* R16914 - HDBASS_X1_1 */
-       [16915] = 0x3525,     /* R16915 - HDBASS_X1_0 */
-       [16916] = 0x0006,     /* R16916 - HDBASS_X2_1 */
-       [16917] = 0x6A4A,     /* R16917 - HDBASS_X2_0 */
-       [16918] = 0x0043,     /* R16918 - HDBASS_X3_1 */
-       [16919] = 0x6079,     /* R16919 - HDBASS_X3_0 */
-       [16920] = 0x0008,     /* R16920 - HDBASS_ATK_1 */
-       [16921] = 0x0000,     /* R16921 - HDBASS_ATK_0 */
-       [16922] = 0x0001,     /* R16922 - HDBASS_DCY_1 */
-       [16923] = 0x0000,     /* R16923 - HDBASS_DCY_0 */
-       [16924] = 0x0059,     /* R16924 - HDBASS_PG_1 */
-       [16925] = 0x999A,     /* R16925 - HDBASS_PG_0 */
-
-       [17048] = 0x0083,     /* R17408 - HPF_C_1 */
-       [17049] = 0x98AD,     /* R17409 - HPF_C_0 */
-
-       [17920] = 0x007F,     /* R17920 - ADCL_RETUNE_C1_1 */
-       [17921] = 0xFFFF,     /* R17921 - ADCL_RETUNE_C1_0 */
-       [17922] = 0x0000,     /* R17922 - ADCL_RETUNE_C2_1 */
-       [17923] = 0x0000,     /* R17923 - ADCL_RETUNE_C2_0 */
-       [17924] = 0x0000,     /* R17924 - ADCL_RETUNE_C3_1 */
-       [17925] = 0x0000,     /* R17925 - ADCL_RETUNE_C3_0 */
-       [17926] = 0x0000,     /* R17926 - ADCL_RETUNE_C4_1 */
-       [17927] = 0x0000,     /* R17927 - ADCL_RETUNE_C4_0 */
-       [17928] = 0x0000,     /* R17928 - ADCL_RETUNE_C5_1 */
-       [17929] = 0x0000,     /* R17929 - ADCL_RETUNE_C5_0 */
-       [17930] = 0x0000,     /* R17930 - ADCL_RETUNE_C6_1 */
-       [17931] = 0x0000,     /* R17931 - ADCL_RETUNE_C6_0 */
-       [17932] = 0x0000,     /* R17932 - ADCL_RETUNE_C7_1 */
-       [17933] = 0x0000,     /* R17933 - ADCL_RETUNE_C7_0 */
-       [17934] = 0x0000,     /* R17934 - ADCL_RETUNE_C8_1 */
-       [17935] = 0x0000,     /* R17935 - ADCL_RETUNE_C8_0 */
-       [17936] = 0x0000,     /* R17936 - ADCL_RETUNE_C9_1 */
-       [17937] = 0x0000,     /* R17937 - ADCL_RETUNE_C9_0 */
-       [17938] = 0x0000,     /* R17938 - ADCL_RETUNE_C10_1 */
-       [17939] = 0x0000,     /* R17939 - ADCL_RETUNE_C10_0 */
-       [17940] = 0x0000,     /* R17940 - ADCL_RETUNE_C11_1 */
-       [17941] = 0x0000,     /* R17941 - ADCL_RETUNE_C11_0 */
-       [17942] = 0x0000,     /* R17942 - ADCL_RETUNE_C12_1 */
-       [17943] = 0x0000,     /* R17943 - ADCL_RETUNE_C12_0 */
-       [17944] = 0x0000,     /* R17944 - ADCL_RETUNE_C13_1 */
-       [17945] = 0x0000,     /* R17945 - ADCL_RETUNE_C13_0 */
-       [17946] = 0x0000,     /* R17946 - ADCL_RETUNE_C14_1 */
-       [17947] = 0x0000,     /* R17947 - ADCL_RETUNE_C14_0 */
-       [17948] = 0x0000,     /* R17948 - ADCL_RETUNE_C15_1 */
-       [17949] = 0x0000,     /* R17949 - ADCL_RETUNE_C15_0 */
-       [17950] = 0x0000,     /* R17950 - ADCL_RETUNE_C16_1 */
-       [17951] = 0x0000,     /* R17951 - ADCL_RETUNE_C16_0 */
-       [17952] = 0x0000,     /* R17952 - ADCL_RETUNE_C17_1 */
-       [17953] = 0x0000,     /* R17953 - ADCL_RETUNE_C17_0 */
-       [17954] = 0x0000,     /* R17954 - ADCL_RETUNE_C18_1 */
-       [17955] = 0x0000,     /* R17955 - ADCL_RETUNE_C18_0 */
-       [17956] = 0x0000,     /* R17956 - ADCL_RETUNE_C19_1 */
-       [17957] = 0x0000,     /* R17957 - ADCL_RETUNE_C19_0 */
-       [17958] = 0x0000,     /* R17958 - ADCL_RETUNE_C20_1 */
-       [17959] = 0x0000,     /* R17959 - ADCL_RETUNE_C20_0 */
-       [17960] = 0x0000,     /* R17960 - ADCL_RETUNE_C21_1 */
-       [17961] = 0x0000,     /* R17961 - ADCL_RETUNE_C21_0 */
-       [17962] = 0x0000,     /* R17962 - ADCL_RETUNE_C22_1 */
-       [17963] = 0x0000,     /* R17963 - ADCL_RETUNE_C22_0 */
-       [17964] = 0x0000,     /* R17964 - ADCL_RETUNE_C23_1 */
-       [17965] = 0x0000,     /* R17965 - ADCL_RETUNE_C23_0 */
-       [17966] = 0x0000,     /* R17966 - ADCL_RETUNE_C24_1 */
-       [17967] = 0x0000,     /* R17967 - ADCL_RETUNE_C24_0 */
-       [17968] = 0x0000,     /* R17968 - ADCL_RETUNE_C25_1 */
-       [17969] = 0x0000,     /* R17969 - ADCL_RETUNE_C25_0 */
-       [17970] = 0x0000,     /* R17970 - ADCL_RETUNE_C26_1 */
-       [17971] = 0x0000,     /* R17971 - ADCL_RETUNE_C26_0 */
-       [17972] = 0x0000,     /* R17972 - ADCL_RETUNE_C27_1 */
-       [17973] = 0x0000,     /* R17973 - ADCL_RETUNE_C27_0 */
-       [17974] = 0x0000,     /* R17974 - ADCL_RETUNE_C28_1 */
-       [17975] = 0x0000,     /* R17975 - ADCL_RETUNE_C28_0 */
-       [17976] = 0x0000,     /* R17976 - ADCL_RETUNE_C29_1 */
-       [17977] = 0x0000,     /* R17977 - ADCL_RETUNE_C29_0 */
-       [17978] = 0x0000,     /* R17978 - ADCL_RETUNE_C30_1 */
-       [17979] = 0x0000,     /* R17979 - ADCL_RETUNE_C30_0 */
-       [17980] = 0x0000,     /* R17980 - ADCL_RETUNE_C31_1 */
-       [17981] = 0x0000,     /* R17981 - ADCL_RETUNE_C31_0 */
-       [17982] = 0x0000,     /* R17982 - ADCL_RETUNE_C32_1 */
-       [17983] = 0x0000,     /* R17983 - ADCL_RETUNE_C32_0 */
-
-       [18432] = 0x0020,     /* R18432 - RETUNEADC_PG2_1 */
-       [18433] = 0x0000,     /* R18433 - RETUNEADC_PG2_0 */
-       [18434] = 0x0040,     /* R18434 - RETUNEADC_PG_1 */
-       [18435] = 0x0000,     /* R18435 - RETUNEADC_PG_0 */
-
-       [18944] = 0x007F,     /* R18944 - ADCR_RETUNE_C1_1 */
-       [18945] = 0xFFFF,     /* R18945 - ADCR_RETUNE_C1_0 */
-       [18946] = 0x0000,     /* R18946 - ADCR_RETUNE_C2_1 */
-       [18947] = 0x0000,     /* R18947 - ADCR_RETUNE_C2_0 */
-       [18948] = 0x0000,     /* R18948 - ADCR_RETUNE_C3_1 */
-       [18949] = 0x0000,     /* R18949 - ADCR_RETUNE_C3_0 */
-       [18950] = 0x0000,     /* R18950 - ADCR_RETUNE_C4_1 */
-       [18951] = 0x0000,     /* R18951 - ADCR_RETUNE_C4_0 */
-       [18952] = 0x0000,     /* R18952 - ADCR_RETUNE_C5_1 */
-       [18953] = 0x0000,     /* R18953 - ADCR_RETUNE_C5_0 */
-       [18954] = 0x0000,     /* R18954 - ADCR_RETUNE_C6_1 */
-       [18955] = 0x0000,     /* R18955 - ADCR_RETUNE_C6_0 */
-       [18956] = 0x0000,     /* R18956 - ADCR_RETUNE_C7_1 */
-       [18957] = 0x0000,     /* R18957 - ADCR_RETUNE_C7_0 */
-       [18958] = 0x0000,     /* R18958 - ADCR_RETUNE_C8_1 */
-       [18959] = 0x0000,     /* R18959 - ADCR_RETUNE_C8_0 */
-       [18960] = 0x0000,     /* R18960 - ADCR_RETUNE_C9_1 */
-       [18961] = 0x0000,     /* R18961 - ADCR_RETUNE_C9_0 */
-       [18962] = 0x0000,     /* R18962 - ADCR_RETUNE_C10_1 */
-       [18963] = 0x0000,     /* R18963 - ADCR_RETUNE_C10_0 */
-       [18964] = 0x0000,     /* R18964 - ADCR_RETUNE_C11_1 */
-       [18965] = 0x0000,     /* R18965 - ADCR_RETUNE_C11_0 */
-       [18966] = 0x0000,     /* R18966 - ADCR_RETUNE_C12_1 */
-       [18967] = 0x0000,     /* R18967 - ADCR_RETUNE_C12_0 */
-       [18968] = 0x0000,     /* R18968 - ADCR_RETUNE_C13_1 */
-       [18969] = 0x0000,     /* R18969 - ADCR_RETUNE_C13_0 */
-       [18970] = 0x0000,     /* R18970 - ADCR_RETUNE_C14_1 */
-       [18971] = 0x0000,     /* R18971 - ADCR_RETUNE_C14_0 */
-       [18972] = 0x0000,     /* R18972 - ADCR_RETUNE_C15_1 */
-       [18973] = 0x0000,     /* R18973 - ADCR_RETUNE_C15_0 */
-       [18974] = 0x0000,     /* R18974 - ADCR_RETUNE_C16_1 */
-       [18975] = 0x0000,     /* R18975 - ADCR_RETUNE_C16_0 */
-       [18976] = 0x0000,     /* R18976 - ADCR_RETUNE_C17_1 */
-       [18977] = 0x0000,     /* R18977 - ADCR_RETUNE_C17_0 */
-       [18978] = 0x0000,     /* R18978 - ADCR_RETUNE_C18_1 */
-       [18979] = 0x0000,     /* R18979 - ADCR_RETUNE_C18_0 */
-       [18980] = 0x0000,     /* R18980 - ADCR_RETUNE_C19_1 */
-       [18981] = 0x0000,     /* R18981 - ADCR_RETUNE_C19_0 */
-       [18982] = 0x0000,     /* R18982 - ADCR_RETUNE_C20_1 */
-       [18983] = 0x0000,     /* R18983 - ADCR_RETUNE_C20_0 */
-       [18984] = 0x0000,     /* R18984 - ADCR_RETUNE_C21_1 */
-       [18985] = 0x0000,     /* R18985 - ADCR_RETUNE_C21_0 */
-       [18986] = 0x0000,     /* R18986 - ADCR_RETUNE_C22_1 */
-       [18987] = 0x0000,     /* R18987 - ADCR_RETUNE_C22_0 */
-       [18988] = 0x0000,     /* R18988 - ADCR_RETUNE_C23_1 */
-       [18989] = 0x0000,     /* R18989 - ADCR_RETUNE_C23_0 */
-       [18990] = 0x0000,     /* R18990 - ADCR_RETUNE_C24_1 */
-       [18991] = 0x0000,     /* R18991 - ADCR_RETUNE_C24_0 */
-       [18992] = 0x0000,     /* R18992 - ADCR_RETUNE_C25_1 */
-       [18993] = 0x0000,     /* R18993 - ADCR_RETUNE_C25_0 */
-       [18994] = 0x0000,     /* R18994 - ADCR_RETUNE_C26_1 */
-       [18995] = 0x0000,     /* R18995 - ADCR_RETUNE_C26_0 */
-       [18996] = 0x0000,     /* R18996 - ADCR_RETUNE_C27_1 */
-       [18997] = 0x0000,     /* R18997 - ADCR_RETUNE_C27_0 */
-       [18998] = 0x0000,     /* R18998 - ADCR_RETUNE_C28_1 */
-       [18999] = 0x0000,     /* R18999 - ADCR_RETUNE_C28_0 */
-       [19000] = 0x0000,     /* R19000 - ADCR_RETUNE_C29_1 */
-       [19001] = 0x0000,     /* R19001 - ADCR_RETUNE_C29_0 */
-       [19002] = 0x0000,     /* R19002 - ADCR_RETUNE_C30_1 */
-       [19003] = 0x0000,     /* R19003 - ADCR_RETUNE_C30_0 */
-       [19004] = 0x0000,     /* R19004 - ADCR_RETUNE_C31_1 */
-       [19005] = 0x0000,     /* R19005 - ADCR_RETUNE_C31_0 */
-       [19006] = 0x0000,     /* R19006 - ADCR_RETUNE_C32_1 */
-       [19007] = 0x0000,     /* R19007 - ADCR_RETUNE_C32_0 */
-
-       [19456] = 0x007F,     /* R19456 - DACL_RETUNE_C1_1 */
-       [19457] = 0xFFFF,     /* R19457 - DACL_RETUNE_C1_0 */
-       [19458] = 0x0000,     /* R19458 - DACL_RETUNE_C2_1 */
-       [19459] = 0x0000,     /* R19459 - DACL_RETUNE_C2_0 */
-       [19460] = 0x0000,     /* R19460 - DACL_RETUNE_C3_1 */
-       [19461] = 0x0000,     /* R19461 - DACL_RETUNE_C3_0 */
-       [19462] = 0x0000,     /* R19462 - DACL_RETUNE_C4_1 */
-       [19463] = 0x0000,     /* R19463 - DACL_RETUNE_C4_0 */
-       [19464] = 0x0000,     /* R19464 - DACL_RETUNE_C5_1 */
-       [19465] = 0x0000,     /* R19465 - DACL_RETUNE_C5_0 */
-       [19466] = 0x0000,     /* R19466 - DACL_RETUNE_C6_1 */
-       [19467] = 0x0000,     /* R19467 - DACL_RETUNE_C6_0 */
-       [19468] = 0x0000,     /* R19468 - DACL_RETUNE_C7_1 */
-       [19469] = 0x0000,     /* R19469 - DACL_RETUNE_C7_0 */
-       [19470] = 0x0000,     /* R19470 - DACL_RETUNE_C8_1 */
-       [19471] = 0x0000,     /* R19471 - DACL_RETUNE_C8_0 */
-       [19472] = 0x0000,     /* R19472 - DACL_RETUNE_C9_1 */
-       [19473] = 0x0000,     /* R19473 - DACL_RETUNE_C9_0 */
-       [19474] = 0x0000,     /* R19474 - DACL_RETUNE_C10_1 */
-       [19475] = 0x0000,     /* R19475 - DACL_RETUNE_C10_0 */
-       [19476] = 0x0000,     /* R19476 - DACL_RETUNE_C11_1 */
-       [19477] = 0x0000,     /* R19477 - DACL_RETUNE_C11_0 */
-       [19478] = 0x0000,     /* R19478 - DACL_RETUNE_C12_1 */
-       [19479] = 0x0000,     /* R19479 - DACL_RETUNE_C12_0 */
-       [19480] = 0x0000,     /* R19480 - DACL_RETUNE_C13_1 */
-       [19481] = 0x0000,     /* R19481 - DACL_RETUNE_C13_0 */
-       [19482] = 0x0000,     /* R19482 - DACL_RETUNE_C14_1 */
-       [19483] = 0x0000,     /* R19483 - DACL_RETUNE_C14_0 */
-       [19484] = 0x0000,     /* R19484 - DACL_RETUNE_C15_1 */
-       [19485] = 0x0000,     /* R19485 - DACL_RETUNE_C15_0 */
-       [19486] = 0x0000,     /* R19486 - DACL_RETUNE_C16_1 */
-       [19487] = 0x0000,     /* R19487 - DACL_RETUNE_C16_0 */
-       [19488] = 0x0000,     /* R19488 - DACL_RETUNE_C17_1 */
-       [19489] = 0x0000,     /* R19489 - DACL_RETUNE_C17_0 */
-       [19490] = 0x0000,     /* R19490 - DACL_RETUNE_C18_1 */
-       [19491] = 0x0000,     /* R19491 - DACL_RETUNE_C18_0 */
-       [19492] = 0x0000,     /* R19492 - DACL_RETUNE_C19_1 */
-       [19493] = 0x0000,     /* R19493 - DACL_RETUNE_C19_0 */
-       [19494] = 0x0000,     /* R19494 - DACL_RETUNE_C20_1 */
-       [19495] = 0x0000,     /* R19495 - DACL_RETUNE_C20_0 */
-       [19496] = 0x0000,     /* R19496 - DACL_RETUNE_C21_1 */
-       [19497] = 0x0000,     /* R19497 - DACL_RETUNE_C21_0 */
-       [19498] = 0x0000,     /* R19498 - DACL_RETUNE_C22_1 */
-       [19499] = 0x0000,     /* R19499 - DACL_RETUNE_C22_0 */
-       [19500] = 0x0000,     /* R19500 - DACL_RETUNE_C23_1 */
-       [19501] = 0x0000,     /* R19501 - DACL_RETUNE_C23_0 */
-       [19502] = 0x0000,     /* R19502 - DACL_RETUNE_C24_1 */
-       [19503] = 0x0000,     /* R19503 - DACL_RETUNE_C24_0 */
-       [19504] = 0x0000,     /* R19504 - DACL_RETUNE_C25_1 */
-       [19505] = 0x0000,     /* R19505 - DACL_RETUNE_C25_0 */
-       [19506] = 0x0000,     /* R19506 - DACL_RETUNE_C26_1 */
-       [19507] = 0x0000,     /* R19507 - DACL_RETUNE_C26_0 */
-       [19508] = 0x0000,     /* R19508 - DACL_RETUNE_C27_1 */
-       [19509] = 0x0000,     /* R19509 - DACL_RETUNE_C27_0 */
-       [19510] = 0x0000,     /* R19510 - DACL_RETUNE_C28_1 */
-       [19511] = 0x0000,     /* R19511 - DACL_RETUNE_C28_0 */
-       [19512] = 0x0000,     /* R19512 - DACL_RETUNE_C29_1 */
-       [19513] = 0x0000,     /* R19513 - DACL_RETUNE_C29_0 */
-       [19514] = 0x0000,     /* R19514 - DACL_RETUNE_C30_1 */
-       [19515] = 0x0000,     /* R19515 - DACL_RETUNE_C30_0 */
-       [19516] = 0x0000,     /* R19516 - DACL_RETUNE_C31_1 */
-       [19517] = 0x0000,     /* R19517 - DACL_RETUNE_C31_0 */
-       [19518] = 0x0000,     /* R19518 - DACL_RETUNE_C32_1 */
-       [19519] = 0x0000,     /* R19519 - DACL_RETUNE_C32_0 */
-
-       [19968] = 0x0020,     /* R19968 - RETUNEDAC_PG2_1 */
-       [19969] = 0x0000,     /* R19969 - RETUNEDAC_PG2_0 */
-       [19970] = 0x0040,     /* R19970 - RETUNEDAC_PG_1 */
-       [19971] = 0x0000,     /* R19971 - RETUNEDAC_PG_0 */
-
-       [20480] = 0x007F,     /* R20480 - DACR_RETUNE_C1_1 */
-       [20481] = 0xFFFF,     /* R20481 - DACR_RETUNE_C1_0 */
-       [20482] = 0x0000,     /* R20482 - DACR_RETUNE_C2_1 */
-       [20483] = 0x0000,     /* R20483 - DACR_RETUNE_C2_0 */
-       [20484] = 0x0000,     /* R20484 - DACR_RETUNE_C3_1 */
-       [20485] = 0x0000,     /* R20485 - DACR_RETUNE_C3_0 */
-       [20486] = 0x0000,     /* R20486 - DACR_RETUNE_C4_1 */
-       [20487] = 0x0000,     /* R20487 - DACR_RETUNE_C4_0 */
-       [20488] = 0x0000,     /* R20488 - DACR_RETUNE_C5_1 */
-       [20489] = 0x0000,     /* R20489 - DACR_RETUNE_C5_0 */
-       [20490] = 0x0000,     /* R20490 - DACR_RETUNE_C6_1 */
-       [20491] = 0x0000,     /* R20491 - DACR_RETUNE_C6_0 */
-       [20492] = 0x0000,     /* R20492 - DACR_RETUNE_C7_1 */
-       [20493] = 0x0000,     /* R20493 - DACR_RETUNE_C7_0 */
-       [20494] = 0x0000,     /* R20494 - DACR_RETUNE_C8_1 */
-       [20495] = 0x0000,     /* R20495 - DACR_RETUNE_C8_0 */
-       [20496] = 0x0000,     /* R20496 - DACR_RETUNE_C9_1 */
-       [20497] = 0x0000,     /* R20497 - DACR_RETUNE_C9_0 */
-       [20498] = 0x0000,     /* R20498 - DACR_RETUNE_C10_1 */
-       [20499] = 0x0000,     /* R20499 - DACR_RETUNE_C10_0 */
-       [20500] = 0x0000,     /* R20500 - DACR_RETUNE_C11_1 */
-       [20501] = 0x0000,     /* R20501 - DACR_RETUNE_C11_0 */
-       [20502] = 0x0000,     /* R20502 - DACR_RETUNE_C12_1 */
-       [20503] = 0x0000,     /* R20503 - DACR_RETUNE_C12_0 */
-       [20504] = 0x0000,     /* R20504 - DACR_RETUNE_C13_1 */
-       [20505] = 0x0000,     /* R20505 - DACR_RETUNE_C13_0 */
-       [20506] = 0x0000,     /* R20506 - DACR_RETUNE_C14_1 */
-       [20507] = 0x0000,     /* R20507 - DACR_RETUNE_C14_0 */
-       [20508] = 0x0000,     /* R20508 - DACR_RETUNE_C15_1 */
-       [20509] = 0x0000,     /* R20509 - DACR_RETUNE_C15_0 */
-       [20510] = 0x0000,     /* R20510 - DACR_RETUNE_C16_1 */
-       [20511] = 0x0000,     /* R20511 - DACR_RETUNE_C16_0 */
-       [20512] = 0x0000,     /* R20512 - DACR_RETUNE_C17_1 */
-       [20513] = 0x0000,     /* R20513 - DACR_RETUNE_C17_0 */
-       [20514] = 0x0000,     /* R20514 - DACR_RETUNE_C18_1 */
-       [20515] = 0x0000,     /* R20515 - DACR_RETUNE_C18_0 */
-       [20516] = 0x0000,     /* R20516 - DACR_RETUNE_C19_1 */
-       [20517] = 0x0000,     /* R20517 - DACR_RETUNE_C19_0 */
-       [20518] = 0x0000,     /* R20518 - DACR_RETUNE_C20_1 */
-       [20519] = 0x0000,     /* R20519 - DACR_RETUNE_C20_0 */
-       [20520] = 0x0000,     /* R20520 - DACR_RETUNE_C21_1 */
-       [20521] = 0x0000,     /* R20521 - DACR_RETUNE_C21_0 */
-       [20522] = 0x0000,     /* R20522 - DACR_RETUNE_C22_1 */
-       [20523] = 0x0000,     /* R20523 - DACR_RETUNE_C22_0 */
-       [20524] = 0x0000,     /* R20524 - DACR_RETUNE_C23_1 */
-       [20525] = 0x0000,     /* R20525 - DACR_RETUNE_C23_0 */
-       [20526] = 0x0000,     /* R20526 - DACR_RETUNE_C24_1 */
-       [20527] = 0x0000,     /* R20527 - DACR_RETUNE_C24_0 */
-       [20528] = 0x0000,     /* R20528 - DACR_RETUNE_C25_1 */
-       [20529] = 0x0000,     /* R20529 - DACR_RETUNE_C25_0 */
-       [20530] = 0x0000,     /* R20530 - DACR_RETUNE_C26_1 */
-       [20531] = 0x0000,     /* R20531 - DACR_RETUNE_C26_0 */
-       [20532] = 0x0000,     /* R20532 - DACR_RETUNE_C27_1 */
-       [20533] = 0x0000,     /* R20533 - DACR_RETUNE_C27_0 */
-       [20534] = 0x0000,     /* R20534 - DACR_RETUNE_C28_1 */
-       [20535] = 0x0000,     /* R20535 - DACR_RETUNE_C28_0 */
-       [20536] = 0x0000,     /* R20536 - DACR_RETUNE_C29_1 */
-       [20537] = 0x0000,     /* R20537 - DACR_RETUNE_C29_0 */
-       [20538] = 0x0000,     /* R20538 - DACR_RETUNE_C30_1 */
-       [20539] = 0x0000,     /* R20539 - DACR_RETUNE_C30_0 */
-       [20540] = 0x0000,     /* R20540 - DACR_RETUNE_C31_1 */
-       [20541] = 0x0000,     /* R20541 - DACR_RETUNE_C31_0 */
-       [20542] = 0x0000,     /* R20542 - DACR_RETUNE_C32_1 */
-       [20543] = 0x0000,     /* R20543 - DACR_RETUNE_C32_0 */
-
-       [20992] = 0x008C,     /* R20992 - VSS_XHD2_1 */
-       [20993] = 0x0200,     /* R20993 - VSS_XHD2_0 */
-       [20994] = 0x0035,     /* R20994 - VSS_XHD3_1 */
-       [20995] = 0x0700,     /* R20995 - VSS_XHD3_0 */
-       [20996] = 0x003A,     /* R20996 - VSS_XHN1_1 */
-       [20997] = 0x4100,     /* R20997 - VSS_XHN1_0 */
-       [20998] = 0x008B,     /* R20998 - VSS_XHN2_1 */
-       [20999] = 0x7D00,     /* R20999 - VSS_XHN2_0 */
-       [21000] = 0x003A,     /* R21000 - VSS_XHN3_1 */
-       [21001] = 0x4100,     /* R21001 - VSS_XHN3_0 */
-       [21002] = 0x008C,     /* R21002 - VSS_XLA_1 */
-       [21003] = 0xFEE8,     /* R21003 - VSS_XLA_0 */
-       [21004] = 0x0078,     /* R21004 - VSS_XLB_1 */
-       [21005] = 0x0000,     /* R21005 - VSS_XLB_0 */
-       [21006] = 0x003F,     /* R21006 - VSS_XLG_1 */
-       [21007] = 0xB260,     /* R21007 - VSS_XLG_0 */
-       [21008] = 0x002D,     /* R21008 - VSS_PG2_1 */
-       [21009] = 0x1818,     /* R21009 - VSS_PG2_0 */
-       [21010] = 0x0020,     /* R21010 - VSS_PG_1 */
-       [21011] = 0x0000,     /* R21011 - VSS_PG_0 */
-       [21012] = 0x00F1,     /* R21012 - VSS_XTD1_1 */
-       [21013] = 0x8340,     /* R21013 - VSS_XTD1_0 */
-       [21014] = 0x00FB,     /* R21014 - VSS_XTD2_1 */
-       [21015] = 0x8300,     /* R21015 - VSS_XTD2_0 */
-       [21016] = 0x00EE,     /* R21016 - VSS_XTD3_1 */
-       [21017] = 0xAEC0,     /* R21017 - VSS_XTD3_0 */
-       [21018] = 0x00FB,     /* R21018 - VSS_XTD4_1 */
-       [21019] = 0xAC40,     /* R21019 - VSS_XTD4_0 */
-       [21020] = 0x00F1,     /* R21020 - VSS_XTD5_1 */
-       [21021] = 0x7F80,     /* R21021 - VSS_XTD5_0 */
-       [21022] = 0x00F4,     /* R21022 - VSS_XTD6_1 */
-       [21023] = 0x3B40,     /* R21023 - VSS_XTD6_0 */
-       [21024] = 0x00F5,     /* R21024 - VSS_XTD7_1 */
-       [21025] = 0xFB00,     /* R21025 - VSS_XTD7_0 */
-       [21026] = 0x00EA,     /* R21026 - VSS_XTD8_1 */
-       [21027] = 0x10C0,     /* R21027 - VSS_XTD8_0 */
-       [21028] = 0x00FC,     /* R21028 - VSS_XTD9_1 */
-       [21029] = 0xC580,     /* R21029 - VSS_XTD9_0 */
-       [21030] = 0x00E2,     /* R21030 - VSS_XTD10_1 */
-       [21031] = 0x75C0,     /* R21031 - VSS_XTD10_0 */
-       [21032] = 0x0004,     /* R21032 - VSS_XTD11_1 */
-       [21033] = 0xB480,     /* R21033 - VSS_XTD11_0 */
-       [21034] = 0x00D4,     /* R21034 - VSS_XTD12_1 */
-       [21035] = 0xF980,     /* R21035 - VSS_XTD12_0 */
-       [21036] = 0x0004,     /* R21036 - VSS_XTD13_1 */
-       [21037] = 0x9140,     /* R21037 - VSS_XTD13_0 */
-       [21038] = 0x00D8,     /* R21038 - VSS_XTD14_1 */
-       [21039] = 0xA480,     /* R21039 - VSS_XTD14_0 */
-       [21040] = 0x0002,     /* R21040 - VSS_XTD15_1 */
-       [21041] = 0x3DC0,     /* R21041 - VSS_XTD15_0 */
-       [21042] = 0x00CF,     /* R21042 - VSS_XTD16_1 */
-       [21043] = 0x7A80,     /* R21043 - VSS_XTD16_0 */
-       [21044] = 0x00DC,     /* R21044 - VSS_XTD17_1 */
-       [21045] = 0x0600,     /* R21045 - VSS_XTD17_0 */
-       [21046] = 0x00F2,     /* R21046 - VSS_XTD18_1 */
-       [21047] = 0xDAC0,     /* R21047 - VSS_XTD18_0 */
-       [21048] = 0x00BA,     /* R21048 - VSS_XTD19_1 */
-       [21049] = 0xF340,     /* R21049 - VSS_XTD19_0 */
-       [21050] = 0x000A,     /* R21050 - VSS_XTD20_1 */
-       [21051] = 0x7940,     /* R21051 - VSS_XTD20_0 */
-       [21052] = 0x001C,     /* R21052 - VSS_XTD21_1 */
-       [21053] = 0x0680,     /* R21053 - VSS_XTD21_0 */
-       [21054] = 0x00FD,     /* R21054 - VSS_XTD22_1 */
-       [21055] = 0x2D00,     /* R21055 - VSS_XTD22_0 */
-       [21056] = 0x001C,     /* R21056 - VSS_XTD23_1 */
-       [21057] = 0xE840,     /* R21057 - VSS_XTD23_0 */
-       [21058] = 0x000D,     /* R21058 - VSS_XTD24_1 */
-       [21059] = 0xDC40,     /* R21059 - VSS_XTD24_0 */
-       [21060] = 0x00FC,     /* R21060 - VSS_XTD25_1 */
-       [21061] = 0x9D00,     /* R21061 - VSS_XTD25_0 */
-       [21062] = 0x0009,     /* R21062 - VSS_XTD26_1 */
-       [21063] = 0x5580,     /* R21063 - VSS_XTD26_0 */
-       [21064] = 0x00FE,     /* R21064 - VSS_XTD27_1 */
-       [21065] = 0x7E80,     /* R21065 - VSS_XTD27_0 */
-       [21066] = 0x000E,     /* R21066 - VSS_XTD28_1 */
-       [21067] = 0xAB40,     /* R21067 - VSS_XTD28_0 */
-       [21068] = 0x00F9,     /* R21068 - VSS_XTD29_1 */
-       [21069] = 0x9880,     /* R21069 - VSS_XTD29_0 */
-       [21070] = 0x0009,     /* R21070 - VSS_XTD30_1 */
-       [21071] = 0x87C0,     /* R21071 - VSS_XTD30_0 */
-       [21072] = 0x00FD,     /* R21072 - VSS_XTD31_1 */
-       [21073] = 0x2C40,     /* R21073 - VSS_XTD31_0 */
-       [21074] = 0x0009,     /* R21074 - VSS_XTD32_1 */
-       [21075] = 0x4800,     /* R21075 - VSS_XTD32_0 */
-       [21076] = 0x0003,     /* R21076 - VSS_XTS1_1 */
-       [21077] = 0x5F40,     /* R21077 - VSS_XTS1_0 */
-       [21078] = 0x0000,     /* R21078 - VSS_XTS2_1 */
-       [21079] = 0x8700,     /* R21079 - VSS_XTS2_0 */
-       [21080] = 0x00FA,     /* R21080 - VSS_XTS3_1 */
-       [21081] = 0xE4C0,     /* R21081 - VSS_XTS3_0 */
-       [21082] = 0x0000,     /* R21082 - VSS_XTS4_1 */
-       [21083] = 0x0B40,     /* R21083 - VSS_XTS4_0 */
-       [21084] = 0x0004,     /* R21084 - VSS_XTS5_1 */
-       [21085] = 0xE180,     /* R21085 - VSS_XTS5_0 */
-       [21086] = 0x0001,     /* R21086 - VSS_XTS6_1 */
-       [21087] = 0x1F40,     /* R21087 - VSS_XTS6_0 */
-       [21088] = 0x00F8,     /* R21088 - VSS_XTS7_1 */
-       [21089] = 0xB000,     /* R21089 - VSS_XTS7_0 */
-       [21090] = 0x00FB,     /* R21090 - VSS_XTS8_1 */
-       [21091] = 0xCBC0,     /* R21091 - VSS_XTS8_0 */
-       [21092] = 0x0004,     /* R21092 - VSS_XTS9_1 */
-       [21093] = 0xF380,     /* R21093 - VSS_XTS9_0 */
-       [21094] = 0x0007,     /* R21094 - VSS_XTS10_1 */
-       [21095] = 0xDF40,     /* R21095 - VSS_XTS10_0 */
-       [21096] = 0x00FF,     /* R21096 - VSS_XTS11_1 */
-       [21097] = 0x0700,     /* R21097 - VSS_XTS11_0 */
-       [21098] = 0x00EF,     /* R21098 - VSS_XTS12_1 */
-       [21099] = 0xD700,     /* R21099 - VSS_XTS12_0 */
-       [21100] = 0x00FB,     /* R21100 - VSS_XTS13_1 */
-       [21101] = 0xAF40,     /* R21101 - VSS_XTS13_0 */
-       [21102] = 0x0010,     /* R21102 - VSS_XTS14_1 */
-       [21103] = 0x8A80,     /* R21103 - VSS_XTS14_0 */
-       [21104] = 0x0011,     /* R21104 - VSS_XTS15_1 */
-       [21105] = 0x07C0,     /* R21105 - VSS_XTS15_0 */
-       [21106] = 0x00E0,     /* R21106 - VSS_XTS16_1 */
-       [21107] = 0x0800,     /* R21107 - VSS_XTS16_0 */
-       [21108] = 0x00D2,     /* R21108 - VSS_XTS17_1 */
-       [21109] = 0x7600,     /* R21109 - VSS_XTS17_0 */
-       [21110] = 0x0020,     /* R21110 - VSS_XTS18_1 */
-       [21111] = 0xCF40,     /* R21111 - VSS_XTS18_0 */
-       [21112] = 0x0030,     /* R21112 - VSS_XTS19_1 */
-       [21113] = 0x2340,     /* R21113 - VSS_XTS19_0 */
-       [21114] = 0x00FD,     /* R21114 - VSS_XTS20_1 */
-       [21115] = 0x69C0,     /* R21115 - VSS_XTS20_0 */
-       [21116] = 0x0028,     /* R21116 - VSS_XTS21_1 */
-       [21117] = 0x3500,     /* R21117 - VSS_XTS21_0 */
-       [21118] = 0x0006,     /* R21118 - VSS_XTS22_1 */
-       [21119] = 0x3300,     /* R21119 - VSS_XTS22_0 */
-       [21120] = 0x00D9,     /* R21120 - VSS_XTS23_1 */
-       [21121] = 0xF6C0,     /* R21121 - VSS_XTS23_0 */
-       [21122] = 0x00F3,     /* R21122 - VSS_XTS24_1 */
-       [21123] = 0x3340,     /* R21123 - VSS_XTS24_0 */
-       [21124] = 0x000F,     /* R21124 - VSS_XTS25_1 */
-       [21125] = 0x4200,     /* R21125 - VSS_XTS25_0 */
-       [21126] = 0x0004,     /* R21126 - VSS_XTS26_1 */
-       [21127] = 0x0C80,     /* R21127 - VSS_XTS26_0 */
-       [21128] = 0x00FB,     /* R21128 - VSS_XTS27_1 */
-       [21129] = 0x3F80,     /* R21129 - VSS_XTS27_0 */
-       [21130] = 0x00F7,     /* R21130 - VSS_XTS28_1 */
-       [21131] = 0x57C0,     /* R21131 - VSS_XTS28_0 */
-       [21132] = 0x0003,     /* R21132 - VSS_XTS29_1 */
-       [21133] = 0x5400,     /* R21133 - VSS_XTS29_0 */
-       [21134] = 0x0000,     /* R21134 - VSS_XTS30_1 */
-       [21135] = 0xC6C0,     /* R21135 - VSS_XTS30_0 */
-       [21136] = 0x0003,     /* R21136 - VSS_XTS31_1 */
-       [21137] = 0x12C0,     /* R21137 - VSS_XTS31_0 */
-       [21138] = 0x00FD,     /* R21138 - VSS_XTS32_1 */
-       [21139] = 0x8580,     /* R21139 - VSS_XTS32_0 */
+static struct reg_default wm8962_reg[] = {
+       { 0, 0x009F },   /* R0     - Left Input volume */
+       { 1, 0x049F },   /* R1     - Right Input volume */
+       { 2, 0x0000 },   /* R2     - HPOUTL volume */
+       { 3, 0x0000 },   /* R3     - HPOUTR volume */
+       { 4, 0x0020 },   /* R4     - Clocking1 */
+       { 5, 0x0018 },   /* R5     - ADC & DAC Control 1 */
+       { 6, 0x2008 },   /* R6     - ADC & DAC Control 2 */
+       { 7, 0x000A },   /* R7     - Audio Interface 0 */
+       { 8, 0x01E4 },   /* R8     - Clocking2 */
+       { 9, 0x0300 },   /* R9     - Audio Interface 1 */
+       { 10, 0x00C0 },  /* R10    - Left DAC volume */
+       { 11, 0x00C0 },  /* R11    - Right DAC volume */
+
+       { 14, 0x0040 },   /* R14    - Audio Interface 2 */
+       { 15, 0x6243 },   /* R15    - Software Reset */
+
+       { 17, 0x007B },   /* R17    - ALC1 */
+       { 18, 0x0000 },   /* R18    - ALC2 */
+       { 19, 0x1C32 },   /* R19    - ALC3 */
+       { 20, 0x3200 },   /* R20    - Noise Gate */
+       { 21, 0x00C0 },   /* R21    - Left ADC volume */
+       { 22, 0x00C0 },   /* R22    - Right ADC volume */
+       { 23, 0x0160 },   /* R23    - Additional control(1) */
+       { 24, 0x0000 },   /* R24    - Additional control(2) */
+       { 25, 0x0000 },   /* R25    - Pwr Mgmt (1) */
+       { 26, 0x0000 },   /* R26    - Pwr Mgmt (2) */
+       { 27, 0x0010 },   /* R27    - Additional Control (3) */
+       { 28, 0x0000 },   /* R28    - Anti-pop */
+
+       { 30, 0x005E },   /* R30    - Clocking 3 */
+       { 31, 0x0000 },   /* R31    - Input mixer control (1) */
+       { 32, 0x0145 },   /* R32    - Left input mixer volume */
+       { 33, 0x0145 },   /* R33    - Right input mixer volume */
+       { 34, 0x0009 },   /* R34    - Input mixer control (2) */
+       { 35, 0x0003 },   /* R35    - Input bias control */
+       { 37, 0x0008 },   /* R37    - Left input PGA control */
+       { 38, 0x0008 },   /* R38    - Right input PGA control */
+
+       { 40, 0x0000 },   /* R40    - SPKOUTL volume */
+       { 41, 0x0000 },   /* R41    - SPKOUTR volume */
+
+       { 47, 0x0000 },   /* R47    - Thermal Shutdown Status */
+       { 48, 0x8027 },   /* R48    - Additional Control (4) */
+       { 49, 0x0010 },   /* R49    - Class D Control 1 */
+
+       { 51, 0x0003 },   /* R51    - Class D Control 2 */
+
+       { 56, 0x0506 },   /* R56    - Clocking 4 */
+       { 57, 0x0000 },   /* R57    - DAC DSP Mixing (1) */
+       { 58, 0x0000 },   /* R58    - DAC DSP Mixing (2) */
+
+       { 60, 0x0300 },   /* R60    - DC Servo 0 */
+       { 61, 0x0300 },   /* R61    - DC Servo 1 */
+
+       { 64, 0x0810 },   /* R64    - DC Servo 4 */
+
+       { 66, 0x0000 },   /* R66    - DC Servo 6 */
+
+       { 68, 0x001B },   /* R68    - Analogue PGA Bias */
+       { 69, 0x0000 },   /* R69    - Analogue HP 0 */
+
+       { 71, 0x01FB },   /* R71    - Analogue HP 2 */
+       { 72, 0x0000 },   /* R72    - Charge Pump 1 */
+
+       { 82, 0x0004 },   /* R82    - Charge Pump B */
+
+       { 87, 0x0000 },   /* R87    - Write Sequencer Control 1 */
+
+       { 90, 0x0000 },   /* R90    - Write Sequencer Control 2 */
+
+       { 93, 0x0000 },   /* R93    - Write Sequencer Control 3 */
+       { 94, 0x0000 },   /* R94    - Control Interface */
+
+       { 99, 0x0000 },   /* R99    - Mixer Enables */
+       { 100, 0x0000 },   /* R100   - Headphone Mixer (1) */
+       { 101, 0x0000 },   /* R101   - Headphone Mixer (2) */
+       { 102, 0x013F },   /* R102   - Headphone Mixer (3) */
+       { 103, 0x013F },   /* R103   - Headphone Mixer (4) */
+
+       { 105, 0x0000 },   /* R105   - Speaker Mixer (1) */
+       { 106, 0x0000 },   /* R106   - Speaker Mixer (2) */
+       { 107, 0x013F },   /* R107   - Speaker Mixer (3) */
+       { 108, 0x013F },   /* R108   - Speaker Mixer (4) */
+       { 109, 0x0003 },   /* R109   - Speaker Mixer (5) */
+       { 110, 0x0002 },   /* R110   - Beep Generator (1) */
+
+       { 115, 0x0006 },   /* R115   - Oscillator Trim (3) */
+       { 116, 0x0026 },   /* R116   - Oscillator Trim (4) */
+
+       { 119, 0x0000 },   /* R119   - Oscillator Trim (7) */
+
+       { 124, 0x0011 },   /* R124   - Analogue Clocking1 */
+       { 125, 0x004B },   /* R125   - Analogue Clocking2 */
+       { 126, 0x000D },   /* R126   - Analogue Clocking3 */
+       { 127, 0x0000 },   /* R127   - PLL Software Reset */
+
+       { 129, 0x0000 },   /* R129   - PLL2 */
+
+       { 131, 0x0000 },   /* R131   - PLL 4 */
+
+       { 136, 0x0067 },   /* R136   - PLL 9 */
+       { 137, 0x001C },   /* R137   - PLL 10 */
+       { 138, 0x0071 },   /* R138   - PLL 11 */
+       { 139, 0x00C7 },   /* R139   - PLL 12 */
+       { 140, 0x0067 },   /* R140   - PLL 13 */
+       { 141, 0x0048 },   /* R141   - PLL 14 */
+       { 142, 0x0022 },   /* R142   - PLL 15 */
+       { 143, 0x0097 },   /* R143   - PLL 16 */
+
+       { 155, 0x000C },   /* R155   - FLL Control (1) */
+       { 156, 0x0039 },   /* R156   - FLL Control (2) */
+       { 157, 0x0180 },   /* R157   - FLL Control (3) */
+
+       { 159, 0x0032 },   /* R159   - FLL Control (5) */
+       { 160, 0x0018 },   /* R160   - FLL Control (6) */
+       { 161, 0x007D },   /* R161   - FLL Control (7) */
+       { 162, 0x0008 },   /* R162   - FLL Control (8) */
+
+       { 252, 0x0005 },   /* R252   - General test 1 */
+
+       { 256, 0x0000 },   /* R256   - DF1 */
+       { 257, 0x0000 },   /* R257   - DF2 */
+       { 258, 0x0000 },   /* R258   - DF3 */
+       { 259, 0x0000 },   /* R259   - DF4 */
+       { 260, 0x0000 },   /* R260   - DF5 */
+       { 261, 0x0000 },   /* R261   - DF6 */
+       { 262, 0x0000 },   /* R262   - DF7 */
+
+       { 264, 0x0000 },   /* R264   - LHPF1 */
+       { 265, 0x0000 },   /* R265   - LHPF2 */
+
+       { 268, 0x0000 },   /* R268   - THREED1 */
+       { 269, 0x0000 },   /* R269   - THREED2 */
+       { 270, 0x0000 },   /* R270   - THREED3 */
+       { 271, 0x0000 },   /* R271   - THREED4 */
+
+       { 276, 0x000C },   /* R276   - DRC 1 */
+       { 277, 0x0925 },   /* R277   - DRC 2 */
+       { 278, 0x0000 },   /* R278   - DRC 3 */
+       { 279, 0x0000 },   /* R279   - DRC 4 */
+       { 280, 0x0000 },   /* R280   - DRC 5 */
+
+       { 285, 0x0000 },   /* R285   - Tloopback */
+
+       { 335, 0x0004 },   /* R335   - EQ1 */
+       { 336, 0x6318 },   /* R336   - EQ2 */
+       { 337, 0x6300 },   /* R337   - EQ3 */
+       { 338, 0x0FCA },   /* R338   - EQ4 */
+       { 339, 0x0400 },   /* R339   - EQ5 */
+       { 340, 0x00D8 },   /* R340   - EQ6 */
+       { 341, 0x1EB5 },   /* R341   - EQ7 */
+       { 342, 0xF145 },   /* R342   - EQ8 */
+       { 343, 0x0B75 },   /* R343   - EQ9 */
+       { 344, 0x01C5 },   /* R344   - EQ10 */
+       { 345, 0x1C58 },   /* R345   - EQ11 */
+       { 346, 0xF373 },   /* R346   - EQ12 */
+       { 347, 0x0A54 },   /* R347   - EQ13 */
+       { 348, 0x0558 },   /* R348   - EQ14 */
+       { 349, 0x168E },   /* R349   - EQ15 */
+       { 350, 0xF829 },   /* R350   - EQ16 */
+       { 351, 0x07AD },   /* R351   - EQ17 */
+       { 352, 0x1103 },   /* R352   - EQ18 */
+       { 353, 0x0564 },   /* R353   - EQ19 */
+       { 354, 0x0559 },   /* R354   - EQ20 */
+       { 355, 0x4000 },   /* R355   - EQ21 */
+       { 356, 0x6318 },   /* R356   - EQ22 */
+       { 357, 0x6300 },   /* R357   - EQ23 */
+       { 358, 0x0FCA },   /* R358   - EQ24 */
+       { 359, 0x0400 },   /* R359   - EQ25 */
+       { 360, 0x00D8 },   /* R360   - EQ26 */
+       { 361, 0x1EB5 },   /* R361   - EQ27 */
+       { 362, 0xF145 },   /* R362   - EQ28 */
+       { 363, 0x0B75 },   /* R363   - EQ29 */
+       { 364, 0x01C5 },   /* R364   - EQ30 */
+       { 365, 0x1C58 },   /* R365   - EQ31 */
+       { 366, 0xF373 },   /* R366   - EQ32 */
+       { 367, 0x0A54 },   /* R367   - EQ33 */
+       { 368, 0x0558 },   /* R368   - EQ34 */
+       { 369, 0x168E },   /* R369   - EQ35 */
+       { 370, 0xF829 },   /* R370   - EQ36 */
+       { 371, 0x07AD },   /* R371   - EQ37 */
+       { 372, 0x1103 },   /* R372   - EQ38 */
+       { 373, 0x0564 },   /* R373   - EQ39 */
+       { 374, 0x0559 },   /* R374   - EQ40 */
+       { 375, 0x4000 },   /* R375   - EQ41 */
+
+       { 513, 0x0000 },   /* R513   - GPIO 2 */
+       { 514, 0x0000 },   /* R514   - GPIO 3 */
+
+       { 516, 0x8100 },   /* R516   - GPIO 5 */
+       { 517, 0x8100 },   /* R517   - GPIO 6 */
+
+       { 560, 0x0000 },   /* R560   - Interrupt Status 1 */
+       { 561, 0x0000 },   /* R561   - Interrupt Status 2 */
+
+       { 568, 0x0030 },   /* R568   - Interrupt Status 1 Mask */
+       { 569, 0xFFED },   /* R569   - Interrupt Status 2 Mask */
+
+       { 576, 0x0000 },   /* R576   - Interrupt Control */
+
+       { 584, 0x002D },   /* R584   - IRQ Debounce */
+
+       { 586, 0x0000 },   /* R586   -  MICINT Source Pol */
+
+       { 768, 0x1C00 },   /* R768   - DSP2 Power Management */
+
+       { 1037, 0x0000 },   /* R1037  - DSP2_ExecControl */
+
+       { 8192, 0x0000 },   /* R8192  - DSP2 Instruction RAM 0 */
+
+       { 9216, 0x0030 },   /* R9216  - DSP2 Address RAM 2 */
+       { 9217, 0x0000 },   /* R9217  - DSP2 Address RAM 1 */
+       { 9218, 0x0000 },   /* R9218  - DSP2 Address RAM 0 */
+
+       { 12288, 0x0000 },   /* R12288 - DSP2 Data1 RAM 1 */
+       { 12289, 0x0000 },   /* R12289 - DSP2 Data1 RAM 0 */
+
+       { 13312, 0x0000 },   /* R13312 - DSP2 Data2 RAM 1 */
+       { 13313, 0x0000 },   /* R13313 - DSP2 Data2 RAM 0 */
+
+       { 14336, 0x0000 },   /* R14336 - DSP2 Data3 RAM 1 */
+       { 14337, 0x0000 },   /* R14337 - DSP2 Data3 RAM 0 */
+
+       { 15360, 0x000A },   /* R15360 - DSP2 Coeff RAM 0 */
+
+       { 16384, 0x0000 },   /* R16384 - RETUNEADC_SHARED_COEFF_1 */
+       { 16385, 0x0000 },   /* R16385 - RETUNEADC_SHARED_COEFF_0 */
+       { 16386, 0x0000 },   /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
+       { 16387, 0x0000 },   /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
+       { 16388, 0x0000 },   /* R16388 - SOUNDSTAGE_ENABLES_1 */
+       { 16389, 0x0000 },   /* R16389 - SOUNDSTAGE_ENABLES_0 */
+
+       { 16896, 0x0002 },   /* R16896 - HDBASS_AI_1 */
+       { 16897, 0xBD12 },   /* R16897 - HDBASS_AI_0 */
+       { 16898, 0x007C },   /* R16898 - HDBASS_AR_1 */
+       { 16899, 0x586C },   /* R16899 - HDBASS_AR_0 */
+       { 16900, 0x0053 },   /* R16900 - HDBASS_B_1 */
+       { 16901, 0x8121 },   /* R16901 - HDBASS_B_0 */
+       { 16902, 0x003F },   /* R16902 - HDBASS_K_1 */
+       { 16903, 0x8BD8 },   /* R16903 - HDBASS_K_0 */
+       { 16904, 0x0032 },   /* R16904 - HDBASS_N1_1 */
+       { 16905, 0xF52D },   /* R16905 - HDBASS_N1_0 */
+       { 16906, 0x0065 },   /* R16906 - HDBASS_N2_1 */
+       { 16907, 0xAC8C },   /* R16907 - HDBASS_N2_0 */
+       { 16908, 0x006B },   /* R16908 - HDBASS_N3_1 */
+       { 16909, 0xE087 },   /* R16909 - HDBASS_N3_0 */
+       { 16910, 0x0072 },   /* R16910 - HDBASS_N4_1 */
+       { 16911, 0x1483 },   /* R16911 - HDBASS_N4_0 */
+       { 16912, 0x0072 },   /* R16912 - HDBASS_N5_1 */
+       { 16913, 0x1483 },   /* R16913 - HDBASS_N5_0 */
+       { 16914, 0x0043 },   /* R16914 - HDBASS_X1_1 */
+       { 16915, 0x3525 },   /* R16915 - HDBASS_X1_0 */
+       { 16916, 0x0006 },   /* R16916 - HDBASS_X2_1 */
+       { 16917, 0x6A4A },   /* R16917 - HDBASS_X2_0 */
+       { 16918, 0x0043 },   /* R16918 - HDBASS_X3_1 */
+       { 16919, 0x6079 },   /* R16919 - HDBASS_X3_0 */
+       { 16920, 0x0008 },   /* R16920 - HDBASS_ATK_1 */
+       { 16921, 0x0000 },   /* R16921 - HDBASS_ATK_0 */
+       { 16922, 0x0001 },   /* R16922 - HDBASS_DCY_1 */
+       { 16923, 0x0000 },   /* R16923 - HDBASS_DCY_0 */
+       { 16924, 0x0059 },   /* R16924 - HDBASS_PG_1 */
+       { 16925, 0x999A },   /* R16925 - HDBASS_PG_0 */
+
+       { 17048, 0x0083 },   /* R17408 - HPF_C_1 */
+       { 17049, 0x98AD },   /* R17409 - HPF_C_0 */
+
+       { 17920, 0x007F },   /* R17920 - ADCL_RETUNE_C1_1 */
+       { 17921, 0xFFFF },   /* R17921 - ADCL_RETUNE_C1_0 */
+       { 17922, 0x0000 },   /* R17922 - ADCL_RETUNE_C2_1 */
+       { 17923, 0x0000 },   /* R17923 - ADCL_RETUNE_C2_0 */
+       { 17924, 0x0000 },   /* R17924 - ADCL_RETUNE_C3_1 */
+       { 17925, 0x0000 },   /* R17925 - ADCL_RETUNE_C3_0 */
+       { 17926, 0x0000 },   /* R17926 - ADCL_RETUNE_C4_1 */
+       { 17927, 0x0000 },   /* R17927 - ADCL_RETUNE_C4_0 */
+       { 17928, 0x0000 },   /* R17928 - ADCL_RETUNE_C5_1 */
+       { 17929, 0x0000 },   /* R17929 - ADCL_RETUNE_C5_0 */
+       { 17930, 0x0000 },   /* R17930 - ADCL_RETUNE_C6_1 */
+       { 17931, 0x0000 },   /* R17931 - ADCL_RETUNE_C6_0 */
+       { 17932, 0x0000 },   /* R17932 - ADCL_RETUNE_C7_1 */
+       { 17933, 0x0000 },   /* R17933 - ADCL_RETUNE_C7_0 */
+       { 17934, 0x0000 },   /* R17934 - ADCL_RETUNE_C8_1 */
+       { 17935, 0x0000 },   /* R17935 - ADCL_RETUNE_C8_0 */
+       { 17936, 0x0000 },   /* R17936 - ADCL_RETUNE_C9_1 */
+       { 17937, 0x0000 },   /* R17937 - ADCL_RETUNE_C9_0 */
+       { 17938, 0x0000 },   /* R17938 - ADCL_RETUNE_C10_1 */
+       { 17939, 0x0000 },   /* R17939 - ADCL_RETUNE_C10_0 */
+       { 17940, 0x0000 },   /* R17940 - ADCL_RETUNE_C11_1 */
+       { 17941, 0x0000 },   /* R17941 - ADCL_RETUNE_C11_0 */
+       { 17942, 0x0000 },   /* R17942 - ADCL_RETUNE_C12_1 */
+       { 17943, 0x0000 },   /* R17943 - ADCL_RETUNE_C12_0 */
+       { 17944, 0x0000 },   /* R17944 - ADCL_RETUNE_C13_1 */
+       { 17945, 0x0000 },   /* R17945 - ADCL_RETUNE_C13_0 */
+       { 17946, 0x0000 },   /* R17946 - ADCL_RETUNE_C14_1 */
+       { 17947, 0x0000 },   /* R17947 - ADCL_RETUNE_C14_0 */
+       { 17948, 0x0000 },   /* R17948 - ADCL_RETUNE_C15_1 */
+       { 17949, 0x0000 },   /* R17949 - ADCL_RETUNE_C15_0 */
+       { 17950, 0x0000 },   /* R17950 - ADCL_RETUNE_C16_1 */
+       { 17951, 0x0000 },   /* R17951 - ADCL_RETUNE_C16_0 */
+       { 17952, 0x0000 },   /* R17952 - ADCL_RETUNE_C17_1 */
+       { 17953, 0x0000 },   /* R17953 - ADCL_RETUNE_C17_0 */
+       { 17954, 0x0000 },   /* R17954 - ADCL_RETUNE_C18_1 */
+       { 17955, 0x0000 },   /* R17955 - ADCL_RETUNE_C18_0 */
+       { 17956, 0x0000 },   /* R17956 - ADCL_RETUNE_C19_1 */
+       { 17957, 0x0000 },   /* R17957 - ADCL_RETUNE_C19_0 */
+       { 17958, 0x0000 },   /* R17958 - ADCL_RETUNE_C20_1 */
+       { 17959, 0x0000 },   /* R17959 - ADCL_RETUNE_C20_0 */
+       { 17960, 0x0000 },   /* R17960 - ADCL_RETUNE_C21_1 */
+       { 17961, 0x0000 },   /* R17961 - ADCL_RETUNE_C21_0 */
+       { 17962, 0x0000 },   /* R17962 - ADCL_RETUNE_C22_1 */
+       { 17963, 0x0000 },   /* R17963 - ADCL_RETUNE_C22_0 */
+       { 17964, 0x0000 },   /* R17964 - ADCL_RETUNE_C23_1 */
+       { 17965, 0x0000 },   /* R17965 - ADCL_RETUNE_C23_0 */
+       { 17966, 0x0000 },   /* R17966 - ADCL_RETUNE_C24_1 */
+       { 17967, 0x0000 },   /* R17967 - ADCL_RETUNE_C24_0 */
+       { 17968, 0x0000 },   /* R17968 - ADCL_RETUNE_C25_1 */
+       { 17969, 0x0000 },   /* R17969 - ADCL_RETUNE_C25_0 */
+       { 17970, 0x0000 },   /* R17970 - ADCL_RETUNE_C26_1 */
+       { 17971, 0x0000 },   /* R17971 - ADCL_RETUNE_C26_0 */
+       { 17972, 0x0000 },   /* R17972 - ADCL_RETUNE_C27_1 */
+       { 17973, 0x0000 },   /* R17973 - ADCL_RETUNE_C27_0 */
+       { 17974, 0x0000 },   /* R17974 - ADCL_RETUNE_C28_1 */
+       { 17975, 0x0000 },   /* R17975 - ADCL_RETUNE_C28_0 */
+       { 17976, 0x0000 },   /* R17976 - ADCL_RETUNE_C29_1 */
+       { 17977, 0x0000 },   /* R17977 - ADCL_RETUNE_C29_0 */
+       { 17978, 0x0000 },   /* R17978 - ADCL_RETUNE_C30_1 */
+       { 17979, 0x0000 },   /* R17979 - ADCL_RETUNE_C30_0 */
+       { 17980, 0x0000 },   /* R17980 - ADCL_RETUNE_C31_1 */
+       { 17981, 0x0000 },   /* R17981 - ADCL_RETUNE_C31_0 */
+       { 17982, 0x0000 },   /* R17982 - ADCL_RETUNE_C32_1 */
+       { 17983, 0x0000 },   /* R17983 - ADCL_RETUNE_C32_0 */
+
+       { 18432, 0x0020 },   /* R18432 - RETUNEADC_PG2_1 */
+       { 18433, 0x0000 },   /* R18433 - RETUNEADC_PG2_0 */
+       { 18434, 0x0040 },   /* R18434 - RETUNEADC_PG_1 */
+       { 18435, 0x0000 },   /* R18435 - RETUNEADC_PG_0 */
+
+       { 18944, 0x007F },   /* R18944 - ADCR_RETUNE_C1_1 */
+       { 18945, 0xFFFF },   /* R18945 - ADCR_RETUNE_C1_0 */
+       { 18946, 0x0000 },   /* R18946 - ADCR_RETUNE_C2_1 */
+       { 18947, 0x0000 },   /* R18947 - ADCR_RETUNE_C2_0 */
+       { 18948, 0x0000 },   /* R18948 - ADCR_RETUNE_C3_1 */
+       { 18949, 0x0000 },   /* R18949 - ADCR_RETUNE_C3_0 */
+       { 18950, 0x0000 },   /* R18950 - ADCR_RETUNE_C4_1 */
+       { 18951, 0x0000 },   /* R18951 - ADCR_RETUNE_C4_0 */
+       { 18952, 0x0000 },   /* R18952 - ADCR_RETUNE_C5_1 */
+       { 18953, 0x0000 },   /* R18953 - ADCR_RETUNE_C5_0 */
+       { 18954, 0x0000 },   /* R18954 - ADCR_RETUNE_C6_1 */
+       { 18955, 0x0000 },   /* R18955 - ADCR_RETUNE_C6_0 */
+       { 18956, 0x0000 },   /* R18956 - ADCR_RETUNE_C7_1 */
+       { 18957, 0x0000 },   /* R18957 - ADCR_RETUNE_C7_0 */
+       { 18958, 0x0000 },   /* R18958 - ADCR_RETUNE_C8_1 */
+       { 18959, 0x0000 },   /* R18959 - ADCR_RETUNE_C8_0 */
+       { 18960, 0x0000 },   /* R18960 - ADCR_RETUNE_C9_1 */
+       { 18961, 0x0000 },   /* R18961 - ADCR_RETUNE_C9_0 */
+       { 18962, 0x0000 },   /* R18962 - ADCR_RETUNE_C10_1 */
+       { 18963, 0x0000 },   /* R18963 - ADCR_RETUNE_C10_0 */
+       { 18964, 0x0000 },   /* R18964 - ADCR_RETUNE_C11_1 */
+       { 18965, 0x0000 },   /* R18965 - ADCR_RETUNE_C11_0 */
+       { 18966, 0x0000 },   /* R18966 - ADCR_RETUNE_C12_1 */
+       { 18967, 0x0000 },   /* R18967 - ADCR_RETUNE_C12_0 */
+       { 18968, 0x0000 },   /* R18968 - ADCR_RETUNE_C13_1 */
+       { 18969, 0x0000 },   /* R18969 - ADCR_RETUNE_C13_0 */
+       { 18970, 0x0000 },   /* R18970 - ADCR_RETUNE_C14_1 */
+       { 18971, 0x0000 },   /* R18971 - ADCR_RETUNE_C14_0 */
+       { 18972, 0x0000 },   /* R18972 - ADCR_RETUNE_C15_1 */
+       { 18973, 0x0000 },   /* R18973 - ADCR_RETUNE_C15_0 */
+       { 18974, 0x0000 },   /* R18974 - ADCR_RETUNE_C16_1 */
+       { 18975, 0x0000 },   /* R18975 - ADCR_RETUNE_C16_0 */
+       { 18976, 0x0000 },   /* R18976 - ADCR_RETUNE_C17_1 */
+       { 18977, 0x0000 },   /* R18977 - ADCR_RETUNE_C17_0 */
+       { 18978, 0x0000 },   /* R18978 - ADCR_RETUNE_C18_1 */
+       { 18979, 0x0000 },   /* R18979 - ADCR_RETUNE_C18_0 */
+       { 18980, 0x0000 },   /* R18980 - ADCR_RETUNE_C19_1 */
+       { 18981, 0x0000 },   /* R18981 - ADCR_RETUNE_C19_0 */
+       { 18982, 0x0000 },   /* R18982 - ADCR_RETUNE_C20_1 */
+       { 18983, 0x0000 },   /* R18983 - ADCR_RETUNE_C20_0 */
+       { 18984, 0x0000 },   /* R18984 - ADCR_RETUNE_C21_1 */
+       { 18985, 0x0000 },   /* R18985 - ADCR_RETUNE_C21_0 */
+       { 18986, 0x0000 },   /* R18986 - ADCR_RETUNE_C22_1 */
+       { 18987, 0x0000 },   /* R18987 - ADCR_RETUNE_C22_0 */
+       { 18988, 0x0000 },   /* R18988 - ADCR_RETUNE_C23_1 */
+       { 18989, 0x0000 },   /* R18989 - ADCR_RETUNE_C23_0 */
+       { 18990, 0x0000 },   /* R18990 - ADCR_RETUNE_C24_1 */
+       { 18991, 0x0000 },   /* R18991 - ADCR_RETUNE_C24_0 */
+       { 18992, 0x0000 },   /* R18992 - ADCR_RETUNE_C25_1 */
+       { 18993, 0x0000 },   /* R18993 - ADCR_RETUNE_C25_0 */
+       { 18994, 0x0000 },   /* R18994 - ADCR_RETUNE_C26_1 */
+       { 18995, 0x0000 },   /* R18995 - ADCR_RETUNE_C26_0 */
+       { 18996, 0x0000 },   /* R18996 - ADCR_RETUNE_C27_1 */
+       { 18997, 0x0000 },   /* R18997 - ADCR_RETUNE_C27_0 */
+       { 18998, 0x0000 },   /* R18998 - ADCR_RETUNE_C28_1 */
+       { 18999, 0x0000 },   /* R18999 - ADCR_RETUNE_C28_0 */
+       { 19000, 0x0000 },   /* R19000 - ADCR_RETUNE_C29_1 */
+       { 19001, 0x0000 },   /* R19001 - ADCR_RETUNE_C29_0 */
+       { 19002, 0x0000 },   /* R19002 - ADCR_RETUNE_C30_1 */
+       { 19003, 0x0000 },   /* R19003 - ADCR_RETUNE_C30_0 */
+       { 19004, 0x0000 },   /* R19004 - ADCR_RETUNE_C31_1 */
+       { 19005, 0x0000 },   /* R19005 - ADCR_RETUNE_C31_0 */
+       { 19006, 0x0000 },   /* R19006 - ADCR_RETUNE_C32_1 */
+       { 19007, 0x0000 },   /* R19007 - ADCR_RETUNE_C32_0 */
+
+       { 19456, 0x007F },   /* R19456 - DACL_RETUNE_C1_1 */
+       { 19457, 0xFFFF },   /* R19457 - DACL_RETUNE_C1_0 */
+       { 19458, 0x0000 },   /* R19458 - DACL_RETUNE_C2_1 */
+       { 19459, 0x0000 },   /* R19459 - DACL_RETUNE_C2_0 */
+       { 19460, 0x0000 },   /* R19460 - DACL_RETUNE_C3_1 */
+       { 19461, 0x0000 },   /* R19461 - DACL_RETUNE_C3_0 */
+       { 19462, 0x0000 },   /* R19462 - DACL_RETUNE_C4_1 */
+       { 19463, 0x0000 },   /* R19463 - DACL_RETUNE_C4_0 */
+       { 19464, 0x0000 },   /* R19464 - DACL_RETUNE_C5_1 */
+       { 19465, 0x0000 },   /* R19465 - DACL_RETUNE_C5_0 */
+       { 19466, 0x0000 },   /* R19466 - DACL_RETUNE_C6_1 */
+       { 19467, 0x0000 },   /* R19467 - DACL_RETUNE_C6_0 */
+       { 19468, 0x0000 },   /* R19468 - DACL_RETUNE_C7_1 */
+       { 19469, 0x0000 },   /* R19469 - DACL_RETUNE_C7_0 */
+       { 19470, 0x0000 },   /* R19470 - DACL_RETUNE_C8_1 */
+       { 19471, 0x0000 },   /* R19471 - DACL_RETUNE_C8_0 */
+       { 19472, 0x0000 },   /* R19472 - DACL_RETUNE_C9_1 */
+       { 19473, 0x0000 },   /* R19473 - DACL_RETUNE_C9_0 */
+       { 19474, 0x0000 },   /* R19474 - DACL_RETUNE_C10_1 */
+       { 19475, 0x0000 },   /* R19475 - DACL_RETUNE_C10_0 */
+       { 19476, 0x0000 },   /* R19476 - DACL_RETUNE_C11_1 */
+       { 19477, 0x0000 },   /* R19477 - DACL_RETUNE_C11_0 */
+       { 19478, 0x0000 },   /* R19478 - DACL_RETUNE_C12_1 */
+       { 19479, 0x0000 },   /* R19479 - DACL_RETUNE_C12_0 */
+       { 19480, 0x0000 },   /* R19480 - DACL_RETUNE_C13_1 */
+       { 19481, 0x0000 },   /* R19481 - DACL_RETUNE_C13_0 */
+       { 19482, 0x0000 },   /* R19482 - DACL_RETUNE_C14_1 */
+       { 19483, 0x0000 },   /* R19483 - DACL_RETUNE_C14_0 */
+       { 19484, 0x0000 },   /* R19484 - DACL_RETUNE_C15_1 */
+       { 19485, 0x0000 },   /* R19485 - DACL_RETUNE_C15_0 */
+       { 19486, 0x0000 },   /* R19486 - DACL_RETUNE_C16_1 */
+       { 19487, 0x0000 },   /* R19487 - DACL_RETUNE_C16_0 */
+       { 19488, 0x0000 },   /* R19488 - DACL_RETUNE_C17_1 */
+       { 19489, 0x0000 },   /* R19489 - DACL_RETUNE_C17_0 */
+       { 19490, 0x0000 },   /* R19490 - DACL_RETUNE_C18_1 */
+       { 19491, 0x0000 },   /* R19491 - DACL_RETUNE_C18_0 */
+       { 19492, 0x0000 },   /* R19492 - DACL_RETUNE_C19_1 */
+       { 19493, 0x0000 },   /* R19493 - DACL_RETUNE_C19_0 */
+       { 19494, 0x0000 },   /* R19494 - DACL_RETUNE_C20_1 */
+       { 19495, 0x0000 },   /* R19495 - DACL_RETUNE_C20_0 */
+       { 19496, 0x0000 },   /* R19496 - DACL_RETUNE_C21_1 */
+       { 19497, 0x0000 },   /* R19497 - DACL_RETUNE_C21_0 */
+       { 19498, 0x0000 },   /* R19498 - DACL_RETUNE_C22_1 */
+       { 19499, 0x0000 },   /* R19499 - DACL_RETUNE_C22_0 */
+       { 19500, 0x0000 },   /* R19500 - DACL_RETUNE_C23_1 */
+       { 19501, 0x0000 },   /* R19501 - DACL_RETUNE_C23_0 */
+       { 19502, 0x0000 },   /* R19502 - DACL_RETUNE_C24_1 */
+       { 19503, 0x0000 },   /* R19503 - DACL_RETUNE_C24_0 */
+       { 19504, 0x0000 },   /* R19504 - DACL_RETUNE_C25_1 */
+       { 19505, 0x0000 },   /* R19505 - DACL_RETUNE_C25_0 */
+       { 19506, 0x0000 },   /* R19506 - DACL_RETUNE_C26_1 */
+       { 19507, 0x0000 },   /* R19507 - DACL_RETUNE_C26_0 */
+       { 19508, 0x0000 },   /* R19508 - DACL_RETUNE_C27_1 */
+       { 19509, 0x0000 },   /* R19509 - DACL_RETUNE_C27_0 */
+       { 19510, 0x0000 },   /* R19510 - DACL_RETUNE_C28_1 */
+       { 19511, 0x0000 },   /* R19511 - DACL_RETUNE_C28_0 */
+       { 19512, 0x0000 },   /* R19512 - DACL_RETUNE_C29_1 */
+       { 19513, 0x0000 },   /* R19513 - DACL_RETUNE_C29_0 */
+       { 19514, 0x0000 },   /* R19514 - DACL_RETUNE_C30_1 */
+       { 19515, 0x0000 },   /* R19515 - DACL_RETUNE_C30_0 */
+       { 19516, 0x0000 },   /* R19516 - DACL_RETUNE_C31_1 */
+       { 19517, 0x0000 },   /* R19517 - DACL_RETUNE_C31_0 */
+       { 19518, 0x0000 },   /* R19518 - DACL_RETUNE_C32_1 */
+       { 19519, 0x0000 },   /* R19519 - DACL_RETUNE_C32_0 */
+
+       { 19968, 0x0020 },   /* R19968 - RETUNEDAC_PG2_1 */
+       { 19969, 0x0000 },   /* R19969 - RETUNEDAC_PG2_0 */
+       { 19970, 0x0040 },   /* R19970 - RETUNEDAC_PG_1 */
+       { 19971, 0x0000 },   /* R19971 - RETUNEDAC_PG_0 */
+
+       { 20480, 0x007F },   /* R20480 - DACR_RETUNE_C1_1 */
+       { 20481, 0xFFFF },   /* R20481 - DACR_RETUNE_C1_0 */
+       { 20482, 0x0000 },   /* R20482 - DACR_RETUNE_C2_1 */
+       { 20483, 0x0000 },   /* R20483 - DACR_RETUNE_C2_0 */
+       { 20484, 0x0000 },   /* R20484 - DACR_RETUNE_C3_1 */
+       { 20485, 0x0000 },   /* R20485 - DACR_RETUNE_C3_0 */
+       { 20486, 0x0000 },   /* R20486 - DACR_RETUNE_C4_1 */
+       { 20487, 0x0000 },   /* R20487 - DACR_RETUNE_C4_0 */
+       { 20488, 0x0000 },   /* R20488 - DACR_RETUNE_C5_1 */
+       { 20489, 0x0000 },   /* R20489 - DACR_RETUNE_C5_0 */
+       { 20490, 0x0000 },   /* R20490 - DACR_RETUNE_C6_1 */
+       { 20491, 0x0000 },   /* R20491 - DACR_RETUNE_C6_0 */
+       { 20492, 0x0000 },   /* R20492 - DACR_RETUNE_C7_1 */
+       { 20493, 0x0000 },   /* R20493 - DACR_RETUNE_C7_0 */
+       { 20494, 0x0000 },   /* R20494 - DACR_RETUNE_C8_1 */
+       { 20495, 0x0000 },   /* R20495 - DACR_RETUNE_C8_0 */
+       { 20496, 0x0000 },   /* R20496 - DACR_RETUNE_C9_1 */
+       { 20497, 0x0000 },   /* R20497 - DACR_RETUNE_C9_0 */
+       { 20498, 0x0000 },   /* R20498 - DACR_RETUNE_C10_1 */
+       { 20499, 0x0000 },   /* R20499 - DACR_RETUNE_C10_0 */
+       { 20500, 0x0000 },   /* R20500 - DACR_RETUNE_C11_1 */
+       { 20501, 0x0000 },   /* R20501 - DACR_RETUNE_C11_0 */
+       { 20502, 0x0000 },   /* R20502 - DACR_RETUNE_C12_1 */
+       { 20503, 0x0000 },   /* R20503 - DACR_RETUNE_C12_0 */
+       { 20504, 0x0000 },   /* R20504 - DACR_RETUNE_C13_1 */
+       { 20505, 0x0000 },   /* R20505 - DACR_RETUNE_C13_0 */
+       { 20506, 0x0000 },   /* R20506 - DACR_RETUNE_C14_1 */
+       { 20507, 0x0000 },   /* R20507 - DACR_RETUNE_C14_0 */
+       { 20508, 0x0000 },   /* R20508 - DACR_RETUNE_C15_1 */
+       { 20509, 0x0000 },   /* R20509 - DACR_RETUNE_C15_0 */
+       { 20510, 0x0000 },   /* R20510 - DACR_RETUNE_C16_1 */
+       { 20511, 0x0000 },   /* R20511 - DACR_RETUNE_C16_0 */
+       { 20512, 0x0000 },   /* R20512 - DACR_RETUNE_C17_1 */
+       { 20513, 0x0000 },   /* R20513 - DACR_RETUNE_C17_0 */
+       { 20514, 0x0000 },   /* R20514 - DACR_RETUNE_C18_1 */
+       { 20515, 0x0000 },   /* R20515 - DACR_RETUNE_C18_0 */
+       { 20516, 0x0000 },   /* R20516 - DACR_RETUNE_C19_1 */
+       { 20517, 0x0000 },   /* R20517 - DACR_RETUNE_C19_0 */
+       { 20518, 0x0000 },   /* R20518 - DACR_RETUNE_C20_1 */
+       { 20519, 0x0000 },   /* R20519 - DACR_RETUNE_C20_0 */
+       { 20520, 0x0000 },   /* R20520 - DACR_RETUNE_C21_1 */
+       { 20521, 0x0000 },   /* R20521 - DACR_RETUNE_C21_0 */
+       { 20522, 0x0000 },   /* R20522 - DACR_RETUNE_C22_1 */
+       { 20523, 0x0000 },   /* R20523 - DACR_RETUNE_C22_0 */
+       { 20524, 0x0000 },   /* R20524 - DACR_RETUNE_C23_1 */
+       { 20525, 0x0000 },   /* R20525 - DACR_RETUNE_C23_0 */
+       { 20526, 0x0000 },   /* R20526 - DACR_RETUNE_C24_1 */
+       { 20527, 0x0000 },   /* R20527 - DACR_RETUNE_C24_0 */
+       { 20528, 0x0000 },   /* R20528 - DACR_RETUNE_C25_1 */
+       { 20529, 0x0000 },   /* R20529 - DACR_RETUNE_C25_0 */
+       { 20530, 0x0000 },   /* R20530 - DACR_RETUNE_C26_1 */
+       { 20531, 0x0000 },   /* R20531 - DACR_RETUNE_C26_0 */
+       { 20532, 0x0000 },   /* R20532 - DACR_RETUNE_C27_1 */
+       { 20533, 0x0000 },   /* R20533 - DACR_RETUNE_C27_0 */
+       { 20534, 0x0000 },   /* R20534 - DACR_RETUNE_C28_1 */
+       { 20535, 0x0000 },   /* R20535 - DACR_RETUNE_C28_0 */
+       { 20536, 0x0000 },   /* R20536 - DACR_RETUNE_C29_1 */
+       { 20537, 0x0000 },   /* R20537 - DACR_RETUNE_C29_0 */
+       { 20538, 0x0000 },   /* R20538 - DACR_RETUNE_C30_1 */
+       { 20539, 0x0000 },   /* R20539 - DACR_RETUNE_C30_0 */
+       { 20540, 0x0000 },   /* R20540 - DACR_RETUNE_C31_1 */
+       { 20541, 0x0000 },   /* R20541 - DACR_RETUNE_C31_0 */
+       { 20542, 0x0000 },   /* R20542 - DACR_RETUNE_C32_1 */
+       { 20543, 0x0000 },   /* R20543 - DACR_RETUNE_C32_0 */
+
+       { 20992, 0x008C },   /* R20992 - VSS_XHD2_1 */
+       { 20993, 0x0200 },   /* R20993 - VSS_XHD2_0 */
+       { 20994, 0x0035 },   /* R20994 - VSS_XHD3_1 */
+       { 20995, 0x0700 },   /* R20995 - VSS_XHD3_0 */
+       { 20996, 0x003A },   /* R20996 - VSS_XHN1_1 */
+       { 20997, 0x4100 },   /* R20997 - VSS_XHN1_0 */
+       { 20998, 0x008B },   /* R20998 - VSS_XHN2_1 */
+       { 20999, 0x7D00 },   /* R20999 - VSS_XHN2_0 */
+       { 21000, 0x003A },   /* R21000 - VSS_XHN3_1 */
+       { 21001, 0x4100 },   /* R21001 - VSS_XHN3_0 */
+       { 21002, 0x008C },   /* R21002 - VSS_XLA_1 */
+       { 21003, 0xFEE8 },   /* R21003 - VSS_XLA_0 */
+       { 21004, 0x0078 },   /* R21004 - VSS_XLB_1 */
+       { 21005, 0x0000 },   /* R21005 - VSS_XLB_0 */
+       { 21006, 0x003F },   /* R21006 - VSS_XLG_1 */
+       { 21007, 0xB260 },   /* R21007 - VSS_XLG_0 */
+       { 21008, 0x002D },   /* R21008 - VSS_PG2_1 */
+       { 21009, 0x1818 },   /* R21009 - VSS_PG2_0 */
+       { 21010, 0x0020 },   /* R21010 - VSS_PG_1 */
+       { 21011, 0x0000 },   /* R21011 - VSS_PG_0 */
+       { 21012, 0x00F1 },   /* R21012 - VSS_XTD1_1 */
+       { 21013, 0x8340 },   /* R21013 - VSS_XTD1_0 */
+       { 21014, 0x00FB },   /* R21014 - VSS_XTD2_1 */
+       { 21015, 0x8300 },   /* R21015 - VSS_XTD2_0 */
+       { 21016, 0x00EE },   /* R21016 - VSS_XTD3_1 */
+       { 21017, 0xAEC0 },   /* R21017 - VSS_XTD3_0 */
+       { 21018, 0x00FB },   /* R21018 - VSS_XTD4_1 */
+       { 21019, 0xAC40 },   /* R21019 - VSS_XTD4_0 */
+       { 21020, 0x00F1 },   /* R21020 - VSS_XTD5_1 */
+       { 21021, 0x7F80 },   /* R21021 - VSS_XTD5_0 */
+       { 21022, 0x00F4 },   /* R21022 - VSS_XTD6_1 */
+       { 21023, 0x3B40 },   /* R21023 - VSS_XTD6_0 */
+       { 21024, 0x00F5 },   /* R21024 - VSS_XTD7_1 */
+       { 21025, 0xFB00 },   /* R21025 - VSS_XTD7_0 */
+       { 21026, 0x00EA },   /* R21026 - VSS_XTD8_1 */
+       { 21027, 0x10C0 },   /* R21027 - VSS_XTD8_0 */
+       { 21028, 0x00FC },   /* R21028 - VSS_XTD9_1 */
+       { 21029, 0xC580 },   /* R21029 - VSS_XTD9_0 */
+       { 21030, 0x00E2 },   /* R21030 - VSS_XTD10_1 */
+       { 21031, 0x75C0 },   /* R21031 - VSS_XTD10_0 */
+       { 21032, 0x0004 },   /* R21032 - VSS_XTD11_1 */
+       { 21033, 0xB480 },   /* R21033 - VSS_XTD11_0 */
+       { 21034, 0x00D4 },   /* R21034 - VSS_XTD12_1 */
+       { 21035, 0xF980 },   /* R21035 - VSS_XTD12_0 */
+       { 21036, 0x0004 },   /* R21036 - VSS_XTD13_1 */
+       { 21037, 0x9140 },   /* R21037 - VSS_XTD13_0 */
+       { 21038, 0x00D8 },   /* R21038 - VSS_XTD14_1 */
+       { 21039, 0xA480 },   /* R21039 - VSS_XTD14_0 */
+       { 21040, 0x0002 },   /* R21040 - VSS_XTD15_1 */
+       { 21041, 0x3DC0 },   /* R21041 - VSS_XTD15_0 */
+       { 21042, 0x00CF },   /* R21042 - VSS_XTD16_1 */
+       { 21043, 0x7A80 },   /* R21043 - VSS_XTD16_0 */
+       { 21044, 0x00DC },   /* R21044 - VSS_XTD17_1 */
+       { 21045, 0x0600 },   /* R21045 - VSS_XTD17_0 */
+       { 21046, 0x00F2 },   /* R21046 - VSS_XTD18_1 */
+       { 21047, 0xDAC0 },   /* R21047 - VSS_XTD18_0 */
+       { 21048, 0x00BA },   /* R21048 - VSS_XTD19_1 */
+       { 21049, 0xF340 },   /* R21049 - VSS_XTD19_0 */
+       { 21050, 0x000A },   /* R21050 - VSS_XTD20_1 */
+       { 21051, 0x7940 },   /* R21051 - VSS_XTD20_0 */
+       { 21052, 0x001C },   /* R21052 - VSS_XTD21_1 */
+       { 21053, 0x0680 },   /* R21053 - VSS_XTD21_0 */
+       { 21054, 0x00FD },   /* R21054 - VSS_XTD22_1 */
+       { 21055, 0x2D00 },   /* R21055 - VSS_XTD22_0 */
+       { 21056, 0x001C },   /* R21056 - VSS_XTD23_1 */
+       { 21057, 0xE840 },   /* R21057 - VSS_XTD23_0 */
+       { 21058, 0x000D },   /* R21058 - VSS_XTD24_1 */
+       { 21059, 0xDC40 },   /* R21059 - VSS_XTD24_0 */
+       { 21060, 0x00FC },   /* R21060 - VSS_XTD25_1 */
+       { 21061, 0x9D00 },   /* R21061 - VSS_XTD25_0 */
+       { 21062, 0x0009 },   /* R21062 - VSS_XTD26_1 */
+       { 21063, 0x5580 },   /* R21063 - VSS_XTD26_0 */
+       { 21064, 0x00FE },   /* R21064 - VSS_XTD27_1 */
+       { 21065, 0x7E80 },   /* R21065 - VSS_XTD27_0 */
+       { 21066, 0x000E },   /* R21066 - VSS_XTD28_1 */
+       { 21067, 0xAB40 },   /* R21067 - VSS_XTD28_0 */
+       { 21068, 0x00F9 },   /* R21068 - VSS_XTD29_1 */
+       { 21069, 0x9880 },   /* R21069 - VSS_XTD29_0 */
+       { 21070, 0x0009 },   /* R21070 - VSS_XTD30_1 */
+       { 21071, 0x87C0 },   /* R21071 - VSS_XTD30_0 */
+       { 21072, 0x00FD },   /* R21072 - VSS_XTD31_1 */
+       { 21073, 0x2C40 },   /* R21073 - VSS_XTD31_0 */
+       { 21074, 0x0009 },   /* R21074 - VSS_XTD32_1 */
+       { 21075, 0x4800 },   /* R21075 - VSS_XTD32_0 */
+       { 21076, 0x0003 },   /* R21076 - VSS_XTS1_1 */
+       { 21077, 0x5F40 },   /* R21077 - VSS_XTS1_0 */
+       { 21078, 0x0000 },   /* R21078 - VSS_XTS2_1 */
+       { 21079, 0x8700 },   /* R21079 - VSS_XTS2_0 */
+       { 21080, 0x00FA },   /* R21080 - VSS_XTS3_1 */
+       { 21081, 0xE4C0 },   /* R21081 - VSS_XTS3_0 */
+       { 21082, 0x0000 },   /* R21082 - VSS_XTS4_1 */
+       { 21083, 0x0B40 },   /* R21083 - VSS_XTS4_0 */
+       { 21084, 0x0004 },   /* R21084 - VSS_XTS5_1 */
+       { 21085, 0xE180 },   /* R21085 - VSS_XTS5_0 */
+       { 21086, 0x0001 },   /* R21086 - VSS_XTS6_1 */
+       { 21087, 0x1F40 },   /* R21087 - VSS_XTS6_0 */
+       { 21088, 0x00F8 },   /* R21088 - VSS_XTS7_1 */
+       { 21089, 0xB000 },   /* R21089 - VSS_XTS7_0 */
+       { 21090, 0x00FB },   /* R21090 - VSS_XTS8_1 */
+       { 21091, 0xCBC0 },   /* R21091 - VSS_XTS8_0 */
+       { 21092, 0x0004 },   /* R21092 - VSS_XTS9_1 */
+       { 21093, 0xF380 },   /* R21093 - VSS_XTS9_0 */
+       { 21094, 0x0007 },   /* R21094 - VSS_XTS10_1 */
+       { 21095, 0xDF40 },   /* R21095 - VSS_XTS10_0 */
+       { 21096, 0x00FF },   /* R21096 - VSS_XTS11_1 */
+       { 21097, 0x0700 },   /* R21097 - VSS_XTS11_0 */
+       { 21098, 0x00EF },   /* R21098 - VSS_XTS12_1 */
+       { 21099, 0xD700 },   /* R21099 - VSS_XTS12_0 */
+       { 21100, 0x00FB },   /* R21100 - VSS_XTS13_1 */
+       { 21101, 0xAF40 },   /* R21101 - VSS_XTS13_0 */
+       { 21102, 0x0010 },   /* R21102 - VSS_XTS14_1 */
+       { 21103, 0x8A80 },   /* R21103 - VSS_XTS14_0 */
+       { 21104, 0x0011 },   /* R21104 - VSS_XTS15_1 */
+       { 21105, 0x07C0 },   /* R21105 - VSS_XTS15_0 */
+       { 21106, 0x00E0 },   /* R21106 - VSS_XTS16_1 */
+       { 21107, 0x0800 },   /* R21107 - VSS_XTS16_0 */
+       { 21108, 0x00D2 },   /* R21108 - VSS_XTS17_1 */
+       { 21109, 0x7600 },   /* R21109 - VSS_XTS17_0 */
+       { 21110, 0x0020 },   /* R21110 - VSS_XTS18_1 */
+       { 21111, 0xCF40 },   /* R21111 - VSS_XTS18_0 */
+       { 21112, 0x0030 },   /* R21112 - VSS_XTS19_1 */
+       { 21113, 0x2340 },   /* R21113 - VSS_XTS19_0 */
+       { 21114, 0x00FD },   /* R21114 - VSS_XTS20_1 */
+       { 21115, 0x69C0 },   /* R21115 - VSS_XTS20_0 */
+       { 21116, 0x0028 },   /* R21116 - VSS_XTS21_1 */
+       { 21117, 0x3500 },   /* R21117 - VSS_XTS21_0 */
+       { 21118, 0x0006 },   /* R21118 - VSS_XTS22_1 */
+       { 21119, 0x3300 },   /* R21119 - VSS_XTS22_0 */
+       { 21120, 0x00D9 },   /* R21120 - VSS_XTS23_1 */
+       { 21121, 0xF6C0 },   /* R21121 - VSS_XTS23_0 */
+       { 21122, 0x00F3 },   /* R21122 - VSS_XTS24_1 */
+       { 21123, 0x3340 },   /* R21123 - VSS_XTS24_0 */
+       { 21124, 0x000F },   /* R21124 - VSS_XTS25_1 */
+       { 21125, 0x4200 },   /* R21125 - VSS_XTS25_0 */
+       { 21126, 0x0004 },   /* R21126 - VSS_XTS26_1 */
+       { 21127, 0x0C80 },   /* R21127 - VSS_XTS26_0 */
+       { 21128, 0x00FB },   /* R21128 - VSS_XTS27_1 */
+       { 21129, 0x3F80 },   /* R21129 - VSS_XTS27_0 */
+       { 21130, 0x00F7 },   /* R21130 - VSS_XTS28_1 */
+       { 21131, 0x57C0 },   /* R21131 - VSS_XTS28_0 */
+       { 21132, 0x0003 },   /* R21132 - VSS_XTS29_1 */
+       { 21133, 0x5400 },   /* R21133 - VSS_XTS29_0 */
+       { 21134, 0x0000 },   /* R21134 - VSS_XTS30_1 */
+       { 21135, 0xC6C0 },   /* R21135 - VSS_XTS30_0 */
+       { 21136, 0x0003 },   /* R21136 - VSS_XTS31_1 */
+       { 21137, 0x12C0 },   /* R21137 - VSS_XTS31_0 */
+       { 21138, 0x00FD },   /* R21138 - VSS_XTS32_1 */
+       { 21139, 0x8580 },   /* R21139 - VSS_XTS32_0 */
 };
 
 static const struct wm8962_reg_access {
@@ -802,7 +803,7 @@ static const struct wm8962_reg_access {
        u16 vol;
 } wm8962_reg_access[WM8962_MAX_REGISTER + 1] = {
        [0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0     - Left Input volume */
-       [1] = { 0xFEFF, 0x01FF, 0xFFFF }, /* R1     - Right Input volume */
+       [1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1     - Right Input volume */
        [2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2     - HPOUTL volume */
        [3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3     - HPOUTR volume */
        [4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4     - Clocking1 */
@@ -1943,7 +1944,7 @@ static const struct wm8962_reg_access {
        [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
 };
 
-static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
 {
        if (wm8962_reg_access[reg].vol)
                return 1;
@@ -1951,7 +1952,7 @@ static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int re
                return 0;
 }
 
-static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8962_readable_register(struct device *dev, unsigned int reg)
 {
        if (wm8962_reg_access[reg].read)
                return 1;
@@ -1959,15 +1960,15 @@ static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re
                return 0;
 }
 
-static int wm8962_reset(struct snd_soc_codec *codec)
+static int wm8962_reset(struct wm8962_priv *wm8962)
 {
        int ret;
 
-       ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
+       ret = regmap_write(wm8962->regmap, WM8962_SOFTWARE_RESET, 0x6243);
        if (ret != 0)
                return ret;
 
-       return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0);
+       return regmap_write(wm8962->regmap, WM8962_PLL_SOFTWARE_RESET, 0);
 }
 
 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -2345,6 +2346,10 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
        int src;
        int fll;
 
+       /* Ignore attempts to run the event during startup */
+       if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
+               return 0;
+
        src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
 
        switch (src) {
@@ -2684,6 +2689,8 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
                      WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
                      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
 
 SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
                   inpgal, ARRAY_SIZE(inpgal)),
@@ -2839,6 +2846,9 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
 
        { "HPOUTL", NULL, "HPOUT" },
        { "HPOUTR", NULL, "HPOUT" },
+
+       { "HPOUTL", NULL, "TEMP_HP" },
+       { "HPOUTR", NULL, "TEMP_HP" },
 };
 
 static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = {
@@ -2855,6 +2865,7 @@ static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = {
        { "Speaker Output", NULL, "Speaker PGA" },
        { "Speaker Output", NULL, "SYSCLK" },
        { "Speaker Output", NULL, "TOCLK" },
+       { "Speaker Output", NULL, "TEMP_SPK" },
 
        { "SPKOUT", NULL, "Speaker Output" },
 };
@@ -2883,10 +2894,12 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
        { "SPKOUTL Output", NULL, "SPKOUTL PGA" },
        { "SPKOUTL Output", NULL, "SYSCLK" },
        { "SPKOUTL Output", NULL, "TOCLK" },
+       { "SPKOUTL Output", NULL, "TEMP_SPK" },
 
        { "SPKOUTR Output", NULL, "SPKOUTR PGA" },
        { "SPKOUTR Output", NULL, "SYSCLK" },
        { "SPKOUTR Output", NULL, "TOCLK" },
+       { "SPKOUTR Output", NULL, "TEMP_SPK" },
 
        { "SPKOUTL", NULL, "SPKOUTL Output" },
        { "SPKOUTR", NULL, "SPKOUTR Output" },
@@ -2931,33 +2944,6 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
        return 0;
 }
 
-static void wm8962_sync_cache(struct snd_soc_codec *codec)
-{
-       u16 *reg_cache = codec->reg_cache;
-       int i;
-
-       if (!codec->cache_sync)
-               return;
-
-       dev_dbg(codec->dev, "Syncing cache\n");
-
-       codec->cache_only = 0;
-
-       /* Sync back cached values if they're different from the
-        * hardware default.
-        */
-       for (i = 1; i < codec->driver->reg_cache_size; i++) {
-               if (i == WM8962_SOFTWARE_RESET)
-                       continue;
-               if (reg_cache[i] == wm8962_reg[i])
-                       continue;
-
-               snd_soc_write(codec, i, reg_cache[i]);
-       }
-
-       codec->cache_sync = 0;
-}
-
 /* -1 for reserved values */
 static const int bclk_divs[] = {
        1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
@@ -3085,7 +3071,8 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
                                return ret;
                        }
 
-                       wm8962_sync_cache(codec);
+                       regcache_cache_only(wm8962->regmap, false);
+                       regcache_sync(wm8962->regmap);
 
                        snd_soc_update_bits(codec, WM8962_ANTI_POP,
                                            WM8962_STARTUP_BIAS_ENA |
@@ -3399,6 +3386,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
        unsigned long timeout;
        int ret;
        int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA;
+       int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA;
 
        /* Any change? */
        if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
@@ -3459,6 +3447,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 
        try_wait_for_completion(&wm8962->fll_lock);
 
+       if (sysclk)
+               fll1 |= WM8962_FLL_ENA;
+
        snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
                            WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
                            WM8962_FLL_ENA, fll1);
@@ -3511,7 +3502,7 @@ static int wm8962_mute(struct snd_soc_dai *dai, int mute)
 #define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8962_dai_ops = {
+static const struct snd_soc_dai_ops wm8962_dai_ops = {
        .hw_params = wm8962_hw_params,
        .set_sysclk = wm8962_set_dai_sysclk,
        .set_fmt = wm8962_set_dai_fmt,
@@ -3662,6 +3653,14 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
        snd_soc_jack_report(wm8962->jack, 0,
                            SND_JACK_MICROPHONE | SND_JACK_BTN_0);
 
+       if (jack) {
+               snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
+               snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS");
+       } else {
+               snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK");
+               snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS");
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(wm8962_mic_detect);
@@ -3946,26 +3945,12 @@ static int wm8962_probe(struct snd_soc_codec *codec)
        bool dmicclk, dmicdat;
 
        wm8962->codec = codec;
-       INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
-       init_completion(&wm8962->fll_lock);
+       codec->control_data = wm8962->regmap;
 
-       codec->cache_sync = 1;
-       codec->dapm.idle_bias_off = 1;
-
-       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
+       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               goto err;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
-               wm8962->supplies[i].supply = wm8962_supply_names[i];
-
-       ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8962->supplies),
-                                wm8962->supplies);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-               goto err;
+               return ret;
        }
 
        wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
@@ -3988,43 +3973,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
                }
        }
 
-       ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
-                                   wm8962->supplies);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
-               goto err_get;
-       }
-
-       ret = snd_soc_read(codec, WM8962_SOFTWARE_RESET);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to read ID register\n");
-               goto err_enable;
-       }
-       if (ret != wm8962_reg[WM8962_SOFTWARE_RESET]) {
-               dev_err(codec->dev, "Device is not a WM8962, ID %x != %x\n",
-                       ret, wm8962_reg[WM8962_SOFTWARE_RESET]);
-               ret = -EINVAL;
-               goto err_enable;
-       }
-
-       ret = snd_soc_read(codec, WM8962_RIGHT_INPUT_VOLUME);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to read device revision: %d\n",
-                       ret);
-               goto err_enable;
-       }
-       
-       dev_info(codec->dev, "customer id %x revision %c\n",
-                (ret & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
-                ((ret & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
-                + 'A');
-
-       ret = wm8962_reset(codec);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
-               goto err_enable;
-       }
-
        /* SYSCLK defaults to on; make sure it is off so we can safely
         * write to registers if the device is declocked.
         */
@@ -4039,8 +3987,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
                            WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA,
                            0);
 
-       regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-
        if (pdata) {
                /* Apply static configuration for GPIOs */
                for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++)
@@ -4091,6 +4037,12 @@ static int wm8962_probe(struct snd_soc_codec *codec)
        /* Stereo control for EQ */
        snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0);
 
+       /* Don't debouce interrupts so we don't need SYSCLK */
+       snd_soc_update_bits(codec, WM8962_IRQ_DEBOUNCE,
+                           WM8962_FLL_LOCK_DB | WM8962_PLL3_LOCK_DB |
+                           WM8962_PLL2_LOCK_DB | WM8962_TEMP_SHUT_DB,
+                           0);
+
        wm8962_add_widgets(codec);
 
        /* Save boards having to disable DMIC when not in use */
@@ -4150,13 +4102,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
        }
 
        return 0;
-
-err_enable:
-       regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err_get:
-       regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err:
-       return ret;
 }
 
 static int wm8962_remove(struct snd_soc_codec *codec)
@@ -4174,7 +4119,6 @@ static int wm8962_remove(struct snd_soc_codec *codec)
        for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
                regulator_unregister_notifier(wm8962->supplies[i].consumer,
                                              &wm8962->disable_nb[i]);
-       regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 
        return 0;
 }
@@ -4183,41 +4127,132 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
        .probe =        wm8962_probe,
        .remove =       wm8962_remove,
        .set_bias_level = wm8962_set_bias_level,
-       .reg_cache_size = WM8962_MAX_REGISTER + 1,
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8962_reg,
-       .volatile_register = wm8962_volatile_register,
-       .readable_register = wm8962_readable_register,
        .set_pll = wm8962_set_fll,
 };
 
+static const struct regmap_config wm8962_regmap = {
+       .reg_bits = 16,
+       .val_bits = 16,
+
+       .max_register = WM8962_MAX_REGISTER,
+       .reg_defaults = wm8962_reg,
+       .num_reg_defaults = ARRAY_SIZE(wm8962_reg),
+       .volatile_reg = wm8962_volatile_register,
+       .readable_reg = wm8962_readable_register,
+       .cache_type = REGCACHE_RBTREE,
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
 {
        struct wm8962_priv *wm8962;
-       int ret;
+       unsigned int reg;
+       int ret, i;
 
-       wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL);
+       wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv),
+                             GFP_KERNEL);
        if (wm8962 == NULL)
                return -ENOMEM;
 
        i2c_set_clientdata(i2c, wm8962);
 
+       INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
+       init_completion(&wm8962->fll_lock);
        wm8962->irq = i2c->irq;
 
+       for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
+               wm8962->supplies[i].supply = wm8962_supply_names[i];
+
+       ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies),
+                                wm8962->supplies);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+               goto err;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
+                                   wm8962->supplies);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+               goto err_get;
+       }
+
+       wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap);
+       if (IS_ERR(wm8962->regmap)) {
+               ret = PTR_ERR(wm8962->regmap);
+               dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+               goto err_enable;
+       }
+
+       /*
+        * We haven't marked the chip revision as volatile due to
+        * sharing a register with the right input volume; explicitly
+        * bypass the cache to read it.
+        */
+       regcache_cache_bypass(wm8962->regmap, true);
+
+       ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, &reg);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read ID register\n");
+               goto err_regmap;
+       }
+       if (reg != 0x6243) {
+               dev_err(&i2c->dev,
+                       "Device is not a WM8962, ID %x != 0x6243\n", ret);
+               ret = -EINVAL;
+               goto err_regmap;
+       }
+
+       ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, &reg);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read device revision: %d\n",
+                       ret);
+               goto err_regmap;
+       }
+
+       dev_info(&i2c->dev, "customer id %x revision %c\n",
+                (reg & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
+                ((reg & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
+                + 'A');
+
+       regcache_cache_bypass(wm8962->regmap, false);
+
+       ret = wm8962_reset(wm8962);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to issue reset\n");
+               goto err_regmap;
+       }
+
+       regcache_cache_only(wm8962->regmap, true);
+
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8962, &wm8962_dai, 1);
        if (ret < 0)
-               kfree(wm8962);
+               goto err_regmap;
+
+       /* The drivers should power up as needed */
+       regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
+
+       return 0;
 
+err_regmap:
+       regmap_exit(wm8962->regmap);
+err_enable:
+       regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
+err_get:
+       regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
+err:
        return ret;
 }
 
 static __devexit int wm8962_i2c_remove(struct i2c_client *client)
 {
+       struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
+
        snd_soc_unregister_codec(&client->dev);
-       kfree(i2c_get_clientdata(client));
+       regmap_exit(wm8962->regmap);
+       regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
        return 0;
 }
 
index b444b297d0b2f442d9f5d1d1e1014227ce42128d..b01df56b824a53b86fdfa0044a5dd300c6ff3457 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -224,7 +223,7 @@ static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
        SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
        SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
 
-       SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0),
+       SND_SOC_DAPM_SUPPLY("Mic Bias", WM8971_PWR1, 1, 0, NULL, 0),
        SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
        SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
 
@@ -567,7 +566,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
 #define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8971_dai_ops = {
+static const struct snd_soc_dai_ops wm8971_dai_ops = {
        .hw_params      = wm8971_pcm_hw_params,
        .digital_mute   = wm8971_mute,
        .set_fmt        = wm8971_set_dai_fmt,
index 9352f1e088d27fd4053ce7b6e6796081c1daee92..e41f9993c6528eb1508a8a28c5e5b4b1cf8c0f16 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -226,7 +225,7 @@ SND_SOC_DAPM_MIXER("Input PGA", WM8974_POWER2, 2, 0, wm8974_inpga,
 SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0,
                   wm8974_boost_mixer, ARRAY_SIZE(wm8974_boost_mixer)),
 
-SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0),
+SND_SOC_DAPM_SUPPLY("Mic Bias", WM8974_POWER1, 4, 0, NULL, 0),
 
 SND_SOC_DAPM_INPUT("MICN"),
 SND_SOC_DAPM_INPUT("MICP"),
@@ -557,7 +556,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
 #define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8974_ops = {
+static const struct snd_soc_dai_ops wm8974_ops = {
        .hw_params = wm8974_pcm_hw_params,
        .digital_mute = wm8974_mute,
        .set_fmt = wm8974_set_dai_fmt,
index 41ca4d9ac20c0dff5aeb5d2666cae916237a0144..649a2e3c02ae5f450b0b1baac3086947cd30fc98 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -865,7 +864,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
 #define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8978_dai_ops = {
+static const struct snd_soc_dai_ops wm8978_dai_ops = {
        .hw_params      = wm8978_hw_params,
        .digital_mute   = wm8978_mute,
        .set_fmt        = wm8978_set_dai_fmt,
index 93ee28439be56f70dbdaec4a4689209df94f3243..362298cce92c5f7619c5ff465f5aaf9e48e92e59 100644 (file)
@@ -481,7 +481,8 @@ static const struct snd_soc_dapm_widget wm8983_dapm_widgets[] = {
        SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3,
                         8, 0, NULL, 0),
 
-       SND_SOC_DAPM_MICBIAS("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0),
+       SND_SOC_DAPM_SUPPLY("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0,
+                           NULL, 0),
 
        SND_SOC_DAPM_INPUT("LIN"),
        SND_SOC_DAPM_INPUT("LIP"),
@@ -1034,7 +1035,7 @@ static int wm8983_probe(struct snd_soc_codec *codec)
        return 0;
 }
 
-static struct snd_soc_dai_ops wm8983_dai_ops = {
+static const struct snd_soc_dai_ops wm8983_dai_ops = {
        .digital_mute = wm8983_dac_mute,
        .hw_params = wm8983_hw_params,
        .set_fmt = wm8983_set_fmt,
index bae510acdec8facfa985a966173c0512a92e8783..9e4481bb122322d51052158d7324e4acc1e2a888 100644 (file)
@@ -411,7 +411,8 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
        SND_SOC_DAPM_PGA("Right Speaker Out", WM8985_POWER_MANAGEMENT_3,
                6, 0, NULL, 0),
 
-       SND_SOC_DAPM_MICBIAS("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0),
+       SND_SOC_DAPM_SUPPLY("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0,
+                           NULL, 0),
 
        SND_SOC_DAPM_INPUT("LIN"),
        SND_SOC_DAPM_INPUT("LIP"),
@@ -1030,7 +1031,7 @@ err_reg_get:
        return ret;
 }
 
-static struct snd_soc_dai_ops wm8985_dai_ops = {
+static const struct snd_soc_dai_ops wm8985_dai_ops = {
        .digital_mute = wm8985_dac_mute,
        .hw_params = wm8985_hw_params,
        .set_fmt = wm8985_set_fmt,
index 2e9eba717d1a9adb1f15fe345276699c67c26fca..608c6721e4f15c5245502afa790981d19b56cb49 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -267,7 +266,7 @@ static const struct snd_kcontrol_new wm8988_monomux_controls =
        SOC_DAPM_ENUM("Route", monomux);
 
 static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
-       SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0),
+       SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0),
 
        SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
                &wm8988_diffmux_controls),
@@ -701,7 +700,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
 #define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8988_ops = {
+static const struct snd_soc_dai_ops wm8988_ops = {
        .startup = wm8988_pcm_startup,
        .hw_params = wm8988_pcm_hw_params,
        .set_fmt = wm8988_set_dai_fmt,
index d29a9622964c20d32850c6f5c0ced435af22a1a7..58d7f0bff99036d014b5e8d58ec658d2318eb68c 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -776,8 +775,8 @@ SND_SOC_DAPM_PGA("ROPGA", WM8990_POWER_MANAGEMENT_3, WM8990_ROPGA_ENA_BIT, 0,
        NULL, 0),
 
 /* MICBIAS */
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8990_POWER_MANAGEMENT_1,
-       WM8990_MICBIAS_ENA_BIT, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS", WM8990_POWER_MANAGEMENT_1,
+                   WM8990_MICBIAS_ENA_BIT, 0, NULL, 0),
 
 SND_SOC_DAPM_OUTPUT("LON"),
 SND_SOC_DAPM_OUTPUT("LOP"),
@@ -1287,7 +1286,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
  * 1. ADC/DAC on Primary Interface
  * 2. ADC on Primary Interface/DAC on secondary
  */
-static struct snd_soc_dai_ops wm8990_dai_ops = {
+static const struct snd_soc_dai_ops wm8990_dai_ops = {
        .hw_params      = wm8990_hw_params,
        .digital_mute   = wm8990_mute,
        .set_fmt        = wm8990_set_dai_fmt,
index c9ab3ba9bcedf4269f3b9d9f00a146d0a7d4a8c8..35c5389e5ef73b3bda94a1ec4530511063afdc11 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -770,8 +769,8 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
                NULL, 0),
 
        /* MICBIAS */
-       SND_SOC_DAPM_MICBIAS("MICBIAS", WM8991_POWER_MANAGEMENT_1,
-               WM8991_MICBIAS_ENA_BIT, 0),
+       SND_SOC_DAPM_SUPPLY("MICBIAS", WM8991_POWER_MANAGEMENT_1,
+                           WM8991_MICBIAS_ENA_BIT, 0, NULL, 0),
 
        SND_SOC_DAPM_OUTPUT("LON"),
        SND_SOC_DAPM_OUTPUT("LOP"),
@@ -1311,7 +1310,7 @@ static int wm8991_probe(struct snd_soc_codec *codec)
 #define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops wm8991_ops = {
+static const struct snd_soc_dai_ops wm8991_ops = {
        .hw_params = wm8991_hw_params,
        .digital_mute = wm8991_mute,
        .set_fmt = wm8991_set_dai_fmt,
index d1a142f48b09f03fb565a5c4a6419842a854c6f6..780c24cdab6de6d989c91a9a0f6a3701cf3b56e0 100644 (file)
@@ -1394,7 +1394,7 @@ out:
        return 0;
 }
 
-static struct snd_soc_dai_ops wm8993_ops = {
+static const struct snd_soc_dai_ops wm8993_ops = {
        .set_sysclk = wm8993_set_sysclk,
        .set_fmt = wm8993_set_dai_fmt,
        .hw_params = wm8993_hw_params,
index 36ba1edfff808ac8cc3a864acc959e3f03950590..6bcb1b6145cbe8dbd142765c62480dec96101dce 100644 (file)
@@ -2536,7 +2536,7 @@ static int wm8994_aif2_probe(struct snd_soc_dai *dai)
 #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
+static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
        .set_sysclk     = wm8994_set_dai_sysclk,
        .set_fmt        = wm8994_set_dai_fmt,
        .hw_params      = wm8994_hw_params,
@@ -2546,7 +2546,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
        .set_tristate   = wm8994_set_tristate,
 };
 
-static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
+static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
        .set_sysclk     = wm8994_set_dai_sysclk,
        .set_fmt        = wm8994_set_dai_fmt,
        .hw_params      = wm8994_hw_params,
@@ -2556,7 +2556,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
        .set_tristate   = wm8994_set_tristate,
 };
 
-static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
+static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
        .hw_params      = wm8994_aif3_hw_params,
        .set_tristate   = wm8994_set_tristate,
 };
@@ -3584,18 +3584,7 @@ static struct platform_driver wm8994_codec_driver = {
        .remove = __devexit_p(wm8994_remove),
 };
 
-static __init int wm8994_init(void)
-{
-       return platform_driver_register(&wm8994_codec_driver);
-}
-module_init(wm8994_init);
-
-static __exit void wm8994_exit(void)
-{
-       platform_driver_unregister(&wm8994_codec_driver);
-}
-module_exit(wm8994_exit);
-
+module_platform_driver(wm8994_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM8994 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
index 78eeb21e66964be9f2457083cf4217b5ac0d5fbd..8f6a36d7c75be67bd3db55c01dc934d66b5b18fc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -43,88 +44,331 @@ static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = {
        "MICVDD"
 };
 
-static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = {
-       [0]     = 0x8995, [5]     = 0x0100, [16]    = 0x000b, [17]    = 0x000b,
-       [24]    = 0x02c0, [25]    = 0x02c0, [26]    = 0x02c0, [27]    = 0x02c0,
-       [28]    = 0x000f, [32]    = 0x0005, [33]    = 0x0005, [40]    = 0x0003,
-       [41]    = 0x0013, [48]    = 0x0004, [56]    = 0x09f8, [64]    = 0x1f25,
-       [69]    = 0x0004, [82]    = 0xaaaa, [84]    = 0x2a2a, [146]   = 0x0060,
-       [256]   = 0x0002, [257]   = 0x8004, [520]   = 0x0010, [528]   = 0x0083,
-       [529]   = 0x0083, [548]   = 0x0c80, [580]   = 0x0c80, [768]   = 0x4050,
-       [769]   = 0x4000, [771]   = 0x0040, [772]   = 0x0040, [773]   = 0x0040,
-       [774]   = 0x0004, [775]   = 0x0100, [784]   = 0x4050, [785]   = 0x4000,
-       [787]   = 0x0040, [788]   = 0x0040, [789]   = 0x0040, [1024]  = 0x00c0,
-       [1025]  = 0x00c0, [1026]  = 0x00c0, [1027]  = 0x00c0, [1028]  = 0x00c0,
-       [1029]  = 0x00c0, [1030]  = 0x00c0, [1031]  = 0x00c0, [1056]  = 0x0200,
-       [1057]  = 0x0010, [1058]  = 0x0200, [1059]  = 0x0010, [1088]  = 0x0098,
-       [1089]  = 0x0845, [1104]  = 0x0098, [1105]  = 0x0845, [1152]  = 0x6318,
-       [1153]  = 0x6300, [1154]  = 0x0fca, [1155]  = 0x0400, [1156]  = 0x00d8,
-       [1157]  = 0x1eb5, [1158]  = 0xf145, [1159]  = 0x0b75, [1160]  = 0x01c5,
-       [1161]  = 0x1c58, [1162]  = 0xf373, [1163]  = 0x0a54, [1164]  = 0x0558,
-       [1165]  = 0x168e, [1166]  = 0xf829, [1167]  = 0x07ad, [1168]  = 0x1103,
-       [1169]  = 0x0564, [1170]  = 0x0559, [1171]  = 0x4000, [1184]  = 0x6318,
-       [1185]  = 0x6300, [1186]  = 0x0fca, [1187]  = 0x0400, [1188]  = 0x00d8,
-       [1189]  = 0x1eb5, [1190]  = 0xf145, [1191]  = 0x0b75, [1192]  = 0x01c5,
-       [1193]  = 0x1c58, [1194]  = 0xf373, [1195]  = 0x0a54, [1196]  = 0x0558,
-       [1197]  = 0x168e, [1198]  = 0xf829, [1199]  = 0x07ad, [1200]  = 0x1103,
-       [1201]  = 0x0564, [1202]  = 0x0559, [1203]  = 0x4000, [1280]  = 0x00c0,
-       [1281]  = 0x00c0, [1282]  = 0x00c0, [1283]  = 0x00c0, [1312]  = 0x0200,
-       [1313]  = 0x0010, [1344]  = 0x0098, [1345]  = 0x0845, [1408]  = 0x6318,
-       [1409]  = 0x6300, [1410]  = 0x0fca, [1411]  = 0x0400, [1412]  = 0x00d8,
-       [1413]  = 0x1eb5, [1414]  = 0xf145, [1415]  = 0x0b75, [1416]  = 0x01c5,
-       [1417]  = 0x1c58, [1418]  = 0xf373, [1419]  = 0x0a54, [1420]  = 0x0558,
-       [1421]  = 0x168e, [1422]  = 0xf829, [1423]  = 0x07ad, [1424]  = 0x1103,
-       [1425]  = 0x0564, [1426]  = 0x0559, [1427]  = 0x4000, [1568]  = 0x0002,
-       [1792]  = 0xa100, [1793]  = 0xa101, [1794]  = 0xa101, [1795]  = 0xa101,
-       [1796]  = 0xa101, [1797]  = 0xa101, [1798]  = 0xa101, [1799]  = 0xa101,
-       [1800]  = 0xa101, [1801]  = 0xa101, [1802]  = 0xa101, [1803]  = 0xa101,
-       [1804]  = 0xa101, [1805]  = 0xa101, [1825]  = 0x0055, [1848]  = 0x3fff,
-       [1849]  = 0x1fff, [2049]  = 0x0001, [2050]  = 0x0069, [2056]  = 0x0002,
-       [2057]  = 0x0003, [2058]  = 0x0069, [12288] = 0x0001, [12289] = 0x0001,
-       [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f,
-       [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104,
-       [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050,
-       [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003,
-       [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b,
-       [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff,
-       [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff,
-       [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001,
-       [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001,
-       [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003,
-       [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401,
-       [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060,
-       [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff,
-       [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff,
-       [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff,
-       [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006,
-       [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006,
-       [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061,
-       [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003,
-       [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106,
-       [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502,
-       [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff,
-       [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff,
-       [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001,
-       [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f,
-       [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106,
-       [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050,
-       [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b,
-       [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff,
-       [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff,
-       [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff,
-       [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100,
-       [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff,
-       [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff,
-       [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff,
-       [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff,
-       [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102,
-       [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff,
-       [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff,
-       [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff,
-       [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff,
-       [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601,
-       [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304,
-       [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100
+static struct reg_default wm8995_reg_defaults[] = {
+       { 0, 0x8995 },
+       { 5, 0x0100 },
+       { 16, 0x000b },
+       { 17, 0x000b },
+       { 24, 0x02c0 },
+       { 25, 0x02c0 },
+       { 26, 0x02c0 },
+       { 27, 0x02c0 },
+       { 28, 0x000f },
+       { 32, 0x0005 },
+       { 33, 0x0005 },
+       { 40, 0x0003 },
+       { 41, 0x0013 },
+       { 48, 0x0004 },
+       { 56, 0x09f8 },
+       { 64, 0x1f25 },
+       { 69, 0x0004 },
+       { 82, 0xaaaa },
+       { 84, 0x2a2a },
+       { 146, 0x0060 },
+       { 256, 0x0002 },
+       { 257, 0x8004 },
+       { 520, 0x0010 },
+       { 528, 0x0083 },
+       { 529, 0x0083 },
+       { 548, 0x0c80 },
+       { 580, 0x0c80 },
+       { 768, 0x4050 },
+       { 769, 0x4000 },
+       { 771, 0x0040 },
+       { 772, 0x0040 },
+       { 773, 0x0040 },
+       { 774, 0x0004 },
+       { 775, 0x0100 },
+       { 784, 0x4050 },
+       { 785, 0x4000 },
+       { 787, 0x0040 },
+       { 788, 0x0040 },
+       { 789, 0x0040 },
+       { 1024, 0x00c0 },
+       { 1025, 0x00c0 },
+       { 1026, 0x00c0 },
+       { 1027, 0x00c0 },
+       { 1028, 0x00c0 },
+       { 1029, 0x00c0 },
+       { 1030, 0x00c0 },
+       { 1031, 0x00c0 },
+       { 1056, 0x0200 },
+       { 1057, 0x0010 },
+       { 1058, 0x0200 },
+       { 1059, 0x0010 },
+       { 1088, 0x0098 },
+       { 1089, 0x0845 },
+       { 1104, 0x0098 },
+       { 1105, 0x0845 },
+       { 1152, 0x6318 },
+       { 1153, 0x6300 },
+       { 1154, 0x0fca },
+       { 1155, 0x0400 },
+       { 1156, 0x00d8 },
+       { 1157, 0x1eb5 },
+       { 1158, 0xf145 },
+       { 1159, 0x0b75 },
+       { 1160, 0x01c5 },
+       { 1161, 0x1c58 },
+       { 1162, 0xf373 },
+       { 1163, 0x0a54 },
+       { 1164, 0x0558 },
+       { 1165, 0x168e },
+       { 1166, 0xf829 },
+       { 1167, 0x07ad },
+       { 1168, 0x1103 },
+       { 1169, 0x0564 },
+       { 1170, 0x0559 },
+       { 1171, 0x4000 },
+       { 1184, 0x6318 },
+       { 1185, 0x6300 },
+       { 1186, 0x0fca },
+       { 1187, 0x0400 },
+       { 1188, 0x00d8 },
+       { 1189, 0x1eb5 },
+       { 1190, 0xf145 },
+       { 1191, 0x0b75 },
+       { 1192, 0x01c5 },
+       { 1193, 0x1c58 },
+       { 1194, 0xf373 },
+       { 1195, 0x0a54 },
+       { 1196, 0x0558 },
+       { 1197, 0x168e },
+       { 1198, 0xf829 },
+       { 1199, 0x07ad },
+       { 1200, 0x1103 },
+       { 1201, 0x0564 },
+       { 1202, 0x0559 },
+       { 1203, 0x4000 },
+       { 1280, 0x00c0 },
+       { 1281, 0x00c0 },
+       { 1282, 0x00c0 },
+       { 1283, 0x00c0 },
+       { 1312, 0x0200 },
+       { 1313, 0x0010 },
+       { 1344, 0x0098 },
+       { 1345, 0x0845 },
+       { 1408, 0x6318 },
+       { 1409, 0x6300 },
+       { 1410, 0x0fca },
+       { 1411, 0x0400 },
+       { 1412, 0x00d8 },
+       { 1413, 0x1eb5 },
+       { 1414, 0xf145 },
+       { 1415, 0x0b75 },
+       { 1416, 0x01c5 },
+       { 1417, 0x1c58 },
+       { 1418, 0xf373 },
+       { 1419, 0x0a54 },
+       { 1420, 0x0558 },
+       { 1421, 0x168e },
+       { 1422, 0xf829 },
+       { 1423, 0x07ad },
+       { 1424, 0x1103 },
+       { 1425, 0x0564 },
+       { 1426, 0x0559 },
+       { 1427, 0x4000 },
+       { 1568, 0x0002 },
+       { 1792, 0xa100 },
+       { 1793, 0xa101 },
+       { 1794, 0xa101 },
+       { 1795, 0xa101 },
+       { 1796, 0xa101 },
+       { 1797, 0xa101 },
+       { 1798, 0xa101 },
+       { 1799, 0xa101 },
+       { 1800, 0xa101 },
+       { 1801, 0xa101 },
+       { 1802, 0xa101 },
+       { 1803, 0xa101 },
+       { 1804, 0xa101 },
+       { 1805, 0xa101 },
+       { 1825, 0x0055 },
+       { 1848, 0x3fff },
+       { 1849, 0x1fff },
+       { 2049, 0x0001 },
+       { 2050, 0x0069 },
+       { 2056, 0x0002 },
+       { 2057, 0x0003 },
+       { 2058, 0x0069 },
+       { 12288, 0x0001 },
+       { 12289, 0x0001 },
+       { 12291, 0x0006 },
+       { 12292, 0x0040 },
+       { 12293, 0x0001 },
+       { 12294, 0x000f },
+       { 12295, 0x0006 },
+       { 12296, 0x0001 },
+       { 12297, 0x0003 },
+       { 12298, 0x0104 },
+       { 12300, 0x0060 },
+       { 12301, 0x0011 },
+       { 12302, 0x0401 },
+       { 12304, 0x0050 },
+       { 12305, 0x0003 },
+       { 12306, 0x0100 },
+       { 12308, 0x0051 },
+       { 12309, 0x0003 },
+       { 12310, 0x0104 },
+       { 12311, 0x000a },
+       { 12312, 0x0060 },
+       { 12313, 0x003b },
+       { 12314, 0x0502 },
+       { 12315, 0x0100 },
+       { 12316, 0x2fff },
+       { 12320, 0x2fff },
+       { 12324, 0x2fff },
+       { 12328, 0x2fff },
+       { 12332, 0x2fff },
+       { 12336, 0x2fff },
+       { 12340, 0x2fff },
+       { 12344, 0x2fff },
+       { 12348, 0x2fff },
+       { 12352, 0x0001 },
+       { 12353, 0x0001 },
+       { 12355, 0x0006 },
+       { 12356, 0x0040 },
+       { 12357, 0x0001 },
+       { 12358, 0x000f },
+       { 12359, 0x0006 },
+       { 12360, 0x0001 },
+       { 12361, 0x0003 },
+       { 12362, 0x0104 },
+       { 12364, 0x0060 },
+       { 12365, 0x0011 },
+       { 12366, 0x0401 },
+       { 12368, 0x0050 },
+       { 12369, 0x0003 },
+       { 12370, 0x0100 },
+       { 12372, 0x0060 },
+       { 12373, 0x003b },
+       { 12374, 0x0502 },
+       { 12375, 0x0100 },
+       { 12376, 0x2fff },
+       { 12380, 0x2fff },
+       { 12384, 0x2fff },
+       { 12388, 0x2fff },
+       { 12392, 0x2fff },
+       { 12396, 0x2fff },
+       { 12400, 0x2fff },
+       { 12404, 0x2fff },
+       { 12408, 0x2fff },
+       { 12412, 0x2fff },
+       { 12416, 0x0001 },
+       { 12417, 0x0001 },
+       { 12419, 0x0006 },
+       { 12420, 0x0040 },
+       { 12421, 0x0001 },
+       { 12422, 0x000f },
+       { 12423, 0x0006 },
+       { 12424, 0x0001 },
+       { 12425, 0x0003 },
+       { 12426, 0x0106 },
+       { 12428, 0x0061 },
+       { 12429, 0x0011 },
+       { 12430, 0x0401 },
+       { 12432, 0x0050 },
+       { 12433, 0x0003 },
+       { 12434, 0x0102 },
+       { 12436, 0x0051 },
+       { 12437, 0x0003 },
+       { 12438, 0x0106 },
+       { 12439, 0x000a },
+       { 12440, 0x0061 },
+       { 12441, 0x003b },
+       { 12442, 0x0502 },
+       { 12443, 0x0100 },
+       { 12444, 0x2fff },
+       { 12448, 0x2fff },
+       { 12452, 0x2fff },
+       { 12456, 0x2fff },
+       { 12460, 0x2fff },
+       { 12464, 0x2fff },
+       { 12468, 0x2fff },
+       { 12472, 0x2fff },
+       { 12476, 0x2fff },
+       { 12480, 0x0001 },
+       { 12481, 0x0001 },
+       { 12483, 0x0006 },
+       { 12484, 0x0040 },
+       { 12485, 0x0001 },
+       { 12486, 0x000f },
+       { 12487, 0x0006 },
+       { 12488, 0x0001 },
+       { 12489, 0x0003 },
+       { 12490, 0x0106 },
+       { 12492, 0x0061 },
+       { 12493, 0x0011 },
+       { 12494, 0x0401 },
+       { 12496, 0x0050 },
+       { 12497, 0x0003 },
+       { 12498, 0x0102 },
+       { 12500, 0x0061 },
+       { 12501, 0x003b },
+       { 12502, 0x0502 },
+       { 12503, 0x0100 },
+       { 12504, 0x2fff },
+       { 12508, 0x2fff },
+       { 12512, 0x2fff },
+       { 12516, 0x2fff },
+       { 12520, 0x2fff },
+       { 12524, 0x2fff },
+       { 12528, 0x2fff },
+       { 12532, 0x2fff },
+       { 12536, 0x2fff },
+       { 12540, 0x2fff },
+       { 12544, 0x0060 },
+       { 12546, 0x0601 },
+       { 12548, 0x0050 },
+       { 12550, 0x0100 },
+       { 12552, 0x0001 },
+       { 12554, 0x0104 },
+       { 12555, 0x0100 },
+       { 12556, 0x2fff },
+       { 12560, 0x2fff },
+       { 12564, 0x2fff },
+       { 12568, 0x2fff },
+       { 12572, 0x2fff },
+       { 12576, 0x2fff },
+       { 12580, 0x2fff },
+       { 12584, 0x2fff },
+       { 12588, 0x2fff },
+       { 12592, 0x2fff },
+       { 12596, 0x2fff },
+       { 12600, 0x2fff },
+       { 12604, 0x2fff },
+       { 12608, 0x0061 },
+       { 12610, 0x0601 },
+       { 12612, 0x0050 },
+       { 12614, 0x0102 },
+       { 12616, 0x0001 },
+       { 12618, 0x0106 },
+       { 12619, 0x0100 },
+       { 12620, 0x2fff },
+       { 12624, 0x2fff },
+       { 12628, 0x2fff },
+       { 12632, 0x2fff },
+       { 12636, 0x2fff },
+       { 12640, 0x2fff },
+       { 12644, 0x2fff },
+       { 12648, 0x2fff },
+       { 12652, 0x2fff },
+       { 12656, 0x2fff },
+       { 12660, 0x2fff },
+       { 12664, 0x2fff },
+       { 12668, 0x2fff },
+       { 12672, 0x0060 },
+       { 12674, 0x0601 },
+       { 12676, 0x0061 },
+       { 12678, 0x0601 },
+       { 12680, 0x0050 },
+       { 12682, 0x0300 },
+       { 12684, 0x0001 },
+       { 12686, 0x0304 },
+       { 12688, 0x0040 },
+       { 12690, 0x000f },
+       { 12692, 0x0001 },
+       { 12695, 0x0100 },
 };
 
 struct fll_config {
@@ -134,7 +378,7 @@ struct fll_config {
 };
 
 struct wm8995_priv {
-       enum snd_soc_control_type control_type;
+       struct regmap *regmap;
        int sysclk[2];
        int mclk[2];
        int aifclk[2];
@@ -156,7 +400,7 @@ static int wm8995_regulator_event_##n(struct notifier_block *nb, \
        struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \
                                     disable_nb[n]); \
        if (event & REGULATOR_EVENT_DISABLE) { \
-               wm8995->codec->cache_sync = 1; \
+               regcache_mark_dirty(wm8995->regmap);    \
        } \
        return 0; \
 }
@@ -688,8 +932,10 @@ static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = {
        SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0,
                &in1r_pga, 1),
 
-       SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0),
-       SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0),
+       SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0,
+                           NULL, 0),
+       SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0,
+                           NULL, 0),
 
        SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0),
        SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0),
@@ -947,31 +1193,244 @@ static const struct snd_soc_dapm_route wm8995_intercon[] = {
        { "SPK2R", NULL, "SPK2R Driver" }
 };
 
-static int wm8995_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8995_readable(struct device *dev, unsigned int reg)
 {
-       /* out of bounds registers are generally considered
-        * volatile to support register banks that are partially
-        * owned by something else for e.g. a DSP
-        */
-       if (reg > WM8995_MAX_CACHED_REGISTER)
-               return 1;
-
        switch (reg) {
        case WM8995_SOFTWARE_RESET:
+       case WM8995_POWER_MANAGEMENT_1:
+       case WM8995_POWER_MANAGEMENT_2:
+       case WM8995_POWER_MANAGEMENT_3:
+       case WM8995_POWER_MANAGEMENT_4:
+       case WM8995_POWER_MANAGEMENT_5:
+       case WM8995_LEFT_LINE_INPUT_1_VOLUME:
+       case WM8995_RIGHT_LINE_INPUT_1_VOLUME:
+       case WM8995_LEFT_LINE_INPUT_CONTROL:
+       case WM8995_DAC1_LEFT_VOLUME:
+       case WM8995_DAC1_RIGHT_VOLUME:
+       case WM8995_DAC2_LEFT_VOLUME:
+       case WM8995_DAC2_RIGHT_VOLUME:
+       case WM8995_OUTPUT_VOLUME_ZC_1:
+       case WM8995_MICBIAS_1:
+       case WM8995_MICBIAS_2:
+       case WM8995_LDO_1:
+       case WM8995_LDO_2:
+       case WM8995_ACCESSORY_DETECT_MODE1:
+       case WM8995_ACCESSORY_DETECT_MODE2:
+       case WM8995_HEADPHONE_DETECT1:
+       case WM8995_HEADPHONE_DETECT2:
+       case WM8995_MIC_DETECT_1:
+       case WM8995_MIC_DETECT_2:
+       case WM8995_CHARGE_PUMP_1:
+       case WM8995_CLASS_W_1:
+       case WM8995_DC_SERVO_1:
+       case WM8995_DC_SERVO_2:
+       case WM8995_DC_SERVO_3:
+       case WM8995_DC_SERVO_5:
+       case WM8995_DC_SERVO_6:
+       case WM8995_DC_SERVO_7:
        case WM8995_DC_SERVO_READBACK_0:
+       case WM8995_ANALOGUE_HP_1:
+       case WM8995_ANALOGUE_HP_2:
+       case WM8995_CHIP_REVISION:
+       case WM8995_CONTROL_INTERFACE_1:
+       case WM8995_CONTROL_INTERFACE_2:
+       case WM8995_WRITE_SEQUENCER_CTRL_1:
+       case WM8995_WRITE_SEQUENCER_CTRL_2:
+       case WM8995_AIF1_CLOCKING_1:
+       case WM8995_AIF1_CLOCKING_2:
+       case WM8995_AIF2_CLOCKING_1:
+       case WM8995_AIF2_CLOCKING_2:
+       case WM8995_CLOCKING_1:
+       case WM8995_CLOCKING_2:
+       case WM8995_AIF1_RATE:
+       case WM8995_AIF2_RATE:
+       case WM8995_RATE_STATUS:
+       case WM8995_FLL1_CONTROL_1:
+       case WM8995_FLL1_CONTROL_2:
+       case WM8995_FLL1_CONTROL_3:
+       case WM8995_FLL1_CONTROL_4:
+       case WM8995_FLL1_CONTROL_5:
+       case WM8995_FLL2_CONTROL_1:
+       case WM8995_FLL2_CONTROL_2:
+       case WM8995_FLL2_CONTROL_3:
+       case WM8995_FLL2_CONTROL_4:
+       case WM8995_FLL2_CONTROL_5:
+       case WM8995_AIF1_CONTROL_1:
+       case WM8995_AIF1_CONTROL_2:
+       case WM8995_AIF1_MASTER_SLAVE:
+       case WM8995_AIF1_BCLK:
+       case WM8995_AIF1ADC_LRCLK:
+       case WM8995_AIF1DAC_LRCLK:
+       case WM8995_AIF1DAC_DATA:
+       case WM8995_AIF1ADC_DATA:
+       case WM8995_AIF2_CONTROL_1:
+       case WM8995_AIF2_CONTROL_2:
+       case WM8995_AIF2_MASTER_SLAVE:
+       case WM8995_AIF2_BCLK:
+       case WM8995_AIF2ADC_LRCLK:
+       case WM8995_AIF2DAC_LRCLK:
+       case WM8995_AIF2DAC_DATA:
+       case WM8995_AIF2ADC_DATA:
+       case WM8995_AIF1_ADC1_LEFT_VOLUME:
+       case WM8995_AIF1_ADC1_RIGHT_VOLUME:
+       case WM8995_AIF1_DAC1_LEFT_VOLUME:
+       case WM8995_AIF1_DAC1_RIGHT_VOLUME:
+       case WM8995_AIF1_ADC2_LEFT_VOLUME:
+       case WM8995_AIF1_ADC2_RIGHT_VOLUME:
+       case WM8995_AIF1_DAC2_LEFT_VOLUME:
+       case WM8995_AIF1_DAC2_RIGHT_VOLUME:
+       case WM8995_AIF1_ADC1_FILTERS:
+       case WM8995_AIF1_ADC2_FILTERS:
+       case WM8995_AIF1_DAC1_FILTERS_1:
+       case WM8995_AIF1_DAC1_FILTERS_2:
+       case WM8995_AIF1_DAC2_FILTERS_1:
+       case WM8995_AIF1_DAC2_FILTERS_2:
+       case WM8995_AIF1_DRC1_1:
+       case WM8995_AIF1_DRC1_2:
+       case WM8995_AIF1_DRC1_3:
+       case WM8995_AIF1_DRC1_4:
+       case WM8995_AIF1_DRC1_5:
+       case WM8995_AIF1_DRC2_1:
+       case WM8995_AIF1_DRC2_2:
+       case WM8995_AIF1_DRC2_3:
+       case WM8995_AIF1_DRC2_4:
+       case WM8995_AIF1_DRC2_5:
+       case WM8995_AIF1_DAC1_EQ_GAINS_1:
+       case WM8995_AIF1_DAC1_EQ_GAINS_2:
+       case WM8995_AIF1_DAC1_EQ_BAND_1_A:
+       case WM8995_AIF1_DAC1_EQ_BAND_1_B:
+       case WM8995_AIF1_DAC1_EQ_BAND_1_PG:
+       case WM8995_AIF1_DAC1_EQ_BAND_2_A:
+       case WM8995_AIF1_DAC1_EQ_BAND_2_B:
+       case WM8995_AIF1_DAC1_EQ_BAND_2_C:
+       case WM8995_AIF1_DAC1_EQ_BAND_2_PG:
+       case WM8995_AIF1_DAC1_EQ_BAND_3_A:
+       case WM8995_AIF1_DAC1_EQ_BAND_3_B:
+       case WM8995_AIF1_DAC1_EQ_BAND_3_C:
+       case WM8995_AIF1_DAC1_EQ_BAND_3_PG:
+       case WM8995_AIF1_DAC1_EQ_BAND_4_A:
+       case WM8995_AIF1_DAC1_EQ_BAND_4_B:
+       case WM8995_AIF1_DAC1_EQ_BAND_4_C:
+       case WM8995_AIF1_DAC1_EQ_BAND_4_PG:
+       case WM8995_AIF1_DAC1_EQ_BAND_5_A:
+       case WM8995_AIF1_DAC1_EQ_BAND_5_B:
+       case WM8995_AIF1_DAC1_EQ_BAND_5_PG:
+       case WM8995_AIF1_DAC2_EQ_GAINS_1:
+       case WM8995_AIF1_DAC2_EQ_GAINS_2:
+       case WM8995_AIF1_DAC2_EQ_BAND_1_A:
+       case WM8995_AIF1_DAC2_EQ_BAND_1_B:
+       case WM8995_AIF1_DAC2_EQ_BAND_1_PG:
+       case WM8995_AIF1_DAC2_EQ_BAND_2_A:
+       case WM8995_AIF1_DAC2_EQ_BAND_2_B:
+       case WM8995_AIF1_DAC2_EQ_BAND_2_C:
+       case WM8995_AIF1_DAC2_EQ_BAND_2_PG:
+       case WM8995_AIF1_DAC2_EQ_BAND_3_A:
+       case WM8995_AIF1_DAC2_EQ_BAND_3_B:
+       case WM8995_AIF1_DAC2_EQ_BAND_3_C:
+       case WM8995_AIF1_DAC2_EQ_BAND_3_PG:
+       case WM8995_AIF1_DAC2_EQ_BAND_4_A:
+       case WM8995_AIF1_DAC2_EQ_BAND_4_B:
+       case WM8995_AIF1_DAC2_EQ_BAND_4_C:
+       case WM8995_AIF1_DAC2_EQ_BAND_4_PG:
+       case WM8995_AIF1_DAC2_EQ_BAND_5_A:
+       case WM8995_AIF1_DAC2_EQ_BAND_5_B:
+       case WM8995_AIF1_DAC2_EQ_BAND_5_PG:
+       case WM8995_AIF2_ADC_LEFT_VOLUME:
+       case WM8995_AIF2_ADC_RIGHT_VOLUME:
+       case WM8995_AIF2_DAC_LEFT_VOLUME:
+       case WM8995_AIF2_DAC_RIGHT_VOLUME:
+       case WM8995_AIF2_ADC_FILTERS:
+       case WM8995_AIF2_DAC_FILTERS_1:
+       case WM8995_AIF2_DAC_FILTERS_2:
+       case WM8995_AIF2_DRC_1:
+       case WM8995_AIF2_DRC_2:
+       case WM8995_AIF2_DRC_3:
+       case WM8995_AIF2_DRC_4:
+       case WM8995_AIF2_DRC_5:
+       case WM8995_AIF2_EQ_GAINS_1:
+       case WM8995_AIF2_EQ_GAINS_2:
+       case WM8995_AIF2_EQ_BAND_1_A:
+       case WM8995_AIF2_EQ_BAND_1_B:
+       case WM8995_AIF2_EQ_BAND_1_PG:
+       case WM8995_AIF2_EQ_BAND_2_A:
+       case WM8995_AIF2_EQ_BAND_2_B:
+       case WM8995_AIF2_EQ_BAND_2_C:
+       case WM8995_AIF2_EQ_BAND_2_PG:
+       case WM8995_AIF2_EQ_BAND_3_A:
+       case WM8995_AIF2_EQ_BAND_3_B:
+       case WM8995_AIF2_EQ_BAND_3_C:
+       case WM8995_AIF2_EQ_BAND_3_PG:
+       case WM8995_AIF2_EQ_BAND_4_A:
+       case WM8995_AIF2_EQ_BAND_4_B:
+       case WM8995_AIF2_EQ_BAND_4_C:
+       case WM8995_AIF2_EQ_BAND_4_PG:
+       case WM8995_AIF2_EQ_BAND_5_A:
+       case WM8995_AIF2_EQ_BAND_5_B:
+       case WM8995_AIF2_EQ_BAND_5_PG:
+       case WM8995_DAC1_MIXER_VOLUMES:
+       case WM8995_DAC1_LEFT_MIXER_ROUTING:
+       case WM8995_DAC1_RIGHT_MIXER_ROUTING:
+       case WM8995_DAC2_MIXER_VOLUMES:
+       case WM8995_DAC2_LEFT_MIXER_ROUTING:
+       case WM8995_DAC2_RIGHT_MIXER_ROUTING:
+       case WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING:
+       case WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING:
+       case WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING:
+       case WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING:
+       case WM8995_DAC_SOFTMUTE:
+       case WM8995_OVERSAMPLING:
+       case WM8995_SIDETONE:
+       case WM8995_GPIO_1:
+       case WM8995_GPIO_2:
+       case WM8995_GPIO_3:
+       case WM8995_GPIO_4:
+       case WM8995_GPIO_5:
+       case WM8995_GPIO_6:
+       case WM8995_GPIO_7:
+       case WM8995_GPIO_8:
+       case WM8995_GPIO_9:
+       case WM8995_GPIO_10:
+       case WM8995_GPIO_11:
+       case WM8995_GPIO_12:
+       case WM8995_GPIO_13:
+       case WM8995_GPIO_14:
+       case WM8995_PULL_CONTROL_1:
+       case WM8995_PULL_CONTROL_2:
        case WM8995_INTERRUPT_STATUS_1:
        case WM8995_INTERRUPT_STATUS_2:
+       case WM8995_INTERRUPT_RAW_STATUS_2:
        case WM8995_INTERRUPT_STATUS_1_MASK:
        case WM8995_INTERRUPT_STATUS_2_MASK:
        case WM8995_INTERRUPT_CONTROL:
+       case WM8995_LEFT_PDM_SPEAKER_1:
+       case WM8995_RIGHT_PDM_SPEAKER_1:
+       case WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE:
+       case WM8995_LEFT_PDM_SPEAKER_2:
+       case WM8995_RIGHT_PDM_SPEAKER_2:
+       case WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool wm8995_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case WM8995_SOFTWARE_RESET:
+       case WM8995_DC_SERVO_READBACK_0:
+       case WM8995_INTERRUPT_STATUS_1:
+       case WM8995_INTERRUPT_STATUS_2:
+       case WM8995_INTERRUPT_CONTROL:
        case WM8995_ACCESSORY_DETECT_MODE1:
        case WM8995_ACCESSORY_DETECT_MODE2:
        case WM8995_HEADPHONE_DETECT1:
        case WM8995_HEADPHONE_DETECT2:
-               return 1;
+       case WM8995_RATE_STATUS:
+               return true;
+       default:
+               return false;
        }
-
-       return 0;
 }
 
 static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
@@ -1526,7 +1985,7 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
                        if (ret)
                                return ret;
 
-                       ret = snd_soc_cache_sync(codec);
+                       ret = regcache_sync(wm8995->regmap);
                        if (ret) {
                                dev_err(codec->dev,
                                        "Failed to sync cache: %d\n", ret);
@@ -1592,7 +2051,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
        wm8995 = snd_soc_codec_get_drvdata(codec);
        wm8995->codec = codec;
 
-       ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
+       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
        if (ret < 0) {
                dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
                return ret;
@@ -1696,7 +2155,7 @@ err_reg_get:
 #define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
+static const struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
        .set_sysclk = wm8995_set_dai_sysclk,
        .set_fmt = wm8995_set_dai_fmt,
        .hw_params = wm8995_hw_params,
@@ -1705,7 +2164,7 @@ static struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
        .set_tristate = wm8995_set_tristate,
 };
 
-static struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
+static const struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
        .set_sysclk = wm8995_set_dai_sysclk,
        .set_fmt = wm8995_set_dai_fmt,
        .hw_params = wm8995_hw_params,
@@ -1714,7 +2173,7 @@ static struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
        .set_tristate = wm8995_set_tristate,
 };
 
-static struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
+static const struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
        .set_tristate = wm8995_set_tristate,
 };
 
@@ -1781,11 +2240,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
        .suspend = wm8995_suspend,
        .resume = wm8995_resume,
        .set_bias_level = wm8995_set_bias_level,
-       .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs),
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8995_reg_defs,
-       .volatile_register = wm8995_volatile,
-       .compress_type = SND_SOC_RBTREE_COMPRESSION
+};
+
+static struct regmap_config wm8995_regmap = {
+       .reg_bits = 16,
+       .val_bits = 16,
+
+       .max_register = WM8995_MAX_REGISTER,
+       .reg_defaults = wm8995_reg_defaults,
+       .num_reg_defaults = ARRAY_SIZE(wm8995_reg_defaults),
+       .volatile_reg = wm8995_volatile,
+       .readable_reg = wm8995_readable,
+       .cache_type = REGCACHE_RBTREE,
 };
 
 #if defined(CONFIG_SPI_MASTER)
@@ -1798,21 +2264,37 @@ static int __devinit wm8995_spi_probe(struct spi_device *spi)
        if (!wm8995)
                return -ENOMEM;
 
-       wm8995->control_type = SND_SOC_SPI;
        spi_set_drvdata(spi, wm8995);
 
+       wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap);
+       if (IS_ERR(wm8995->regmap)) {
+               ret = PTR_ERR(wm8995->regmap);
+               dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
+               goto err_alloc;
+       }
+
        ret = snd_soc_register_codec(&spi->dev,
                                     &soc_codec_dev_wm8995, wm8995_dai,
                                     ARRAY_SIZE(wm8995_dai));
        if (ret < 0)
-               kfree(wm8995);
+               goto err_regmap;
+
+       return ret;
+
+err_regmap:
+       regmap_exit(wm8995->regmap);
+err_alloc:
+       kfree(wm8995);
+
        return ret;
 }
 
 static int __devexit wm8995_spi_remove(struct spi_device *spi)
 {
+       struct wm8995_priv *wm8995 = spi_get_drvdata(spi);
        snd_soc_unregister_codec(&spi->dev);
-       kfree(spi_get_drvdata(spi));
+       regmap_exit(wm8995->regmap);
+       kfree(wm8995);
        return 0;
 }
 
@@ -1837,21 +2319,40 @@ static __devinit int wm8995_i2c_probe(struct i2c_client *i2c,
        if (!wm8995)
                return -ENOMEM;
 
-       wm8995->control_type = SND_SOC_I2C;
        i2c_set_clientdata(i2c, wm8995);
 
+       wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap);
+       if (IS_ERR(wm8995->regmap)) {
+               ret = PTR_ERR(wm8995->regmap);
+               dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret);
+               goto err_alloc;
+       }
+
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8995, wm8995_dai,
                                     ARRAY_SIZE(wm8995_dai));
-       if (ret < 0)
-               kfree(wm8995);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+               goto err_regmap;
+       }
+
+       return ret;
+
+err_regmap:
+       regmap_exit(wm8995->regmap);
+err_alloc:
+       kfree(wm8995);
+
        return ret;
 }
 
 static __devexit int wm8995_i2c_remove(struct i2c_client *client)
 {
+       struct wm8995_priv *wm8995 = i2c_get_clientdata(client);
+
        snd_soc_unregister_codec(&client->dev);
-       kfree(i2c_get_clientdata(client));
+       regmap_exit(wm8995->regmap);
+       kfree(wm8995);
        return 0;
 }
 
index 645c980d6b80edd81b1f0886c013c34f884346d6..41cc9d2d5ae9c36289e7ea687bcac8cfc5d213c2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gcd.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
@@ -49,6 +50,8 @@ static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
 };
 
 struct wm8996_priv {
+       struct device *dev;
+       struct regmap *regmap;
        struct snd_soc_codec *codec;
 
        int ldo1ena;
@@ -105,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
        struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
                                                  disable_nb[n]); \
        if (event & REGULATOR_EVENT_DISABLE) { \
-               wm8996->codec->cache_sync = 1; \
+               regcache_cache_only(wm8996->regmap, true);      \
        } \
        return 0; \
 }
@@ -114,297 +117,365 @@ WM8996_REGULATOR_EVENT(0)
 WM8996_REGULATOR_EVENT(1)
 WM8996_REGULATOR_EVENT(2)
 
-static const u16 wm8996_reg[WM8996_MAX_REGISTER] = {
-       [WM8996_SOFTWARE_RESET] = 0x8996,
-       [WM8996_POWER_MANAGEMENT_7] = 0x10,
-       [WM8996_DAC1_HPOUT1_VOLUME] = 0x88,
-       [WM8996_DAC2_HPOUT2_VOLUME] = 0x88,
-       [WM8996_DAC1_LEFT_VOLUME] = 0x2c0,
-       [WM8996_DAC1_RIGHT_VOLUME] = 0x2c0,
-       [WM8996_DAC2_LEFT_VOLUME] = 0x2c0,
-       [WM8996_DAC2_RIGHT_VOLUME] = 0x2c0,
-       [WM8996_OUTPUT1_LEFT_VOLUME] = 0x80,
-       [WM8996_OUTPUT1_RIGHT_VOLUME] = 0x80,
-       [WM8996_OUTPUT2_LEFT_VOLUME] = 0x80,
-       [WM8996_OUTPUT2_RIGHT_VOLUME] = 0x80,
-       [WM8996_MICBIAS_1] = 0x39,
-       [WM8996_MICBIAS_2] = 0x39,
-       [WM8996_LDO_1] = 0x3,
-       [WM8996_LDO_2] = 0x13,
-       [WM8996_ACCESSORY_DETECT_MODE_1] = 0x4,
-       [WM8996_HEADPHONE_DETECT_1] = 0x20,
-       [WM8996_MIC_DETECT_1] = 0x7600,
-       [WM8996_MIC_DETECT_2] = 0xbf,
-       [WM8996_CHARGE_PUMP_1] = 0x1f25,
-       [WM8996_CHARGE_PUMP_2] = 0xab19,
-       [WM8996_DC_SERVO_5] = 0x2a2a,
-       [WM8996_CONTROL_INTERFACE_1] = 0x8004,
-       [WM8996_CLOCKING_1] = 0x10,
-       [WM8996_AIF_RATE] = 0x83,
-       [WM8996_FLL_CONTROL_4] = 0x5dc0,
-       [WM8996_FLL_CONTROL_5] = 0xc84,
-       [WM8996_FLL_EFS_2] = 0x2,
-       [WM8996_AIF1_TX_LRCLK_1] = 0x80,
-       [WM8996_AIF1_TX_LRCLK_2] = 0x8,
-       [WM8996_AIF1_RX_LRCLK_1] = 0x80,
-       [WM8996_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
-       [WM8996_AIF1RX_DATA_CONFIGURATION] = 0x1818,
-       [WM8996_AIF1TX_TEST] = 0x7,
-       [WM8996_AIF2_TX_LRCLK_1] = 0x80,
-       [WM8996_AIF2_TX_LRCLK_2] = 0x8,
-       [WM8996_AIF2_RX_LRCLK_1] = 0x80,
-       [WM8996_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
-       [WM8996_AIF2RX_DATA_CONFIGURATION] = 0x1818,
-       [WM8996_AIF2TX_TEST] = 0x1,
-       [WM8996_DSP1_TX_LEFT_VOLUME] = 0xc0,
-       [WM8996_DSP1_TX_RIGHT_VOLUME] = 0xc0,
-       [WM8996_DSP1_RX_LEFT_VOLUME] = 0xc0,
-       [WM8996_DSP1_RX_RIGHT_VOLUME] = 0xc0,
-       [WM8996_DSP1_TX_FILTERS] = 0x2000,
-       [WM8996_DSP1_RX_FILTERS_1] = 0x200,
-       [WM8996_DSP1_RX_FILTERS_2] = 0x10,
-       [WM8996_DSP1_DRC_1] = 0x98,
-       [WM8996_DSP1_DRC_2] = 0x845,
-       [WM8996_DSP1_RX_EQ_GAINS_1] = 0x6318,
-       [WM8996_DSP1_RX_EQ_GAINS_2] = 0x6300,
-       [WM8996_DSP1_RX_EQ_BAND_1_A] = 0xfca,
-       [WM8996_DSP1_RX_EQ_BAND_1_B] = 0x400,
-       [WM8996_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
-       [WM8996_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
-       [WM8996_DSP1_RX_EQ_BAND_2_B] = 0xf145,
-       [WM8996_DSP1_RX_EQ_BAND_2_C] = 0xb75,
-       [WM8996_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
-       [WM8996_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
-       [WM8996_DSP1_RX_EQ_BAND_3_B] = 0xf373,
-       [WM8996_DSP1_RX_EQ_BAND_3_C] = 0xa54,
-       [WM8996_DSP1_RX_EQ_BAND_3_PG] = 0x558,
-       [WM8996_DSP1_RX_EQ_BAND_4_A] = 0x168e,
-       [WM8996_DSP1_RX_EQ_BAND_4_B] = 0xf829,
-       [WM8996_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
-       [WM8996_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
-       [WM8996_DSP1_RX_EQ_BAND_5_A] = 0x564,
-       [WM8996_DSP1_RX_EQ_BAND_5_B] = 0x559,
-       [WM8996_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
-       [WM8996_DSP2_TX_LEFT_VOLUME] = 0xc0,
-       [WM8996_DSP2_TX_RIGHT_VOLUME] = 0xc0,
-       [WM8996_DSP2_RX_LEFT_VOLUME] = 0xc0,
-       [WM8996_DSP2_RX_RIGHT_VOLUME] = 0xc0,
-       [WM8996_DSP2_TX_FILTERS] = 0x2000,
-       [WM8996_DSP2_RX_FILTERS_1] = 0x200,
-       [WM8996_DSP2_RX_FILTERS_2] = 0x10,
-       [WM8996_DSP2_DRC_1] = 0x98,
-       [WM8996_DSP2_DRC_2] = 0x845,
-       [WM8996_DSP2_RX_EQ_GAINS_1] = 0x6318,
-       [WM8996_DSP2_RX_EQ_GAINS_2] = 0x6300,
-       [WM8996_DSP2_RX_EQ_BAND_1_A] = 0xfca,
-       [WM8996_DSP2_RX_EQ_BAND_1_B] = 0x400,
-       [WM8996_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
-       [WM8996_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
-       [WM8996_DSP2_RX_EQ_BAND_2_B] = 0xf145,
-       [WM8996_DSP2_RX_EQ_BAND_2_C] = 0xb75,
-       [WM8996_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
-       [WM8996_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
-       [WM8996_DSP2_RX_EQ_BAND_3_B] = 0xf373,
-       [WM8996_DSP2_RX_EQ_BAND_3_C] = 0xa54,
-       [WM8996_DSP2_RX_EQ_BAND_3_PG] = 0x558,
-       [WM8996_DSP2_RX_EQ_BAND_4_A] = 0x168e,
-       [WM8996_DSP2_RX_EQ_BAND_4_B] = 0xf829,
-       [WM8996_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
-       [WM8996_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
-       [WM8996_DSP2_RX_EQ_BAND_5_A] = 0x564,
-       [WM8996_DSP2_RX_EQ_BAND_5_B] = 0x559,
-       [WM8996_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
-       [WM8996_OVERSAMPLING] = 0xd,
-       [WM8996_SIDETONE] = 0x1040,
-       [WM8996_GPIO_1] = 0xa101,
-       [WM8996_GPIO_2] = 0xa101,
-       [WM8996_GPIO_3] = 0xa101,
-       [WM8996_GPIO_4] = 0xa101,
-       [WM8996_GPIO_5] = 0xa101,
-       [WM8996_PULL_CONTROL_2] = 0x140,
-       [WM8996_INTERRUPT_STATUS_1_MASK] = 0x1f,
-       [WM8996_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
-       [WM8996_RIGHT_PDM_SPEAKER] = 0x1,
-       [WM8996_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
-       [WM8996_PDM_SPEAKER_VOLUME] = 0x66,
-       [WM8996_WRITE_SEQUENCER_0] = 0x1,
-       [WM8996_WRITE_SEQUENCER_1] = 0x1,
-       [WM8996_WRITE_SEQUENCER_3] = 0x6,
-       [WM8996_WRITE_SEQUENCER_4] = 0x40,
-       [WM8996_WRITE_SEQUENCER_5] = 0x1,
-       [WM8996_WRITE_SEQUENCER_6] = 0xf,
-       [WM8996_WRITE_SEQUENCER_7] = 0x6,
-       [WM8996_WRITE_SEQUENCER_8] = 0x1,
-       [WM8996_WRITE_SEQUENCER_9] = 0x3,
-       [WM8996_WRITE_SEQUENCER_10] = 0x104,
-       [WM8996_WRITE_SEQUENCER_12] = 0x60,
-       [WM8996_WRITE_SEQUENCER_13] = 0x11,
-       [WM8996_WRITE_SEQUENCER_14] = 0x401,
-       [WM8996_WRITE_SEQUENCER_16] = 0x50,
-       [WM8996_WRITE_SEQUENCER_17] = 0x3,
-       [WM8996_WRITE_SEQUENCER_18] = 0x100,
-       [WM8996_WRITE_SEQUENCER_20] = 0x51,
-       [WM8996_WRITE_SEQUENCER_21] = 0x3,
-       [WM8996_WRITE_SEQUENCER_22] = 0x104,
-       [WM8996_WRITE_SEQUENCER_23] = 0xa,
-       [WM8996_WRITE_SEQUENCER_24] = 0x60,
-       [WM8996_WRITE_SEQUENCER_25] = 0x3b,
-       [WM8996_WRITE_SEQUENCER_26] = 0x502,
-       [WM8996_WRITE_SEQUENCER_27] = 0x100,
-       [WM8996_WRITE_SEQUENCER_28] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_32] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_36] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_40] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_44] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_48] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_52] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_56] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_60] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_64] = 0x1,
-       [WM8996_WRITE_SEQUENCER_65] = 0x1,
-       [WM8996_WRITE_SEQUENCER_67] = 0x6,
-       [WM8996_WRITE_SEQUENCER_68] = 0x40,
-       [WM8996_WRITE_SEQUENCER_69] = 0x1,
-       [WM8996_WRITE_SEQUENCER_70] = 0xf,
-       [WM8996_WRITE_SEQUENCER_71] = 0x6,
-       [WM8996_WRITE_SEQUENCER_72] = 0x1,
-       [WM8996_WRITE_SEQUENCER_73] = 0x3,
-       [WM8996_WRITE_SEQUENCER_74] = 0x104,
-       [WM8996_WRITE_SEQUENCER_76] = 0x60,
-       [WM8996_WRITE_SEQUENCER_77] = 0x11,
-       [WM8996_WRITE_SEQUENCER_78] = 0x401,
-       [WM8996_WRITE_SEQUENCER_80] = 0x50,
-       [WM8996_WRITE_SEQUENCER_81] = 0x3,
-       [WM8996_WRITE_SEQUENCER_82] = 0x100,
-       [WM8996_WRITE_SEQUENCER_84] = 0x60,
-       [WM8996_WRITE_SEQUENCER_85] = 0x3b,
-       [WM8996_WRITE_SEQUENCER_86] = 0x502,
-       [WM8996_WRITE_SEQUENCER_87] = 0x100,
-       [WM8996_WRITE_SEQUENCER_88] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_92] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_96] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_100] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_104] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_108] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_112] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_116] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_120] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_124] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_128] = 0x1,
-       [WM8996_WRITE_SEQUENCER_129] = 0x1,
-       [WM8996_WRITE_SEQUENCER_131] = 0x6,
-       [WM8996_WRITE_SEQUENCER_132] = 0x40,
-       [WM8996_WRITE_SEQUENCER_133] = 0x1,
-       [WM8996_WRITE_SEQUENCER_134] = 0xf,
-       [WM8996_WRITE_SEQUENCER_135] = 0x6,
-       [WM8996_WRITE_SEQUENCER_136] = 0x1,
-       [WM8996_WRITE_SEQUENCER_137] = 0x3,
-       [WM8996_WRITE_SEQUENCER_138] = 0x106,
-       [WM8996_WRITE_SEQUENCER_140] = 0x61,
-       [WM8996_WRITE_SEQUENCER_141] = 0x11,
-       [WM8996_WRITE_SEQUENCER_142] = 0x401,
-       [WM8996_WRITE_SEQUENCER_144] = 0x50,
-       [WM8996_WRITE_SEQUENCER_145] = 0x3,
-       [WM8996_WRITE_SEQUENCER_146] = 0x102,
-       [WM8996_WRITE_SEQUENCER_148] = 0x51,
-       [WM8996_WRITE_SEQUENCER_149] = 0x3,
-       [WM8996_WRITE_SEQUENCER_150] = 0x106,
-       [WM8996_WRITE_SEQUENCER_151] = 0xa,
-       [WM8996_WRITE_SEQUENCER_152] = 0x61,
-       [WM8996_WRITE_SEQUENCER_153] = 0x3b,
-       [WM8996_WRITE_SEQUENCER_154] = 0x502,
-       [WM8996_WRITE_SEQUENCER_155] = 0x100,
-       [WM8996_WRITE_SEQUENCER_156] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_160] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_164] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_168] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_172] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_176] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_180] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_184] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_188] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_192] = 0x1,
-       [WM8996_WRITE_SEQUENCER_193] = 0x1,
-       [WM8996_WRITE_SEQUENCER_195] = 0x6,
-       [WM8996_WRITE_SEQUENCER_196] = 0x40,
-       [WM8996_WRITE_SEQUENCER_197] = 0x1,
-       [WM8996_WRITE_SEQUENCER_198] = 0xf,
-       [WM8996_WRITE_SEQUENCER_199] = 0x6,
-       [WM8996_WRITE_SEQUENCER_200] = 0x1,
-       [WM8996_WRITE_SEQUENCER_201] = 0x3,
-       [WM8996_WRITE_SEQUENCER_202] = 0x106,
-       [WM8996_WRITE_SEQUENCER_204] = 0x61,
-       [WM8996_WRITE_SEQUENCER_205] = 0x11,
-       [WM8996_WRITE_SEQUENCER_206] = 0x401,
-       [WM8996_WRITE_SEQUENCER_208] = 0x50,
-       [WM8996_WRITE_SEQUENCER_209] = 0x3,
-       [WM8996_WRITE_SEQUENCER_210] = 0x102,
-       [WM8996_WRITE_SEQUENCER_212] = 0x61,
-       [WM8996_WRITE_SEQUENCER_213] = 0x3b,
-       [WM8996_WRITE_SEQUENCER_214] = 0x502,
-       [WM8996_WRITE_SEQUENCER_215] = 0x100,
-       [WM8996_WRITE_SEQUENCER_216] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_220] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_224] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_228] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_232] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_236] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_240] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_244] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_248] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_252] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_256] = 0x60,
-       [WM8996_WRITE_SEQUENCER_258] = 0x601,
-       [WM8996_WRITE_SEQUENCER_260] = 0x50,
-       [WM8996_WRITE_SEQUENCER_262] = 0x100,
-       [WM8996_WRITE_SEQUENCER_264] = 0x1,
-       [WM8996_WRITE_SEQUENCER_266] = 0x104,
-       [WM8996_WRITE_SEQUENCER_267] = 0x100,
-       [WM8996_WRITE_SEQUENCER_268] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_272] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_276] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_280] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_284] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_288] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_292] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_296] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_300] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_304] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_308] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_312] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_316] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_320] = 0x61,
-       [WM8996_WRITE_SEQUENCER_322] = 0x601,
-       [WM8996_WRITE_SEQUENCER_324] = 0x50,
-       [WM8996_WRITE_SEQUENCER_326] = 0x102,
-       [WM8996_WRITE_SEQUENCER_328] = 0x1,
-       [WM8996_WRITE_SEQUENCER_330] = 0x106,
-       [WM8996_WRITE_SEQUENCER_331] = 0x100,
-       [WM8996_WRITE_SEQUENCER_332] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_336] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_340] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_344] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_348] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_352] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_356] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_360] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_364] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_368] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_372] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_376] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_380] = 0x2fff,
-       [WM8996_WRITE_SEQUENCER_384] = 0x60,
-       [WM8996_WRITE_SEQUENCER_386] = 0x601,
-       [WM8996_WRITE_SEQUENCER_388] = 0x61,
-       [WM8996_WRITE_SEQUENCER_390] = 0x601,
-       [WM8996_WRITE_SEQUENCER_392] = 0x50,
-       [WM8996_WRITE_SEQUENCER_394] = 0x300,
-       [WM8996_WRITE_SEQUENCER_396] = 0x1,
-       [WM8996_WRITE_SEQUENCER_398] = 0x304,
-       [WM8996_WRITE_SEQUENCER_400] = 0x40,
-       [WM8996_WRITE_SEQUENCER_402] = 0xf,
-       [WM8996_WRITE_SEQUENCER_404] = 0x1,
-       [WM8996_WRITE_SEQUENCER_407] = 0x100,
+static struct reg_default wm8996_reg[] = {
+       { WM8996_SOFTWARE_RESET, 0x8996 },
+       { WM8996_POWER_MANAGEMENT_1, 0x0 },
+       { WM8996_POWER_MANAGEMENT_2, 0x0 },
+       { WM8996_POWER_MANAGEMENT_3, 0x0 },
+       { WM8996_POWER_MANAGEMENT_4, 0x0 },
+       { WM8996_POWER_MANAGEMENT_5, 0x0 },
+       { WM8996_POWER_MANAGEMENT_6, 0x0 },
+       { WM8996_POWER_MANAGEMENT_7, 0x10 },
+       { WM8996_POWER_MANAGEMENT_8, 0x0 },
+       { WM8996_LEFT_LINE_INPUT_VOLUME, 0x0 },
+       { WM8996_RIGHT_LINE_INPUT_VOLUME, 0x0 },
+       { WM8996_LINE_INPUT_CONTROL, 0x0 },
+       { WM8996_DAC1_HPOUT1_VOLUME, 0x88 },
+       { WM8996_DAC2_HPOUT2_VOLUME, 0x88 },
+       { WM8996_DAC1_LEFT_VOLUME, 0x2c0 },
+       { WM8996_DAC1_RIGHT_VOLUME, 0x2c0 },
+       { WM8996_DAC2_LEFT_VOLUME, 0x2c0 },
+       { WM8996_DAC2_RIGHT_VOLUME, 0x2c0 },
+       { WM8996_OUTPUT1_LEFT_VOLUME, 0x80 },
+       { WM8996_OUTPUT1_RIGHT_VOLUME, 0x80 },
+       { WM8996_OUTPUT2_LEFT_VOLUME, 0x80 },
+       { WM8996_OUTPUT2_RIGHT_VOLUME, 0x80 },
+       { WM8996_MICBIAS_1, 0x39 },
+       { WM8996_MICBIAS_2, 0x39 },
+       { WM8996_LDO_1, 0x3 },
+       { WM8996_LDO_2, 0x13 },
+       { WM8996_ACCESSORY_DETECT_MODE_1, 0x4 },
+       { WM8996_ACCESSORY_DETECT_MODE_2, 0x0 },
+       { WM8996_HEADPHONE_DETECT_1, 0x20 },
+       { WM8996_HEADPHONE_DETECT_2, 0x0 },
+       { WM8996_MIC_DETECT_1, 0x7600 },
+       { WM8996_MIC_DETECT_2, 0xbf },
+       { WM8996_CHARGE_PUMP_1, 0x1f25 },
+       { WM8996_CHARGE_PUMP_2, 0xab19 },
+       { WM8996_DC_SERVO_1, 0x0 },
+       { WM8996_DC_SERVO_2, 0x0 },
+       { WM8996_DC_SERVO_3, 0x0 },
+       { WM8996_DC_SERVO_5, 0x2a2a },
+       { WM8996_DC_SERVO_6, 0x0 },
+       { WM8996_DC_SERVO_7, 0x0 },
+       { WM8996_ANALOGUE_HP_1, 0x0 },
+       { WM8996_ANALOGUE_HP_2, 0x0 },
+       { WM8996_CONTROL_INTERFACE_1, 0x8004 },
+       { WM8996_WRITE_SEQUENCER_CTRL_1, 0x0 },
+       { WM8996_WRITE_SEQUENCER_CTRL_2, 0x0 },
+       { WM8996_AIF_CLOCKING_1, 0x0 },
+       { WM8996_AIF_CLOCKING_2, 0x0 },
+       { WM8996_CLOCKING_1, 0x10 },
+       { WM8996_CLOCKING_2, 0x0 },
+       { WM8996_AIF_RATE, 0x83 },
+       { WM8996_FLL_CONTROL_1, 0x0 },
+       { WM8996_FLL_CONTROL_2, 0x0 },
+       { WM8996_FLL_CONTROL_3, 0x0 },
+       { WM8996_FLL_CONTROL_4, 0x5dc0 },
+       { WM8996_FLL_CONTROL_5, 0xc84 },
+       { WM8996_FLL_EFS_1, 0x0 },
+       { WM8996_FLL_EFS_2, 0x2 },
+       { WM8996_AIF1_CONTROL, 0x0 },
+       { WM8996_AIF1_BCLK, 0x0 },
+       { WM8996_AIF1_TX_LRCLK_1, 0x80 },
+       { WM8996_AIF1_TX_LRCLK_2, 0x8 },
+       { WM8996_AIF1_RX_LRCLK_1, 0x80 },
+       { WM8996_AIF1_RX_LRCLK_2, 0x0 },
+       { WM8996_AIF1TX_DATA_CONFIGURATION_1, 0x1818 },
+       { WM8996_AIF1TX_DATA_CONFIGURATION_2, 0 },
+       { WM8996_AIF1RX_DATA_CONFIGURATION, 0x1818 },
+       { WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, 0x0 },
+       { WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, 0x0 },
+       { WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, 0x0 },
+       { WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, 0x0 },
+       { WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, 0x0 },
+       { WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, 0x0 },
+       { WM8996_AIF1RX_MONO_CONFIGURATION, 0x0 },
+       { WM8996_AIF1TX_TEST, 0x7 },
+       { WM8996_AIF2_CONTROL, 0x0 },
+       { WM8996_AIF2_BCLK, 0x0 },
+       { WM8996_AIF2_TX_LRCLK_1, 0x80 },
+       { WM8996_AIF2_TX_LRCLK_2, 0x8 },
+       { WM8996_AIF2_RX_LRCLK_1, 0x80 },
+       { WM8996_AIF2_RX_LRCLK_2, 0x0 },
+       { WM8996_AIF2TX_DATA_CONFIGURATION_1, 0x1818 },
+       { WM8996_AIF2RX_DATA_CONFIGURATION, 0x1818 },
+       { WM8996_AIF2RX_DATA_CONFIGURATION, 0x0 },
+       { WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, 0x0 },
+       { WM8996_AIF2TX_CHANNEL_1_CONFIGURATION, 0x0 },
+       { WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, 0x0 },
+       { WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, 0x0 },
+       { WM8996_AIF2RX_MONO_CONFIGURATION, 0x0 },
+       { WM8996_AIF2TX_TEST, 0x1 },
+       { WM8996_DSP1_TX_LEFT_VOLUME, 0xc0 },
+       { WM8996_DSP1_TX_RIGHT_VOLUME, 0xc0 },
+       { WM8996_DSP1_RX_LEFT_VOLUME, 0xc0 },
+       { WM8996_DSP1_RX_RIGHT_VOLUME, 0xc0 },
+       { WM8996_DSP1_TX_FILTERS, 0x2000 },
+       { WM8996_DSP1_RX_FILTERS_1, 0x200 },
+       { WM8996_DSP1_RX_FILTERS_2, 0x10 },
+       { WM8996_DSP1_DRC_1, 0x98 },
+       { WM8996_DSP1_DRC_2, 0x845 },
+       { WM8996_DSP1_RX_EQ_GAINS_1, 0x6318 },
+       { WM8996_DSP1_RX_EQ_GAINS_2, 0x6300 },
+       { WM8996_DSP1_RX_EQ_BAND_1_A, 0xfca },
+       { WM8996_DSP1_RX_EQ_BAND_1_B, 0x400 },
+       { WM8996_DSP1_RX_EQ_BAND_1_PG, 0xd8 },
+       { WM8996_DSP1_RX_EQ_BAND_2_A, 0x1eb5 },
+       { WM8996_DSP1_RX_EQ_BAND_2_B, 0xf145 },
+       { WM8996_DSP1_RX_EQ_BAND_2_C, 0xb75 },
+       { WM8996_DSP1_RX_EQ_BAND_2_PG, 0x1c5 },
+       { WM8996_DSP1_RX_EQ_BAND_3_A, 0x1c58 },
+       { WM8996_DSP1_RX_EQ_BAND_3_B, 0xf373 },
+       { WM8996_DSP1_RX_EQ_BAND_3_C, 0xa54 },
+       { WM8996_DSP1_RX_EQ_BAND_3_PG, 0x558 },
+       { WM8996_DSP1_RX_EQ_BAND_4_A, 0x168e },
+       { WM8996_DSP1_RX_EQ_BAND_4_B, 0xf829 },
+       { WM8996_DSP1_RX_EQ_BAND_4_C, 0x7ad },
+       { WM8996_DSP1_RX_EQ_BAND_4_PG, 0x1103 },
+       { WM8996_DSP1_RX_EQ_BAND_5_A, 0x564 },
+       { WM8996_DSP1_RX_EQ_BAND_5_B, 0x559 },
+       { WM8996_DSP1_RX_EQ_BAND_5_PG, 0x4000 },
+       { WM8996_DSP2_TX_LEFT_VOLUME, 0xc0 },
+       { WM8996_DSP2_TX_RIGHT_VOLUME, 0xc0 },
+       { WM8996_DSP2_RX_LEFT_VOLUME, 0xc0 },
+       { WM8996_DSP2_RX_RIGHT_VOLUME, 0xc0 },
+       { WM8996_DSP2_TX_FILTERS, 0x2000 },
+       { WM8996_DSP2_RX_FILTERS_1, 0x200 },
+       { WM8996_DSP2_RX_FILTERS_2, 0x10 },
+       { WM8996_DSP2_DRC_1, 0x98 },
+       { WM8996_DSP2_DRC_2, 0x845 },
+       { WM8996_DSP2_RX_EQ_GAINS_1, 0x6318 },
+       { WM8996_DSP2_RX_EQ_GAINS_2, 0x6300 },
+       { WM8996_DSP2_RX_EQ_BAND_1_A, 0xfca },
+       { WM8996_DSP2_RX_EQ_BAND_1_B, 0x400 },
+       { WM8996_DSP2_RX_EQ_BAND_1_PG, 0xd8 },
+       { WM8996_DSP2_RX_EQ_BAND_2_A, 0x1eb5 },
+       { WM8996_DSP2_RX_EQ_BAND_2_B, 0xf145 },
+       { WM8996_DSP2_RX_EQ_BAND_2_C, 0xb75 },
+       { WM8996_DSP2_RX_EQ_BAND_2_PG, 0x1c5 },
+       { WM8996_DSP2_RX_EQ_BAND_3_A, 0x1c58 },
+       { WM8996_DSP2_RX_EQ_BAND_3_B, 0xf373 },
+       { WM8996_DSP2_RX_EQ_BAND_3_C, 0xa54 },
+       { WM8996_DSP2_RX_EQ_BAND_3_PG, 0x558 },
+       { WM8996_DSP2_RX_EQ_BAND_4_A, 0x168e },
+       { WM8996_DSP2_RX_EQ_BAND_4_B, 0xf829 },
+       { WM8996_DSP2_RX_EQ_BAND_4_C, 0x7ad },
+       { WM8996_DSP2_RX_EQ_BAND_4_PG, 0x1103 },
+       { WM8996_DSP2_RX_EQ_BAND_5_A, 0x564 },
+       { WM8996_DSP2_RX_EQ_BAND_5_B, 0x559 },
+       { WM8996_DSP2_RX_EQ_BAND_5_PG, 0x4000 },
+       { WM8996_DAC1_MIXER_VOLUMES, 0x0 },
+       { WM8996_DAC1_LEFT_MIXER_ROUTING, 0x0 },
+       { WM8996_DAC1_RIGHT_MIXER_ROUTING, 0x0 },
+       { WM8996_DAC2_MIXER_VOLUMES, 0x0 },
+       { WM8996_DAC2_LEFT_MIXER_ROUTING, 0x0 },
+       { WM8996_DAC2_RIGHT_MIXER_ROUTING, 0x0 },
+       { WM8996_DSP1_TX_LEFT_MIXER_ROUTING, 0x0 },
+       { WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, 0x0 },
+       { WM8996_DSP2_TX_LEFT_MIXER_ROUTING, 0x0 },
+       { WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, 0x0 },
+       { WM8996_DSP_TX_MIXER_SELECT, 0x0 },
+       { WM8996_DAC_SOFTMUTE, 0x0 },
+       { WM8996_OVERSAMPLING, 0xd },
+       { WM8996_SIDETONE, 0x1040 },
+       { WM8996_GPIO_1, 0xa101 },
+       { WM8996_GPIO_2, 0xa101 },
+       { WM8996_GPIO_3, 0xa101 },
+       { WM8996_GPIO_4, 0xa101 },
+       { WM8996_GPIO_5, 0xa101 },
+       { WM8996_PULL_CONTROL_1, 0x0 },
+       { WM8996_PULL_CONTROL_2, 0x140 },
+       { WM8996_INTERRUPT_STATUS_1_MASK, 0x1f },
+       { WM8996_INTERRUPT_STATUS_2_MASK, 0x1ecf },
+       { WM8996_LEFT_PDM_SPEAKER, 0x0 },
+       { WM8996_RIGHT_PDM_SPEAKER, 0x1 },
+       { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },
+       { WM8996_PDM_SPEAKER_VOLUME, 0x66 },
+       { WM8996_WRITE_SEQUENCER_0, 0x1 },
+       { WM8996_WRITE_SEQUENCER_1, 0x1 },
+       { WM8996_WRITE_SEQUENCER_3, 0x6 },
+       { WM8996_WRITE_SEQUENCER_4, 0x40 },
+       { WM8996_WRITE_SEQUENCER_5, 0x1 },
+       { WM8996_WRITE_SEQUENCER_6, 0xf },
+       { WM8996_WRITE_SEQUENCER_7, 0x6 },
+       { WM8996_WRITE_SEQUENCER_8, 0x1 },
+       { WM8996_WRITE_SEQUENCER_9, 0x3 },
+       { WM8996_WRITE_SEQUENCER_10, 0x104 },
+       { WM8996_WRITE_SEQUENCER_12, 0x60 },
+       { WM8996_WRITE_SEQUENCER_13, 0x11 },
+       { WM8996_WRITE_SEQUENCER_14, 0x401 },
+       { WM8996_WRITE_SEQUENCER_16, 0x50 },
+       { WM8996_WRITE_SEQUENCER_17, 0x3 },
+       { WM8996_WRITE_SEQUENCER_18, 0x100 },
+       { WM8996_WRITE_SEQUENCER_20, 0x51 },
+       { WM8996_WRITE_SEQUENCER_21, 0x3 },
+       { WM8996_WRITE_SEQUENCER_22, 0x104 },
+       { WM8996_WRITE_SEQUENCER_23, 0xa },
+       { WM8996_WRITE_SEQUENCER_24, 0x60 },
+       { WM8996_WRITE_SEQUENCER_25, 0x3b },
+       { WM8996_WRITE_SEQUENCER_26, 0x502 },
+       { WM8996_WRITE_SEQUENCER_27, 0x100 },
+       { WM8996_WRITE_SEQUENCER_28, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_32, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_36, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_40, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_44, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_48, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_52, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_56, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_60, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_64, 0x1 },
+       { WM8996_WRITE_SEQUENCER_65, 0x1 },
+       { WM8996_WRITE_SEQUENCER_67, 0x6 },
+       { WM8996_WRITE_SEQUENCER_68, 0x40 },
+       { WM8996_WRITE_SEQUENCER_69, 0x1 },
+       { WM8996_WRITE_SEQUENCER_70, 0xf },
+       { WM8996_WRITE_SEQUENCER_71, 0x6 },
+       { WM8996_WRITE_SEQUENCER_72, 0x1 },
+       { WM8996_WRITE_SEQUENCER_73, 0x3 },
+       { WM8996_WRITE_SEQUENCER_74, 0x104 },
+       { WM8996_WRITE_SEQUENCER_76, 0x60 },
+       { WM8996_WRITE_SEQUENCER_77, 0x11 },
+       { WM8996_WRITE_SEQUENCER_78, 0x401 },
+       { WM8996_WRITE_SEQUENCER_80, 0x50 },
+       { WM8996_WRITE_SEQUENCER_81, 0x3 },
+       { WM8996_WRITE_SEQUENCER_82, 0x100 },
+       { WM8996_WRITE_SEQUENCER_84, 0x60 },
+       { WM8996_WRITE_SEQUENCER_85, 0x3b },
+       { WM8996_WRITE_SEQUENCER_86, 0x502 },
+       { WM8996_WRITE_SEQUENCER_87, 0x100 },
+       { WM8996_WRITE_SEQUENCER_88, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_92, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_96, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_100, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_104, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_108, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_112, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_116, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_120, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_124, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_128, 0x1 },
+       { WM8996_WRITE_SEQUENCER_129, 0x1 },
+       { WM8996_WRITE_SEQUENCER_131, 0x6 },
+       { WM8996_WRITE_SEQUENCER_132, 0x40 },
+       { WM8996_WRITE_SEQUENCER_133, 0x1 },
+       { WM8996_WRITE_SEQUENCER_134, 0xf },
+       { WM8996_WRITE_SEQUENCER_135, 0x6 },
+       { WM8996_WRITE_SEQUENCER_136, 0x1 },
+       { WM8996_WRITE_SEQUENCER_137, 0x3 },
+       { WM8996_WRITE_SEQUENCER_138, 0x106 },
+       { WM8996_WRITE_SEQUENCER_140, 0x61 },
+       { WM8996_WRITE_SEQUENCER_141, 0x11 },
+       { WM8996_WRITE_SEQUENCER_142, 0x401 },
+       { WM8996_WRITE_SEQUENCER_144, 0x50 },
+       { WM8996_WRITE_SEQUENCER_145, 0x3 },
+       { WM8996_WRITE_SEQUENCER_146, 0x102 },
+       { WM8996_WRITE_SEQUENCER_148, 0x51 },
+       { WM8996_WRITE_SEQUENCER_149, 0x3 },
+       { WM8996_WRITE_SEQUENCER_150, 0x106 },
+       { WM8996_WRITE_SEQUENCER_151, 0xa },
+       { WM8996_WRITE_SEQUENCER_152, 0x61 },
+       { WM8996_WRITE_SEQUENCER_153, 0x3b },
+       { WM8996_WRITE_SEQUENCER_154, 0x502 },
+       { WM8996_WRITE_SEQUENCER_155, 0x100 },
+       { WM8996_WRITE_SEQUENCER_156, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_160, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_164, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_168, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_172, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_176, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_180, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_184, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_188, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_192, 0x1 },
+       { WM8996_WRITE_SEQUENCER_193, 0x1 },
+       { WM8996_WRITE_SEQUENCER_195, 0x6 },
+       { WM8996_WRITE_SEQUENCER_196, 0x40 },
+       { WM8996_WRITE_SEQUENCER_197, 0x1 },
+       { WM8996_WRITE_SEQUENCER_198, 0xf },
+       { WM8996_WRITE_SEQUENCER_199, 0x6 },
+       { WM8996_WRITE_SEQUENCER_200, 0x1 },
+       { WM8996_WRITE_SEQUENCER_201, 0x3 },
+       { WM8996_WRITE_SEQUENCER_202, 0x106 },
+       { WM8996_WRITE_SEQUENCER_204, 0x61 },
+       { WM8996_WRITE_SEQUENCER_205, 0x11 },
+       { WM8996_WRITE_SEQUENCER_206, 0x401 },
+       { WM8996_WRITE_SEQUENCER_208, 0x50 },
+       { WM8996_WRITE_SEQUENCER_209, 0x3 },
+       { WM8996_WRITE_SEQUENCER_210, 0x102 },
+       { WM8996_WRITE_SEQUENCER_212, 0x61 },
+       { WM8996_WRITE_SEQUENCER_213, 0x3b },
+       { WM8996_WRITE_SEQUENCER_214, 0x502 },
+       { WM8996_WRITE_SEQUENCER_215, 0x100 },
+       { WM8996_WRITE_SEQUENCER_216, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_220, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_224, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_228, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_232, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_236, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_240, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_244, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_248, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_252, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_256, 0x60 },
+       { WM8996_WRITE_SEQUENCER_258, 0x601 },
+       { WM8996_WRITE_SEQUENCER_260, 0x50 },
+       { WM8996_WRITE_SEQUENCER_262, 0x100 },
+       { WM8996_WRITE_SEQUENCER_264, 0x1 },
+       { WM8996_WRITE_SEQUENCER_266, 0x104 },
+       { WM8996_WRITE_SEQUENCER_267, 0x100 },
+       { WM8996_WRITE_SEQUENCER_268, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_272, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_276, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_280, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_284, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_288, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_292, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_296, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_300, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_304, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_308, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_312, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_316, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_320, 0x61 },
+       { WM8996_WRITE_SEQUENCER_322, 0x601 },
+       { WM8996_WRITE_SEQUENCER_324, 0x50 },
+       { WM8996_WRITE_SEQUENCER_326, 0x102 },
+       { WM8996_WRITE_SEQUENCER_328, 0x1 },
+       { WM8996_WRITE_SEQUENCER_330, 0x106 },
+       { WM8996_WRITE_SEQUENCER_331, 0x100 },
+       { WM8996_WRITE_SEQUENCER_332, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_336, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_340, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_344, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_348, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_352, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_356, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_360, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_364, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_368, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_372, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_376, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_380, 0x2fff },
+       { WM8996_WRITE_SEQUENCER_384, 0x60 },
+       { WM8996_WRITE_SEQUENCER_386, 0x601 },
+       { WM8996_WRITE_SEQUENCER_388, 0x61 },
+       { WM8996_WRITE_SEQUENCER_390, 0x601 },
+       { WM8996_WRITE_SEQUENCER_392, 0x50 },
+       { WM8996_WRITE_SEQUENCER_394, 0x300 },
+       { WM8996_WRITE_SEQUENCER_396, 0x1 },
+       { WM8996_WRITE_SEQUENCER_398, 0x304 },
+       { WM8996_WRITE_SEQUENCER_400, 0x40 },
+       { WM8996_WRITE_SEQUENCER_402, 0xf },
+       { WM8996_WRITE_SEQUENCER_404, 0x1 },
+       { WM8996_WRITE_SEQUENCER_407, 0x100 },
 };
 
 static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
@@ -1413,8 +1484,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
        { "SPKDAT", NULL, "SPKR PGA" },
 };
 
-static int wm8996_readable_register(struct snd_soc_codec *codec,
-                                   unsigned int reg)
+static bool wm8996_readable_register(struct device *dev, unsigned int reg)
 {
        /* Due to the sparseness of the register map the compiler
         * output from an explicit switch statement ends up being much
@@ -1621,8 +1691,7 @@ static int wm8996_readable_register(struct snd_soc_codec *codec,
        }
 }
 
-static int wm8996_volatile_register(struct snd_soc_codec *codec,
-                                   unsigned int reg)
+static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM8996_SOFTWARE_RESET:
@@ -1646,9 +1715,15 @@ static int wm8996_volatile_register(struct snd_soc_codec *codec,
        }
 }
 
-static int wm8996_reset(struct snd_soc_codec *codec)
+static int wm8996_reset(struct wm8996_priv *wm8996)
 {
-       return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915);
+       if (wm8996->pdata.ldo_ena > 0) {
+               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
+               return 0;
+       } else {
+               return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
+                                   0x8915);
+       }
 }
 
 static const int bclk_divs[] = {
@@ -1723,13 +1798,13 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
                                msleep(5);
                        }
 
-                       codec->cache_only = false;
-                       snd_soc_cache_sync(codec);
+                       regcache_cache_only(codec->control_data, false);
+                       regcache_sync(codec->control_data);
                }
                break;
 
        case SND_SOC_BIAS_OFF:
-               codec->cache_only = true;
+               regcache_cache_only(codec->control_data, true);
                if (wm8996->pdata.ldo_ena >= 0)
                        gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
                regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
@@ -2251,48 +2326,45 @@ static inline struct wm8996_priv *gpio_to_wm8996(struct gpio_chip *chip)
 static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
-       struct snd_soc_codec *codec = wm8996->codec;
 
-       snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
-                           WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);
+       regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
+                          WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);
 }
 
 static int wm8996_gpio_direction_out(struct gpio_chip *chip,
                                     unsigned offset, int value)
 {
        struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
-       struct snd_soc_codec *codec = wm8996->codec;
        int val;
 
        val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT);
 
-       return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
-                                  WM8996_GP1_FN_MASK | WM8996_GP1_DIR |
-                                  WM8996_GP1_LVL, val);
+       return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
+                                 WM8996_GP1_FN_MASK | WM8996_GP1_DIR |
+                                 WM8996_GP1_LVL, val);
 }
 
 static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
        struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
-       struct snd_soc_codec *codec = wm8996->codec;
+       unsigned int reg;
        int ret;
 
-       ret = snd_soc_read(codec, WM8996_GPIO_1 + offset);
+       ret = regmap_read(wm8996->regmap, WM8996_GPIO_1 + offset, &reg);
        if (ret < 0)
                return ret;
 
-       return (ret & WM8996_GP1_LVL) != 0;
+       return (reg & WM8996_GP1_LVL) != 0;
 }
 
 static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
 {
        struct wm8996_priv *wm8996 = gpio_to_wm8996(chip);
-       struct snd_soc_codec *codec = wm8996->codec;
 
-       return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset,
-                                  WM8996_GP1_FN_MASK | WM8996_GP1_DIR,
-                                  (1 << WM8996_GP1_FN_SHIFT) |
-                                  (1 << WM8996_GP1_DIR_SHIFT));
+       return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,
+                                 WM8996_GP1_FN_MASK | WM8996_GP1_DIR,
+                                 (1 << WM8996_GP1_FN_SHIFT) |
+                                 (1 << WM8996_GP1_DIR_SHIFT));
 }
 
 static struct gpio_chip wm8996_template_chip = {
@@ -2305,14 +2377,13 @@ static struct gpio_chip wm8996_template_chip = {
        .can_sleep              = 1,
 };
 
-static void wm8996_init_gpio(struct snd_soc_codec *codec)
+static void wm8996_init_gpio(struct wm8996_priv *wm8996)
 {
-       struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
        wm8996->gpio_chip = wm8996_template_chip;
        wm8996->gpio_chip.ngpio = 5;
-       wm8996->gpio_chip.dev = codec->dev;
+       wm8996->gpio_chip.dev = wm8996->dev;
 
        if (wm8996->pdata.gpio_base)
                wm8996->gpio_chip.base = wm8996->pdata.gpio_base;
@@ -2321,24 +2392,23 @@ static void wm8996_init_gpio(struct snd_soc_codec *codec)
 
        ret = gpiochip_add(&wm8996->gpio_chip);
        if (ret != 0)
-               dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
+               dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret);
 }
 
-static void wm8996_free_gpio(struct snd_soc_codec *codec)
+static void wm8996_free_gpio(struct wm8996_priv *wm8996)
 {
-       struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
        ret = gpiochip_remove(&wm8996->gpio_chip);
        if (ret != 0)
-               dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
+               dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret);
 }
 #else
-static void wm8996_init_gpio(struct snd_soc_codec *codec)
+static void wm8996_init_gpio(struct wm8996_priv *wm8996)
 {
 }
 
-static void wm8996_free_gpio(struct snd_soc_codec *codec)
+static void wm8996_free_gpio(struct wm8996_priv *wm8996)
 {
 }
 #endif
@@ -2692,6 +2762,18 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
                        "Failed to add ReTune Mobile controls: %d\n", ret);
 }
 
+static const struct regmap_config wm8996_regmap = {
+       .reg_bits = 16,
+       .val_bits = 16,
+
+       .max_register = WM8996_MAX_REGISTER,
+       .reg_defaults = wm8996_reg,
+       .num_reg_defaults = ARRAY_SIZE(wm8996_reg),
+       .volatile_reg = wm8996_volatile_register,
+       .readable_reg = wm8996_readable_register,
+       .cache_type = REGCACHE_RBTREE,
+};
+
 static int wm8996_probe(struct snd_soc_codec *codec)
 {
        int ret;
@@ -2707,19 +2789,11 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 
        dapm->idle_bias_off = true;
 
-       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
-               goto err;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
-               wm8996->supplies[i].supply = wm8996_supply_names[i];
+       codec->control_data = wm8996->regmap;
 
-       ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies),
-                                wm8996->supplies);
+       ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
        if (ret != 0) {
-               dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                goto err;
        }
 
@@ -2727,13 +2801,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
        wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
        wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
 
-       wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
-       if (IS_ERR(wm8996->cpvdd)) {
-               ret = PTR_ERR(wm8996->cpvdd);
-               dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
-               goto err_get;
-       }
-
        /* This should really be moved into the regulator core */
        for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
                ret = regulator_register_notifier(wm8996->supplies[i].consumer,
@@ -2745,50 +2812,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
                }
        }
 
-       ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
-                                   wm8996->supplies);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
-               goto err_cpvdd;
-       }
-
-       if (wm8996->pdata.ldo_ena >= 0) {
-               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
-               msleep(5);
-       }
-
-       ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
-               goto err_enable;
-       }
-       if (ret != 0x8915) {
-               dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret);
-               ret = -EINVAL;
-               goto err_enable;
-       }
-
-       ret = snd_soc_read(codec, WM8996_CHIP_REVISION);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to read device revision: %d\n",
-                       ret);
-               goto err_enable;
-       }
-       
-       dev_info(codec->dev, "revision %c\n",
-                (ret & WM8996_CHIP_REV_MASK) + 'A');
-
-       if (wm8996->pdata.ldo_ena >= 0) {
-               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
-       } else {
-               ret = wm8996_reset(codec);
-               if (ret < 0) {
-                       dev_err(codec->dev, "Failed to issue reset\n");
-                       goto err_enable;
-               }
-       }
-
-       codec->cache_only = true;
+       regcache_cache_only(codec->control_data, true);
 
        /* Apply platform data settings */
        snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
@@ -2946,10 +2970,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
                                    WM8996_AIF2TX_LRCLK_MODE,
                                    WM8996_AIF2TX_LRCLK_MODE);
 
-       regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-
-       wm8996_init_gpio(codec);
-
        if (i2c->irq) {
                if (wm8996->pdata.irq_flags)
                        irq_flags = wm8996->pdata.irq_flags;
@@ -2987,15 +3007,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 
        return 0;
 
-err_enable:
-       if (wm8996->pdata.ldo_ena >= 0)
-               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
-
-       regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-err_cpvdd:
-       regulator_put(wm8996->cpvdd);
-err_get:
-       regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
 err:
        return ret;
 }
@@ -3012,8 +3023,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
        if (i2c->irq)
                free_irq(i2c->irq, codec);
 
-       wm8996_free_gpio(codec);
-
        for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
                regulator_unregister_notifier(wm8996->supplies[i].consumer,
                                              &wm8996->disable_nb[i]);
@@ -3028,12 +3037,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
        .remove =       wm8996_remove,
        .set_bias_level = wm8996_set_bias_level,
        .seq_notifier = wm8996_seq_notifier,
-       .reg_cache_size = WM8996_MAX_REGISTER + 1,
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm8996_reg,
-       .volatile_register = wm8996_volatile_register,
-       .readable_register = wm8996_readable_register,
-       .compress_type = SND_SOC_RBTREE_COMPRESSION,
        .controls = wm8996_snd_controls,
        .num_controls = ARRAY_SIZE(wm8996_snd_controls),
        .dapm_widgets = wm8996_dapm_widgets,
@@ -3049,7 +3052,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
                        SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
                        SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm8996_dai_ops = {
+static const struct snd_soc_dai_ops wm8996_dai_ops = {
        .set_fmt = wm8996_set_fmt,
        .hw_params = wm8996_hw_params,
        .set_sysclk = wm8996_set_sysclk,
@@ -3098,13 +3101,16 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
 {
        struct wm8996_priv *wm8996;
-       int ret;
+       int ret, i;
+       unsigned int reg;
 
-       wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL);
+       wm8996 = devm_kzalloc(&i2c->dev, sizeof(struct wm8996_priv),
+                             GFP_KERNEL);
        if (wm8996 == NULL)
                return -ENOMEM;
 
        i2c_set_clientdata(i2c, wm8996);
+       wm8996->dev = &i2c->dev;
 
        if (dev_get_platdata(&i2c->dev))
                memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev),
@@ -3120,19 +3126,97 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
                }
        }
 
+       for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
+               wm8996->supplies[i].supply = wm8996_supply_names[i];
+
+       ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
+                                wm8996->supplies);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+               goto err_gpio;
+       }
+
+       wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
+       if (IS_ERR(wm8996->cpvdd)) {
+               ret = PTR_ERR(wm8996->cpvdd);
+               dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
+               goto err_get;
+       }
+
+       ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
+                                   wm8996->supplies);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+               goto err_cpvdd;
+       }
+
+       if (wm8996->pdata.ldo_ena > 0) {
+               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
+               msleep(5);
+       }
+
+       wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap);
+       if (IS_ERR(wm8996->regmap)) {
+               ret = PTR_ERR(wm8996->regmap);
+               dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+               goto err_enable;
+       }
+
+       ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, &reg);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
+               goto err_regmap;
+       }
+       if (reg != 0x8915) {
+               dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret);
+               ret = -EINVAL;
+               goto err_regmap;
+       }
+
+       ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, &reg);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to read device revision: %d\n",
+                       ret);
+               goto err_regmap;
+       }
+
+       dev_info(&i2c->dev, "revision %c\n",
+                (reg & WM8996_CHIP_REV_MASK) + 'A');
+
+       regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+
+       ret = wm8996_reset(wm8996);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to issue reset\n");
+               goto err_regmap;
+       }
+
+       wm8996_init_gpio(wm8996);
+
        ret = snd_soc_register_codec(&i2c->dev,
                                     &soc_codec_dev_wm8996, wm8996_dai,
                                     ARRAY_SIZE(wm8996_dai));
        if (ret < 0)
-               goto err_gpio;
+               goto err_gpiolib;
 
        return ret;
 
+err_gpiolib:
+       wm8996_free_gpio(wm8996);
+err_regmap:
+       regmap_exit(wm8996->regmap);
+err_enable:
+       if (wm8996->pdata.ldo_ena > 0)
+               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
+       regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+err_cpvdd:
+       regulator_put(wm8996->cpvdd);
+err_get:
+       regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
 err_gpio:
        if (wm8996->pdata.ldo_ena > 0)
                gpio_free(wm8996->pdata.ldo_ena);
 err:
-       kfree(wm8996);
 
        return ret;
 }
@@ -3142,9 +3226,14 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
        struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
 
        snd_soc_unregister_codec(&client->dev);
-       if (wm8996->pdata.ldo_ena > 0)
+       wm8996_free_gpio(wm8996);
+       regulator_put(wm8996->cpvdd);
+       regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
+       regmap_exit(wm8996->regmap);
+       if (wm8996->pdata.ldo_ena > 0) {
+               gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
                gpio_free(wm8996->pdata.ldo_ena);
-       kfree(i2c_get_clientdata(client));
+       }
        return 0;
 }
 
index 4a398c3bfe84aea9ef4f6c8540f09b8b2bf34282..8a4b970604444e5140d5017447ee81bdd6036294 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/device.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/wm9081.h>
 #include "wm9081.h"
 
-static u16 wm9081_reg_defaults[] = {
-       0x0000,     /* R0  - Software Reset */
-       0x0000,     /* R1 */
-       0x00B9,     /* R2  - Analogue Lineout */
-       0x00B9,     /* R3  - Analogue Speaker PGA */
-       0x0001,     /* R4  - VMID Control */
-       0x0068,     /* R5  - Bias Control 1 */
-       0x0000,     /* R6 */
-       0x0000,     /* R7  - Analogue Mixer */
-       0x0000,     /* R8  - Anti Pop Control */
-       0x01DB,     /* R9  - Analogue Speaker 1 */
-       0x0018,     /* R10 - Analogue Speaker 2 */
-       0x0180,     /* R11 - Power Management */
-       0x0000,     /* R12 - Clock Control 1 */
-       0x0038,     /* R13 - Clock Control 2 */
-       0x4000,     /* R14 - Clock Control 3 */
-       0x0000,     /* R15 */
-       0x0000,     /* R16 - FLL Control 1 */
-       0x0200,     /* R17 - FLL Control 2 */
-       0x0000,     /* R18 - FLL Control 3 */
-       0x0204,     /* R19 - FLL Control 4 */
-       0x0000,     /* R20 - FLL Control 5 */
-       0x0000,     /* R21 */
-       0x0000,     /* R22 - Audio Interface 1 */
-       0x0002,     /* R23 - Audio Interface 2 */
-       0x0008,     /* R24 - Audio Interface 3 */
-       0x0022,     /* R25 - Audio Interface 4 */
-       0x0000,     /* R26 - Interrupt Status */
-       0x0006,     /* R27 - Interrupt Status Mask */
-       0x0000,     /* R28 - Interrupt Polarity */
-       0x0000,     /* R29 - Interrupt Control */
-       0x00C0,     /* R30 - DAC Digital 1 */
-       0x0008,     /* R31 - DAC Digital 2 */
-       0x09AF,     /* R32 - DRC 1 */
-       0x4201,     /* R33 - DRC 2 */
-       0x0000,     /* R34 - DRC 3 */
-       0x0000,     /* R35 - DRC 4 */
-       0x0000,     /* R36 */
-       0x0000,     /* R37 */
-       0x0000,     /* R38 - Write Sequencer 1 */
-       0x0000,     /* R39 - Write Sequencer 2 */
-       0x0002,     /* R40 - MW Slave 1 */
-       0x0000,     /* R41 */
-       0x0000,     /* R42 - EQ 1 */
-       0x0000,     /* R43 - EQ 2 */
-       0x0FCA,     /* R44 - EQ 3 */
-       0x0400,     /* R45 - EQ 4 */
-       0x00B8,     /* R46 - EQ 5 */
-       0x1EB5,     /* R47 - EQ 6 */
-       0xF145,     /* R48 - EQ 7 */
-       0x0B75,     /* R49 - EQ 8 */
-       0x01C5,     /* R50 - EQ 9 */
-       0x169E,     /* R51 - EQ 10 */
-       0xF829,     /* R52 - EQ 11 */
-       0x07AD,     /* R53 - EQ 12 */
-       0x1103,     /* R54 - EQ 13 */
-       0x1C58,     /* R55 - EQ 14 */
-       0xF373,     /* R56 - EQ 15 */
-       0x0A54,     /* R57 - EQ 16 */
-       0x0558,     /* R58 - EQ 17 */
-       0x0564,     /* R59 - EQ 18 */
-       0x0559,     /* R60 - EQ 19 */
-       0x4000,     /* R61 - EQ 20 */
+static struct reg_default wm9081_reg[] = {
+       {  0, 0x9081 },     /* R0  - Software Reset */
+       {  2, 0x00B9 },     /* R2  - Analogue Lineout */
+       {  3, 0x00B9 },     /* R3  - Analogue Speaker PGA */
+       {  4, 0x0001 },     /* R4  - VMID Control */
+       {  5, 0x0068 },     /* R5  - Bias Control 1 */
+       {  7, 0x0000 },     /* R7  - Analogue Mixer */
+       {  8, 0x0000 },     /* R8  - Anti Pop Control */
+       {  9, 0x01DB },     /* R9  - Analogue Speaker 1 */
+       { 10, 0x0018 },     /* R10 - Analogue Speaker 2 */
+       { 11, 0x0180 },     /* R11 - Power Management */
+       { 12, 0x0000 },     /* R12 - Clock Control 1 */
+       { 13, 0x0038 },     /* R13 - Clock Control 2 */
+       { 14, 0x4000 },     /* R14 - Clock Control 3 */
+       { 16, 0x0000 },     /* R16 - FLL Control 1 */
+       { 17, 0x0200 },     /* R17 - FLL Control 2 */
+       { 18, 0x0000 },     /* R18 - FLL Control 3 */
+       { 19, 0x0204 },     /* R19 - FLL Control 4 */
+       { 20, 0x0000 },     /* R20 - FLL Control 5 */
+       { 22, 0x0000 },     /* R22 - Audio Interface 1 */
+       { 23, 0x0002 },     /* R23 - Audio Interface 2 */
+       { 24, 0x0008 },     /* R24 - Audio Interface 3 */
+       { 25, 0x0022 },     /* R25 - Audio Interface 4 */
+       { 27, 0x0006 },     /* R27 - Interrupt Status Mask */
+       { 28, 0x0000 },     /* R28 - Interrupt Polarity */
+       { 29, 0x0000 },     /* R29 - Interrupt Control */
+       { 30, 0x00C0 },     /* R30 - DAC Digital 1 */
+       { 31, 0x0008 },     /* R31 - DAC Digital 2 */
+       { 32, 0x09AF },     /* R32 - DRC 1 */
+       { 33, 0x4201 },     /* R33 - DRC 2 */
+       { 34, 0x0000 },     /* R34 - DRC 3 */
+       { 35, 0x0000 },     /* R35 - DRC 4 */
+       { 38, 0x0000 },     /* R38 - Write Sequencer 1 */
+       { 39, 0x0000 },     /* R39 - Write Sequencer 2 */
+       { 40, 0x0002 },     /* R40 - MW Slave 1 */
+       { 42, 0x0000 },     /* R42 - EQ 1 */
+       { 43, 0x0000 },     /* R43 - EQ 2 */
+       { 44, 0x0FCA },     /* R44 - EQ 3 */
+       { 45, 0x0400 },     /* R45 - EQ 4 */
+       { 46, 0x00B8 },     /* R46 - EQ 5 */
+       { 47, 0x1EB5 },     /* R47 - EQ 6 */
+       { 48, 0xF145 },     /* R48 - EQ 7 */
+       { 49, 0x0B75 },     /* R49 - EQ 8 */
+       { 50, 0x01C5 },     /* R50 - EQ 9 */
+       { 51, 0x169E },     /* R51 - EQ 10 */
+       { 52, 0xF829 },     /* R52 - EQ 11 */
+       { 53, 0x07AD },     /* R53 - EQ 12 */
+       { 54, 0x1103 },     /* R54 - EQ 13 */
+       { 55, 0x1C58 },     /* R55 - EQ 14 */
+       { 56, 0xF373 },     /* R56 - EQ 15 */
+       { 57, 0x0A54 },     /* R57 - EQ 16 */
+       { 58, 0x0558 },     /* R58 - EQ 17 */
+       { 59, 0x0564 },     /* R59 - EQ 18 */
+       { 60, 0x0559 },     /* R60 - EQ 19 */
+       { 61, 0x4000 },     /* R61 - EQ 20 */
 };
 
 static struct {
@@ -156,7 +148,7 @@ static struct {
 };
 
 struct wm9081_priv {
-       enum snd_soc_control_type control_type;
+       struct regmap *regmap;
        int sysclk_source;
        int mclk_rate;
        int sysclk_rate;
@@ -169,20 +161,84 @@ struct wm9081_priv {
        struct wm9081_pdata pdata;
 };
 
-static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm9081_volatile_register(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case WM9081_SOFTWARE_RESET:
        case WM9081_INTERRUPT_STATUS:
-               return 1;
+               return true;
        default:
-               return 0;
+               return false;
+       }
+}
+
+static bool wm9081_readable_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case WM9081_SOFTWARE_RESET:
+       case WM9081_ANALOGUE_LINEOUT:
+       case WM9081_ANALOGUE_SPEAKER_PGA:
+       case WM9081_VMID_CONTROL:
+       case WM9081_BIAS_CONTROL_1:
+       case WM9081_ANALOGUE_MIXER:
+       case WM9081_ANTI_POP_CONTROL:
+       case WM9081_ANALOGUE_SPEAKER_1:
+       case WM9081_ANALOGUE_SPEAKER_2:
+       case WM9081_POWER_MANAGEMENT:
+       case WM9081_CLOCK_CONTROL_1:
+       case WM9081_CLOCK_CONTROL_2:
+       case WM9081_CLOCK_CONTROL_3:
+       case WM9081_FLL_CONTROL_1:
+       case WM9081_FLL_CONTROL_2:
+       case WM9081_FLL_CONTROL_3:
+       case WM9081_FLL_CONTROL_4:
+       case WM9081_FLL_CONTROL_5:
+       case WM9081_AUDIO_INTERFACE_1:
+       case WM9081_AUDIO_INTERFACE_2:
+       case WM9081_AUDIO_INTERFACE_3:
+       case WM9081_AUDIO_INTERFACE_4:
+       case WM9081_INTERRUPT_STATUS:
+       case WM9081_INTERRUPT_STATUS_MASK:
+       case WM9081_INTERRUPT_POLARITY:
+       case WM9081_INTERRUPT_CONTROL:
+       case WM9081_DAC_DIGITAL_1:
+       case WM9081_DAC_DIGITAL_2:
+       case WM9081_DRC_1:
+       case WM9081_DRC_2:
+       case WM9081_DRC_3:
+       case WM9081_DRC_4:
+       case WM9081_WRITE_SEQUENCER_1:
+       case WM9081_WRITE_SEQUENCER_2:
+       case WM9081_MW_SLAVE_1:
+       case WM9081_EQ_1:
+       case WM9081_EQ_2:
+       case WM9081_EQ_3:
+       case WM9081_EQ_4:
+       case WM9081_EQ_5:
+       case WM9081_EQ_6:
+       case WM9081_EQ_7:
+       case WM9081_EQ_8:
+       case WM9081_EQ_9:
+       case WM9081_EQ_10:
+       case WM9081_EQ_11:
+       case WM9081_EQ_12:
+       case WM9081_EQ_13:
+       case WM9081_EQ_14:
+       case WM9081_EQ_15:
+       case WM9081_EQ_16:
+       case WM9081_EQ_17:
+       case WM9081_EQ_18:
+       case WM9081_EQ_19:
+       case WM9081_EQ_20:
+               return true;
+       default:
+               return false;
        }
 }
 
-static int wm9081_reset(struct snd_soc_codec *codec)
+static int wm9081_reset(struct regmap *map)
 {
-       return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0);
+       return regmap_write(map, WM9081_SOFTWARE_RESET, 0x9081);
 }
 
 static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0);
@@ -737,6 +793,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM9081_CLOCK_CONTROL_3, 0, 0, clk_sys_event,
                    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("TSENSE", WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0),
 };
 
 
@@ -759,6 +816,7 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
        { "Speaker PGA", NULL, "CLK_SYS" },
 
        { "Speaker", NULL, "Speaker PGA" },
+       { "Speaker", NULL, "TSENSE" },
 
        { "SPKN", NULL, "Speaker" },
        { "SPKP", NULL, "Speaker" },
@@ -767,84 +825,74 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
 static int wm9081_set_bias_level(struct snd_soc_codec *codec,
                                 enum snd_soc_bias_level level)
 {
-       u16 reg;
-
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
 
        case SND_SOC_BIAS_PREPARE:
                /* VMID=2*40k */
-               reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
-               reg &= ~WM9081_VMID_SEL_MASK;
-               reg |= 0x2;
-               snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+               snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+                                   WM9081_VMID_SEL_MASK, 0x2);
 
                /* Normal bias current */
-               reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
-               reg &= ~WM9081_STBY_BIAS_ENA;
-               snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+               snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+                                   WM9081_STBY_BIAS_ENA, 0);
                break;
 
        case SND_SOC_BIAS_STANDBY:
                /* Initial cold start */
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
                        /* Disable LINEOUT discharge */
-                       reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
-                       reg &= ~WM9081_LINEOUT_DISCH;
-                       snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
+                       snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
+                                           WM9081_LINEOUT_DISCH, 0);
 
                        /* Select startup bias source */
-                       reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
-                       reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA;
-                       snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+                       snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+                                           WM9081_BIAS_SRC | WM9081_BIAS_ENA,
+                                           WM9081_BIAS_SRC | WM9081_BIAS_ENA);
 
                        /* VMID 2*4k; Soft VMID ramp enable */
-                       reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
-                       reg |= WM9081_VMID_RAMP | 0x6;
-                       snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+                       snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+                                           WM9081_VMID_RAMP |
+                                           WM9081_VMID_SEL_MASK,
+                                           WM9081_VMID_RAMP | 0x6);
 
                        mdelay(100);
 
                        /* Normal bias enable & soft start off */
-                       reg &= ~WM9081_VMID_RAMP;
-                       snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+                       snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+                                           WM9081_VMID_RAMP, 0);
 
                        /* Standard bias source */
-                       reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
-                       reg &= ~WM9081_BIAS_SRC;
-                       snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+                       snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+                                           WM9081_BIAS_SRC, 0);
                }
 
                /* VMID 2*240k */
-               reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
-               reg &= ~WM9081_VMID_SEL_MASK;
-               reg |= 0x04;
-               snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+               snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+                                   WM9081_VMID_SEL_MASK, 0x04);
 
                /* Standby bias current on */
-               reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
-               reg |= WM9081_STBY_BIAS_ENA;
-               snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+               snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+                                   WM9081_STBY_BIAS_ENA,
+                                   WM9081_STBY_BIAS_ENA);
                break;
 
        case SND_SOC_BIAS_OFF:
                /* Startup bias source and disable bias */
-               reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
-               reg |= WM9081_BIAS_SRC;
-               reg &= ~WM9081_BIAS_ENA;
-               snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
+               snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1,
+                                   WM9081_BIAS_SRC | WM9081_BIAS_ENA,
+                                   WM9081_BIAS_SRC);
 
                /* Disable VMID with soft ramping */
-               reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
-               reg &= ~WM9081_VMID_SEL_MASK;
-               reg |= WM9081_VMID_RAMP;
-               snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
+               snd_soc_update_bits(codec, WM9081_VMID_CONTROL,
+                                   WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK,
+                                   WM9081_VMID_RAMP);
 
                /* Actively discharge LINEOUT */
-               reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
-               reg |= WM9081_LINEOUT_DISCH;
-               snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
+               snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
+                                   WM9081_LINEOUT_DISCH,
+                                   WM9081_LINEOUT_DISCH);
                break;
        }
 
@@ -1185,7 +1233,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops wm9081_dai_ops = {
+static const struct snd_soc_dai_ops wm9081_dai_ops = {
        .hw_params = wm9081_hw_params,
        .set_fmt = wm9081_set_dai_fmt,
        .digital_mute = wm9081_digital_mute,
@@ -1213,25 +1261,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
        int ret;
        u16 reg;
 
-       ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
+       codec->control_data = wm9081->regmap;
+
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
        }
 
-       reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
-       if (reg != 0x9081) {
-               dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
-               ret = -EINVAL;
-               return ret;
-       }
-
-       ret = wm9081_reset(codec);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to issue reset\n");
-               return ret;
-       }
-
        reg = 0;
        if (wm9081->pdata.irq_high)
                reg |= WM9081_IRQ_POL;
@@ -1243,11 +1280,10 @@ static int wm9081_probe(struct snd_soc_codec *codec)
        wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        /* Enable zero cross by default */
-       reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
-       snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
-       reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
-       snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
-                    reg | WM9081_SPKPGAZC);
+       snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
+                           WM9081_LINEOUTZC, WM9081_LINEOUTZC);
+       snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA,
+                           WM9081_SPKPGAZC, WM9081_SPKPGAZC);
 
        if (!wm9081->pdata.num_retune_configs) {
                dev_dbg(codec->dev,
@@ -1275,15 +1311,9 @@ static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 static int wm9081_resume(struct snd_soc_codec *codec)
 {
-       u16 *reg_cache = codec->reg_cache;
-       int i;
-
-       for (i = 0; i < codec->driver->reg_cache_size; i++) {
-               if (i == WM9081_SOFTWARE_RESET)
-                       continue;
+       struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
 
-               snd_soc_write(codec, i, reg_cache[i]);
-       }
+       regcache_sync(wm9081->regmap);
 
        wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
@@ -1303,11 +1333,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
        .set_sysclk = wm9081_set_sysclk,
        .set_bias_level = wm9081_set_bias_level,
 
-       .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
-       .reg_word_size = sizeof(u16),
-       .reg_cache_default = wm9081_reg_defaults,
-       .volatile_register = wm9081_volatile_register,
-
        .controls         = wm9081_snd_controls,
        .num_controls     = ARRAY_SIZE(wm9081_snd_controls),
        .dapm_widgets     = wm9081_dapm_widgets,
@@ -1316,19 +1341,56 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
        .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
 };
 
+static const struct regmap_config wm9081_regmap = {
+       .reg_bits = 8,
+       .val_bits = 16,
+
+       .max_register = WM9081_MAX_REGISTER,
+       .reg_defaults = wm9081_reg,
+       .num_reg_defaults = ARRAY_SIZE(wm9081_reg),
+       .volatile_reg = wm9081_volatile_register,
+       .readable_reg = wm9081_readable_register,
+       .cache_type = REGCACHE_RBTREE,
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
                                      const struct i2c_device_id *id)
 {
        struct wm9081_priv *wm9081;
+       unsigned int reg;
        int ret;
 
-       wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL);
+       wm9081 = devm_kzalloc(&i2c->dev, sizeof(struct wm9081_priv),
+                             GFP_KERNEL);
        if (wm9081 == NULL)
                return -ENOMEM;
 
        i2c_set_clientdata(i2c, wm9081);
-       wm9081->control_type = SND_SOC_I2C;
+
+       wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap);
+       if (IS_ERR(wm9081->regmap)) {
+               ret = PTR_ERR(wm9081->regmap);
+               dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+               goto err;
+       }
+
+       ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, &reg);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
+               goto err_regmap;
+       }
+       if (reg != 0x9081) {
+               dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg);
+               ret = -EINVAL;
+               goto err_regmap;
+       }
+
+       ret = wm9081_reset(wm9081->regmap);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to issue reset\n");
+               goto err_regmap;
+       }
 
        if (dev_get_platdata(&i2c->dev))
                memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
@@ -1337,14 +1399,23 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
        ret = snd_soc_register_codec(&i2c->dev,
                        &soc_codec_dev_wm9081, &wm9081_dai, 1);
        if (ret < 0)
-               kfree(wm9081);
+               goto err_regmap;
+
+       return 0;
+
+err_regmap:
+       regmap_exit(wm9081->regmap);
+err:
+
        return ret;
 }
 
 static __devexit int wm9081_i2c_remove(struct i2c_client *client)
 {
+       struct wm9081_priv *wm9081 = i2c_get_clientdata(client);
+
        snd_soc_unregister_codec(&client->dev);
-       kfree(i2c_get_clientdata(client));
+       regmap_exit(wm9081->regmap);
        return 0;
 }
 
index 646b58dda849192777adc69d66ab54bb14891928..b720a43c422c1935017baa8e5a198a01522af059 100644 (file)
@@ -258,7 +258,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
                        SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
                        SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_dai_ops wm9705_dai_ops = {
+static const struct snd_soc_dai_ops wm9705_dai_ops = {
        .prepare        = ac97_prepare,
 };
 
@@ -406,17 +406,7 @@ static struct platform_driver wm9705_codec_driver = {
        .remove = __devexit_p(wm9705_remove),
 };
 
-static int __init wm9705_init(void)
-{
-       return platform_driver_register(&wm9705_codec_driver);
-}
-module_init(wm9705_init);
-
-static void __exit wm9705_exit(void)
-{
-       platform_driver_unregister(&wm9705_codec_driver);
-}
-module_exit(wm9705_exit);
+module_platform_driver(wm9705_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM9705 driver");
 MODULE_AUTHOR("Ian Molton");
index 90117f8156e83c8da98b1f53fdb23573be4f9a03..4ce73f59df2071336862e07a9b467fdc40d1fa1f 100644 (file)
@@ -505,11 +505,11 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
                SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
                SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
+static const struct snd_soc_dai_ops wm9712_dai_ops_hifi = {
        .prepare        = ac97_prepare,
 };
 
-static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
+static const struct snd_soc_dai_ops wm9712_dai_ops_aux = {
        .prepare        = ac97_aux_prepare,
 };
 
@@ -694,17 +694,7 @@ static struct platform_driver wm9712_codec_driver = {
        .remove = __devexit_p(wm9712_remove),
 };
 
-static int __init wm9712_init(void)
-{
-       return platform_driver_register(&wm9712_codec_driver);
-}
-module_init(wm9712_init);
-
-static void __exit wm9712_exit(void)
-{
-       platform_driver_unregister(&wm9712_codec_driver);
-}
-module_exit(wm9712_exit);
+module_platform_driver(wm9712_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
 MODULE_AUTHOR("Liam Girdwood");
index 7167cb6787dba44efdc25a4550d12d24bbb026c6..edb598182c696d1a930970b34b9ad81b71616713 100644 (file)
@@ -1026,19 +1026,19 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
        (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
         SNDRV_PCM_FORMAT_S24_LE)
 
-static struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
+static const struct snd_soc_dai_ops wm9713_dai_ops_hifi = {
        .prepare        = ac97_hifi_prepare,
        .set_clkdiv     = wm9713_set_dai_clkdiv,
        .set_pll        = wm9713_set_dai_pll,
 };
 
-static struct snd_soc_dai_ops wm9713_dai_ops_aux = {
+static const struct snd_soc_dai_ops wm9713_dai_ops_aux = {
        .prepare        = ac97_aux_prepare,
        .set_clkdiv     = wm9713_set_dai_clkdiv,
        .set_pll        = wm9713_set_dai_pll,
 };
 
-static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
+static const struct snd_soc_dai_ops wm9713_dai_ops_voice = {
        .hw_params      = wm9713_pcm_hw_params,
        .set_clkdiv     = wm9713_set_dai_clkdiv,
        .set_pll        = wm9713_set_dai_pll,
@@ -1277,17 +1277,7 @@ static struct platform_driver wm9713_codec_driver = {
        .remove = __devexit_p(wm9713_remove),
 };
 
-static int __init wm9713_init(void)
-{
-       return platform_driver_register(&wm9713_codec_driver);
-}
-module_init(wm9713_init);
-
-static void __exit wm9713_exit(void)
-{
-       platform_driver_unregister(&wm9713_codec_driver);
-}
-module_exit(wm9713_exit);
+module_platform_driver(wm9713_codec_driver);
 
 MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
 MODULE_AUTHOR("Liam Girdwood");
index 48e61e912400fb2d2cca4ad74d9faf17a3075444..d1debfb20c60d56b11ffec320900e830216f109e 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
-#include <linux/platform_device.h>
 #include <linux/mfd/wm8994/registers.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -654,6 +653,7 @@ SND_SOC_DAPM_MIXER("SPKL Boost", SND_SOC_NOPM, 0, 0,
 SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
                   right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
 
+SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
 SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
                 NULL, 0),
 SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
@@ -789,10 +789,12 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
        { "SPKL Driver", NULL, "VMID" },
        { "SPKL Driver", NULL, "SPKL Boost" },
        { "SPKL Driver", NULL, "CLK_SYS" },
+       { "SPKL Driver", NULL, "TSHUT" },
 
        { "SPKR Driver", NULL, "VMID" },
        { "SPKR Driver", NULL, "SPKR Boost" },
        { "SPKR Driver", NULL, "CLK_SYS" },
+       { "SPKR Driver", NULL, "TSHUT" },
 
        { "SPKOUTLP", NULL, "SPKL Driver" },
        { "SPKOUTLN", NULL, "SPKL Driver" },
index 300e12118c0093722f1e2b5f527b8627cdbab116..ec187100367edd98585c27ecd9dfef908410ad20 100644 (file)
@@ -620,7 +620,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
 
 #define DAVINCI_I2S_RATES      SNDRV_PCM_RATE_8000_96000
 
-static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
+static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
        .startup        = davinci_i2s_startup,
        .shutdown       = davinci_i2s_shutdown,
        .prepare        = davinci_i2s_prepare,
@@ -774,17 +774,7 @@ static struct platform_driver davinci_mcbsp_driver = {
        },
 };
 
-static int __init davinci_i2s_init(void)
-{
-       return platform_driver_register(&davinci_mcbsp_driver);
-}
-module_init(davinci_i2s_init);
-
-static void __exit davinci_i2s_exit(void)
-{
-       platform_driver_unregister(&davinci_mcbsp_driver);
-}
-module_exit(davinci_i2s_exit);
+module_platform_driver(davinci_mcbsp_driver);
 
 MODULE_AUTHOR("Vladimir Barinov");
 MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
index 7173df254a9150b0f69d527f7cd2f6ab02cfc7e3..2152ff5c04f66df8aacfcd4a2fa0e429f64af5a2 100644 (file)
@@ -813,7 +813,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
        .startup        = davinci_mcasp_startup,
        .trigger        = davinci_mcasp_trigger,
        .hw_params      = davinci_mcasp_hw_params,
@@ -991,17 +991,7 @@ static struct platform_driver davinci_mcasp_driver = {
        },
 };
 
-static int __init davinci_mcasp_init(void)
-{
-       return platform_driver_register(&davinci_mcasp_driver);
-}
-module_init(davinci_mcasp_init);
-
-static void __exit davinci_mcasp_exit(void)
-{
-       platform_driver_unregister(&davinci_mcasp_driver);
-}
-module_exit(davinci_mcasp_exit);
+module_platform_driver(davinci_mcasp_driver);
 
 MODULE_AUTHOR("Steve Chen");
 MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
index d5fe08cc5db7ec83efbfcb2b8b13d6094c2bf986..65bff3d30dd757909ca2e0a59bb6ec214b676d79 100644 (file)
@@ -886,17 +886,7 @@ static struct platform_driver davinci_pcm_driver = {
        .remove = __devexit_p(davinci_soc_platform_remove),
 };
 
-static int __init snd_davinci_pcm_init(void)
-{
-       return platform_driver_register(&davinci_pcm_driver);
-}
-module_init(snd_davinci_pcm_init);
-
-static void __exit snd_davinci_pcm_exit(void)
-{
-       platform_driver_unregister(&davinci_pcm_driver);
-}
-module_exit(snd_davinci_pcm_exit);
+module_platform_driver(davinci_pcm_driver);
 
 MODULE_AUTHOR("Vladimir Barinov");
 MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
index 1f11525d97e805ade146e26fe45cf9eb48ed432c..70ce10c5d9982310a4ac1c6a5c82042ad6442bcd 100644 (file)
@@ -183,7 +183,7 @@ static int davinci_vcif_startup(struct snd_pcm_substream *substream,
 
 #define DAVINCI_VCIF_RATES     SNDRV_PCM_RATE_8000_48000
 
-static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
+static const struct snd_soc_dai_ops davinci_vcif_dai_ops = {
        .startup        = davinci_vcif_startup,
        .trigger        = davinci_vcif_trigger,
        .hw_params      = davinci_vcif_hw_params,
@@ -265,17 +265,7 @@ static struct platform_driver davinci_vcif_driver = {
        },
 };
 
-static int __init davinci_vcif_init(void)
-{
-       return platform_driver_probe(&davinci_vcif_driver, davinci_vcif_probe);
-}
-module_init(davinci_vcif_init);
-
-static void __exit davinci_vcif_exit(void)
-{
-       platform_driver_unregister(&davinci_vcif_driver);
-}
-module_exit(davinci_vcif_exit);
+module_platform_driver(davinci_vcif_driver);
 
 MODULE_AUTHOR("Miguel Aguilar");
 MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface");
index 51930b6a83af193f3f802df490df3f00b7930cd1..6b90c757cf4c1c60210ed6101bf0abc06bde6b95 100644 (file)
@@ -131,17 +131,7 @@ static struct platform_driver edb93xx_driver = {
        .remove         = __devexit_p(edb93xx_remove),
 };
 
-static int __init edb93xx_init(void)
-{
-       return platform_driver_register(&edb93xx_driver);
-}
-module_init(edb93xx_init);
-
-static void __exit edb93xx_exit(void)
-{
-       platform_driver_unregister(&edb93xx_driver);
-}
-module_exit(edb93xx_exit);
+module_platform_driver(edb93xx_driver);
 
 MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
 MODULE_DESCRIPTION("ALSA SoC EDB93xx");
index 3cd6158d83e13f486e8c564cbef8ac809b2d7af8..0678637abd66c6110524fa7bd3ee17d8e4abf8d9 100644 (file)
@@ -330,7 +330,7 @@ static int ep93xx_ac97_startup(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
+static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = {
        .startup        = ep93xx_ac97_startup,
        .trigger        = ep93xx_ac97_trigger,
 };
@@ -449,17 +449,7 @@ static struct platform_driver ep93xx_ac97_driver = {
        },
 };
 
-static int __init ep93xx_ac97_init(void)
-{
-       return platform_driver_register(&ep93xx_ac97_driver);
-}
-module_init(ep93xx_ac97_init);
-
-static void __exit ep93xx_ac97_exit(void)
-{
-       platform_driver_unregister(&ep93xx_ac97_driver);
-}
-module_exit(ep93xx_ac97_exit);
+module_platform_driver(ep93xx_ac97_driver);
 
 MODULE_DESCRIPTION("EP93xx AC97 ASoC Driver");
 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
index 099614e16651bb78c78e0c805aa56c72c97fe9e9..f7a62348e3fe022a3bc7ba4faa06b9e19f5c23a0 100644 (file)
@@ -338,7 +338,7 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
 #define ep93xx_i2s_resume      NULL
 #endif
 
-static struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
        .startup        = ep93xx_i2s_startup,
        .shutdown       = ep93xx_i2s_shutdown,
        .hw_params      = ep93xx_i2s_hw_params,
@@ -464,18 +464,7 @@ static struct platform_driver ep93xx_i2s_driver = {
        },
 };
 
-static int __init ep93xx_i2s_init(void)
-{
-       return platform_driver_register(&ep93xx_i2s_driver);
-}
-
-static void __exit ep93xx_i2s_exit(void)
-{
-       platform_driver_unregister(&ep93xx_i2s_driver);
-}
-
-module_init(ep93xx_i2s_init);
-module_exit(ep93xx_i2s_exit);
+module_platform_driver(ep93xx_i2s_driver);
 
 MODULE_ALIAS("platform:ep93xx-i2s");
 MODULE_AUTHOR("Ryan Mallon");
index d00230a591b19efc8f4df849b7dbe07cb6cb665c..a2de9c42b702d4a841ba3dd0f8831b5d984273be 100644 (file)
@@ -339,18 +339,7 @@ static struct platform_driver ep93xx_pcm_driver = {
        .remove = __devexit_p(ep93xx_soc_platform_remove),
 };
 
-static int __init ep93xx_soc_platform_init(void)
-{
-       return platform_driver_register(&ep93xx_pcm_driver);
-}
-
-static void __exit ep93xx_soc_platform_exit(void)
-{
-       platform_driver_unregister(&ep93xx_pcm_driver);
-}
-
-module_init(ep93xx_soc_platform_init);
-module_exit(ep93xx_soc_platform_exit);
+module_platform_driver(ep93xx_pcm_driver);
 
 MODULE_AUTHOR("Ryan Mallon");
 MODULE_DESCRIPTION("EP93xx ALSA PCM interface");
index 968cb316d5115cf0d99bebf6d1fb1a47aef3a4e8..1e00b33cc50884be16e404e8f37a55c1e0b1b7d3 100644 (file)
@@ -81,17 +81,7 @@ static struct platform_driver simone_driver = {
        .remove         = __devexit_p(simone_remove),
 };
 
-static int __init simone_init(void)
-{
-       return platform_driver_register(&simone_driver);
-}
-module_init(simone_init);
-
-static void __exit simone_exit(void)
-{
-       platform_driver_unregister(&simone_driver);
-}
-module_exit(simone_exit);
+module_platform_driver(simone_driver);
 
 MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One");
 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
index 2cde43321eecc44545a9a1415c9b96d1780f3766..33901d647b728ab761ba41befb91d9225935b4ce 100644 (file)
@@ -147,18 +147,7 @@ static struct platform_driver snappercl15_driver = {
        .remove         = __devexit_p(snappercl15_remove),
 };
 
-static int __init snappercl15_init(void)
-{
-       return platform_driver_register(&snappercl15_driver);
-}
-
-static void __exit snappercl15_exit(void)
-{
-       platform_driver_unregister(&snappercl15_driver);
-}
-
-module_init(snappercl15_init);
-module_exit(snappercl15_exit);
+module_platform_driver(snappercl15_driver);
 
 MODULE_AUTHOR("Ryan Mallon");
 MODULE_DESCRIPTION("ALSA SoC Snapper CL15");
index ef15402a3bc4948311c69b4b69da9ebd7055ee58..4f59bbaba48f4fcb8ae70e0ced615f19ab71404e 100644 (file)
@@ -992,20 +992,7 @@ static struct platform_driver fsl_soc_dma_driver = {
        .remove = __devexit_p(fsl_soc_dma_remove),
 };
 
-static int __init fsl_soc_dma_init(void)
-{
-       pr_info("Freescale Elo DMA ASoC PCM Driver\n");
-
-       return platform_driver_register(&fsl_soc_dma_driver);
-}
-
-static void __exit fsl_soc_dma_exit(void)
-{
-       platform_driver_unregister(&fsl_soc_dma_driver);
-}
-
-module_init(fsl_soc_dma_init);
-module_exit(fsl_soc_dma_exit);
+module_platform_driver(fsl_soc_dma_driver);
 
 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
 MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
index 83c4bd5b2dd76bbf3f401c5a6bf0159d337f29b4..3e066966d8783f8c7e558c9c8677b64406c6b17b 100644 (file)
@@ -514,7 +514,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
        }
 }
 
-static struct snd_soc_dai_ops fsl_ssi_dai_ops = {
+static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
        .startup        = fsl_ssi_startup,
        .hw_params      = fsl_ssi_hw_params,
        .shutdown       = fsl_ssi_shutdown,
@@ -793,20 +793,7 @@ static struct platform_driver fsl_ssi_driver = {
        .remove = fsl_ssi_remove,
 };
 
-static int __init fsl_ssi_init(void)
-{
-       printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n");
-
-       return platform_driver_register(&fsl_ssi_driver);
-}
-
-static void __exit fsl_ssi_exit(void)
-{
-       platform_driver_unregister(&fsl_ssi_driver);
-}
-
-module_init(fsl_ssi_init);
-module_exit(fsl_ssi_exit);
+module_platform_driver(fsl_ssi_driver);
 
 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
 MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
index 5c6c2457386e9145dfaa513697c425f372f1cbfd..e7803d34c425a35a8be366ccd5b9324b8eb41cad 100644 (file)
@@ -526,17 +526,7 @@ static struct platform_driver mpc5200_hpcd_of_driver = {
        }
 };
 
-static int __init mpc5200_hpcd_init(void)
-{
-       return platform_driver_register(&mpc5200_hpcd_of_driver);
-}
-module_init(mpc5200_hpcd_init);
-
-static void __exit mpc5200_hpcd_exit(void)
-{
-       platform_driver_unregister(&mpc5200_hpcd_of_driver);
-}
-module_exit(mpc5200_hpcd_exit);
+module_platform_driver(mpc5200_hpcd_of_driver);
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
index ad36b095bb79ce268ba754a2dbe95446b510efc4..ffa00a2eb7704439341debdcf7cafe2310e4ce94 100644 (file)
@@ -226,12 +226,12 @@ static int psc_ac97_probe(struct snd_soc_dai *cpu_dai)
 /**
  * psc_ac97_dai_template: template CPU Digital Audio Interface
  */
-static struct snd_soc_dai_ops psc_ac97_analog_ops = {
+static const struct snd_soc_dai_ops psc_ac97_analog_ops = {
        .hw_params      = psc_ac97_hw_analog_params,
        .trigger        = psc_ac97_trigger,
 };
 
-static struct snd_soc_dai_ops psc_ac97_digital_ops = {
+static const struct snd_soc_dai_ops psc_ac97_digital_ops = {
        .hw_params      = psc_ac97_hw_digital_params,
 };
 
@@ -325,21 +325,7 @@ static struct platform_driver psc_ac97_driver = {
        },
 };
 
-/* ---------------------------------------------------------------------
- * Module setup and teardown; simply register the of_platform driver
- * for the PSC in AC97 mode.
- */
-static int __init psc_ac97_init(void)
-{
-       return platform_driver_register(&psc_ac97_driver);
-}
-module_init(psc_ac97_init);
-
-static void __exit psc_ac97_exit(void)
-{
-       platform_driver_unregister(&psc_ac97_driver);
-}
-module_exit(psc_ac97_exit);
+module_platform_driver(psc_ac97_driver);
 
 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
 MODULE_DESCRIPTION("mpc5200 AC97 module");
index 87cf2a5c2b2c2957e77fb17e94fa36038e6e318c..7b530327553ad998f0cdf81635e3af218418e414 100644 (file)
@@ -123,7 +123,7 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
 /**
  * psc_i2s_dai_template: template CPU Digital Audio Interface
  */
-static struct snd_soc_dai_ops psc_i2s_dai_ops = {
+static const struct snd_soc_dai_ops psc_i2s_dai_ops = {
        .hw_params      = psc_i2s_hw_params,
        .set_sysclk     = psc_i2s_set_sysclk,
        .set_fmt        = psc_i2s_set_fmt,
@@ -222,21 +222,7 @@ static struct platform_driver psc_i2s_driver = {
        },
 };
 
-/* ---------------------------------------------------------------------
- * Module setup and teardown; simply register the of_platform driver
- * for the PSC in I2S mode.
- */
-static int __init psc_i2s_init(void)
-{
-       return platform_driver_register(&psc_i2s_driver);
-}
-module_init(psc_i2s_init);
-
-static void __exit psc_i2s_exit(void)
-{
-       platform_driver_unregister(&psc_i2s_driver);
-}
-module_exit(psc_i2s_exit);
+module_platform_driver(psc_i2s_driver);
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
index 43fdc24f7e8d6fdf323f096fee6c01682c433a24..1cf2fe889f6adaa885c77bf2c74da9dd9f56a3d8 100644 (file)
@@ -326,16 +326,6 @@ static struct platform_driver imx_pcm_driver = {
        .remove = __devexit_p(imx_soc_platform_remove),
 };
 
-static int __init snd_imx_pcm_init(void)
-{
-       return platform_driver_register(&imx_pcm_driver);
-}
-module_init(snd_imx_pcm_init);
-
-static void __exit snd_imx_pcm_exit(void)
-{
-       platform_driver_unregister(&imx_pcm_driver);
-}
-module_exit(snd_imx_pcm_exit);
+module_platform_driver(imx_pcm_driver);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:imx-pcm-audio");
index 8df0fae21943b64d9bb99ffd462b679592a69742..d7ea0b3541245bbf5a3f81cf0398e19db2fea57b 100644 (file)
@@ -331,14 +331,4 @@ static struct platform_driver imx_pcm_driver = {
        .remove = __devexit_p(imx_soc_platform_remove),
 };
 
-static int __init snd_imx_pcm_init(void)
-{
-       return platform_driver_register(&imx_pcm_driver);
-}
-module_init(snd_imx_pcm_init);
-
-static void __exit snd_imx_pcm_exit(void)
-{
-       platform_driver_unregister(&imx_pcm_driver);
-}
-module_exit(snd_imx_pcm_exit);
+module_platform_driver(imx_pcm_driver);
index 4c05e2b8f4d2bf3bd09309c5e254e8bce02814b6..01d1f749cf021908ead5cb27e30966a17f144ca6 100644 (file)
@@ -342,7 +342,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
        return 0;
 }
 
-static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
+static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
        .hw_params      = imx_ssi_hw_params,
        .set_fmt        = imx_ssi_set_dai_fmt,
        .set_clkdiv     = imx_ssi_set_dai_clkdiv,
@@ -757,18 +757,7 @@ static struct platform_driver imx_ssi_driver = {
        },
 };
 
-static int __init imx_ssi_init(void)
-{
-       return platform_driver_register(&imx_ssi_driver);
-}
-
-static void __exit imx_ssi_exit(void)
-{
-       platform_driver_unregister(&imx_ssi_driver);
-}
-
-module_init(imx_ssi_init);
-module_exit(imx_ssi_exit);
+module_platform_driver(imx_ssi_driver);
 
 /* Module information */
 MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
index cd22a54b2f14b3cd408d64acbbc519786320f573..a5af7c42e62bb7ce641e13d3635c3c5312fc167b 100644 (file)
@@ -392,7 +392,7 @@ static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai)
        return 0;
 }
 
-static struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
+static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
        .startup = jz4740_i2s_startup,
        .shutdown = jz4740_i2s_shutdown,
        .trigger = jz4740_i2s_trigger,
@@ -519,17 +519,7 @@ static struct platform_driver jz4740_i2s_driver = {
        },
 };
 
-static int __init jz4740_i2s_init(void)
-{
-       return platform_driver_register(&jz4740_i2s_driver);
-}
-module_init(jz4740_i2s_init);
-
-static void __exit jz4740_i2s_exit(void)
-{
-       platform_driver_unregister(&jz4740_i2s_driver);
-}
-module_exit(jz4740_i2s_exit);
+module_platform_driver(jz4740_i2s_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
 MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
index d1989cde9f14d0d442531066f96b2a6e9c4f3525..50cda9ea915644baf3d93a02ec8b10e7e24d61d9 100644 (file)
@@ -356,17 +356,7 @@ static struct platform_driver jz4740_pcm_driver = {
        },
 };
 
-static int __init jz4740_soc_platform_init(void)
-{
-       return platform_driver_register(&jz4740_pcm_driver);
-}
-module_init(jz4740_soc_platform_init);
-
-static void __exit jz4740_soc_platform_exit(void)
-{
-       return platform_driver_unregister(&jz4740_pcm_driver);
-}
-module_exit(jz4740_soc_platform_exit);
+module_platform_driver(jz4740_pcm_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver");
index cd33de1c5b7a88bead8fe1c3ee25ae1bb6752c32..210438261a49fab17aeb6fe857846e9bccba74e7 100644 (file)
@@ -388,17 +388,7 @@ static struct platform_driver kirkwood_pcm_driver = {
        .remove = __devexit_p(kirkwood_soc_platform_remove),
 };
 
-static int __init kirkwood_pcm_init(void)
-{
-       return platform_driver_register(&kirkwood_pcm_driver);
-}
-module_init(kirkwood_pcm_init);
-
-static void __exit kirkwood_pcm_exit(void)
-{
-       platform_driver_unregister(&kirkwood_pcm_driver);
-}
-module_exit(kirkwood_pcm_exit);
+module_platform_driver(kirkwood_pcm_driver);
 
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module");
index 715e841c05072edeb469f1e99dc4aa60ad2821c5..f6bb211568769b897a2809a28679bf7aee373ace 100644 (file)
@@ -373,7 +373,7 @@ static int kirkwood_i2s_remove(struct snd_soc_dai *dai)
        return 0;
 }
 
-static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
+static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
        .startup        = kirkwood_i2s_startup,
        .trigger        = kirkwood_i2s_trigger,
        .hw_params      = kirkwood_i2s_hw_params,
@@ -483,17 +483,7 @@ static struct platform_driver kirkwood_i2s_driver = {
        },
 };
 
-static int __init kirkwood_i2s_init(void)
-{
-       return platform_driver_register(&kirkwood_i2s_driver);
-}
-module_init(kirkwood_i2s_init);
-
-static void __exit kirkwood_i2s_exit(void)
-{
-       platform_driver_unregister(&kirkwood_i2s_driver);
-}
-module_exit(kirkwood_i2s_exit);
+module_platform_driver(kirkwood_i2s_driver);
 
 /* Module information */
 MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
index cca693ae1bd444e5b12d7617f56a160453dafd9e..e53f8e473a78be51d13cff82f0cf17a7f5b24da3 100644 (file)
@@ -428,19 +428,7 @@ static struct platform_driver snd_mfld_mc_driver = {
        .remove = __devexit_p(snd_mfld_mc_remove),
 };
 
-static int __init snd_mfld_driver_init(void)
-{
-       pr_debug("snd_mfld_driver_init called\n");
-       return platform_driver_register(&snd_mfld_mc_driver);
-}
-module_init(snd_mfld_driver_init);
-
-static void __exit snd_mfld_driver_exit(void)
-{
-       pr_debug("snd_mfld_driver_exit called\n");
-       platform_driver_unregister(&snd_mfld_mc_driver);
-}
-module_exit(snd_mfld_driver_exit);
+module_platform_driver(snd_mfld_mc_driver);
 
 MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver");
 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
index 23057020aa0fb01abff851ae0fa4e3f75d9cf30c..94f70b3f94e655254b82caf123075e43e5895ae7 100644 (file)
@@ -472,19 +472,7 @@ static struct platform_driver sst_platform_driver = {
        .remove         = sst_platform_remove,
 };
 
-static int __init sst_soc_platform_init(void)
-{
-       pr_debug("sst_soc_platform_init called\n");
-       return platform_driver_register(&sst_platform_driver);
-}
-module_init(sst_soc_platform_init);
-
-static void __exit sst_soc_platform_exit(void)
-{
-       platform_driver_unregister(&sst_platform_driver);
-       pr_debug("sst_soc_platform_exit success\n");
-}
-module_exit(sst_soc_platform_exit);
+module_platform_driver(sst_platform_driver);
 
 MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
index dea5aa4aa6473a03231ff22e416bb61684c80046..612ad3d9052d7b555236188482cea3d0646336f5 100644 (file)
@@ -346,14 +346,4 @@ static struct platform_driver mxs_pcm_driver = {
        .remove = __devexit_p(mxs_soc_platform_remove),
 };
 
-static int __init snd_mxs_pcm_init(void)
-{
-       return platform_driver_register(&mxs_pcm_driver);
-}
-module_init(snd_mxs_pcm_init);
-
-static void __exit snd_mxs_pcm_exit(void)
-{
-       platform_driver_unregister(&mxs_pcm_driver);
-}
-module_exit(snd_mxs_pcm_exit);
+module_platform_driver(mxs_pcm_driver);
index 76dc74d24fc2ff7b50b9665b7443c56372c70b7c..1a13ab8b8e0da93d7c5bd6017bdd420c49cbc5e6 100644 (file)
@@ -550,7 +550,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
        SNDRV_PCM_FMTBIT_S24_LE)
 
-static struct snd_soc_dai_ops mxs_saif_dai_ops = {
+static const struct snd_soc_dai_ops mxs_saif_dai_ops = {
        .startup = mxs_saif_startup,
        .trigger = mxs_saif_trigger,
        .prepare = mxs_saif_prepare,
@@ -781,18 +781,8 @@ static struct platform_driver mxs_saif_driver = {
        },
 };
 
-static int __init mxs_saif_init(void)
-{
-       return platform_driver_register(&mxs_saif_driver);
-}
-
-static void __exit mxs_saif_exit(void)
-{
-       platform_driver_unregister(&mxs_saif_driver);
-}
+module_platform_driver(mxs_saif_driver);
 
-module_init(mxs_saif_init);
-module_exit(mxs_saif_exit);
 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 MODULE_DESCRIPTION("MXS ASoC SAIF driver");
 MODULE_LICENSE("GPL");
index 7fbeaec06eb4d514fdebb8aef5e4e1e568489b4c..200a9282b7cc66b2f5a610079e7cf35918bbad5c 100644 (file)
@@ -156,17 +156,7 @@ static struct platform_driver mxs_sgtl5000_audio_driver = {
        .remove = __devexit_p(mxs_sgtl5000_remove),
 };
 
-static int __init mxs_sgtl5000_init(void)
-{
-       return platform_driver_register(&mxs_sgtl5000_audio_driver);
-}
-module_init(mxs_sgtl5000_init);
-
-static void __exit mxs_sgtl5000_exit(void)
-{
-       platform_driver_unregister(&mxs_sgtl5000_audio_driver);
-}
-module_exit(mxs_sgtl5000_exit);
+module_platform_driver(mxs_sgtl5000_audio_driver);
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 MODULE_DESCRIPTION("MXS ALSA SoC Machine driver");
index 9c0edad90d8b4b3591c7c3a23f4c03b9e42594c1..f0c790451bd6d1fb1f92e38140086fe68a67598a 100644 (file)
@@ -291,7 +291,7 @@ static int nuc900_ac97_remove(struct snd_soc_dai *dai)
        return 0;
 }
 
-static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
+static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
        .trigger        = nuc900_ac97_trigger,
 };
 
@@ -405,18 +405,7 @@ static struct platform_driver nuc900_ac97_driver = {
        .remove         = __devexit_p(nuc900_ac97_drvremove),
 };
 
-static int __init nuc900_ac97_init(void)
-{
-       return platform_driver_register(&nuc900_ac97_driver);
-}
-
-static void __exit nuc900_ac97_exit(void)
-{
-       platform_driver_unregister(&nuc900_ac97_driver);
-}
-
-module_init(nuc900_ac97_init);
-module_exit(nuc900_ac97_exit);
+module_platform_driver(nuc900_ac97_driver);
 
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
 MODULE_DESCRIPTION("NUC900 AC97 SoC driver!");
index ae8d6806966ba935cbbebd3ec11c5bdaa82ad8c4..37585b47f4e3c4a5ea48ce7513ef08093de7e08d 100644 (file)
@@ -358,17 +358,7 @@ static struct platform_driver nuc900_pcm_driver = {
        .remove = __devexit_p(nuc900_soc_platform_remove),
 };
 
-static int __init nuc900_pcm_init(void)
-{
-       return platform_driver_register(&nuc900_pcm_driver);
-}
-module_init(nuc900_pcm_init);
-
-static void __exit nuc900_pcm_exit(void)
-{
-       platform_driver_unregister(&nuc900_pcm_driver);
-}
-module_exit(nuc900_pcm_exit);
+module_platform_driver(nuc900_pcm_driver);
 
 MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>");
 MODULE_DESCRIPTION("nuc900 Audio DMA module");
index fe83d0d176be4b43d34bacc8f34e10e3973c234f..fb1bf2581efb1b224aadbdd040ec83feab61f88d 100644 (file)
@@ -2,6 +2,9 @@ config SND_OMAP_SOC
        tristate "SoC Audio for the Texas Instruments OMAP chips"
        depends on ARCH_OMAP
 
+config SND_OMAP_SOC_DMIC
+       tristate
+
 config SND_OMAP_SOC_MCBSP
        tristate
        select OMAP_MCBSP
@@ -97,8 +100,10 @@ config SND_OMAP_SOC_SDP3430
 config SND_OMAP_SOC_SDP4430
        tristate "SoC Audio support for Texas Instruments SDP4430"
        depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP
+       select SND_OMAP_SOC_DMIC
        select SND_OMAP_SOC_MCPDM
        select SND_SOC_TWL6040
+       select SND_SOC_DMIC
        help
          Say Y if you want to add support for SoC audio on Texas Instruments
          SDP4430.
index 052fd758722eb0cdc2db322476546228d5e534e8..1fd723fb559d0e14b55bd4b2bf549f77a532ea5c 100644 (file)
@@ -1,10 +1,12 @@
 # OMAP Platform Support
 snd-soc-omap-objs := omap-pcm.o
+snd-soc-omap-dmic-objs := omap-dmic.o
 snd-soc-omap-mcbsp-objs := omap-mcbsp.o
 snd-soc-omap-mcpdm-objs := omap-mcpdm.o
 snd-soc-omap-hdmi-objs := omap-hdmi.o
 
 obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
+obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
 obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
 obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
 obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o
index ccb8a6aa1817acec4d71f0b5988faaf547e35599..a04a4338fdac131e5542dc0a41c757e3ed5a46a7 100644 (file)
@@ -474,7 +474,7 @@ static int ams_delta_digital_mute(struct snd_soc_dai *dai, int mute)
 }
 
 /* Our codec DAI probably doesn't have its own .ops structure */
-static struct snd_soc_dai_ops ams_delta_dai_ops = {
+static const struct snd_soc_dai_ops ams_delta_dai_ops = {
        .digital_mute = ams_delta_digital_mute,
 };
 
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
new file mode 100644 (file)
index 0000000..9c73c0c
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * omap-dmic.c  --  OMAP ASoC DMIC DAI driver
+ *
+ * Copyright (C) 2010 - 2011 Texas Instruments
+ *
+ * Author: David Lambert <dlambert@ti.com>
+ *        Misael Lopez Cruz <misael.lopez@ti.com>
+ *        Liam Girdwood <lrg@ti.com>
+ *        Peter Ujfalusi <peter.ujfalusi@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
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <plat/dma.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include "omap-pcm.h"
+#include "omap-dmic.h"
+
+struct omap_dmic {
+       struct device *dev;
+       void __iomem *io_base;
+       struct clk *fclk;
+       int fclk_freq;
+       int out_freq;
+       int clk_div;
+       int sysclk;
+       int threshold;
+       u32 ch_enabled;
+       bool active;
+       struct mutex mutex;
+};
+
+/*
+ * Stream DMA parameters
+ */
+static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
+       .name           = "DMIC capture",
+       .data_type      = OMAP_DMA_DATA_TYPE_S32,
+       .sync_mode      = OMAP_DMA_SYNC_PACKET,
+};
+
+static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
+{
+       __raw_writel(val, dmic->io_base + reg);
+}
+
+static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg)
+{
+       return __raw_readl(dmic->io_base + reg);
+}
+
+static inline void omap_dmic_start(struct omap_dmic *dmic)
+{
+       u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
+
+       /* Configure DMA controller */
+       omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET_REG,
+                       OMAP_DMIC_DMA_ENABLE);
+
+       omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl | dmic->ch_enabled);
+}
+
+static inline void omap_dmic_stop(struct omap_dmic *dmic)
+{
+       u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
+       omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
+                       ctrl & ~OMAP_DMIC_UP_ENABLE_MASK);
+
+       /* Disable DMA request generation */
+       omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR_REG,
+                       OMAP_DMIC_DMA_ENABLE);
+
+}
+
+static inline int dmic_is_enabled(struct omap_dmic *dmic)
+{
+       return omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG) &
+                                               OMAP_DMIC_UP_ENABLE_MASK;
+}
+
+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);
+       int ret = 0;
+
+       mutex_lock(&dmic->mutex);
+
+       if (!dai->active) {
+               pm_runtime_get_sync(dmic->dev);
+               snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
+               dmic->active = 1;
+       } else {
+               ret = -EBUSY;
+       }
+
+       mutex_unlock(&dmic->mutex);
+
+       return ret;
+}
+
+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);
+
+       mutex_lock(&dmic->mutex);
+
+       if (!dai->active) {
+               pm_runtime_put_sync(dmic->dev);
+               dmic->active = 0;
+       }
+
+       mutex_unlock(&dmic->mutex);
+}
+
+static int omap_dmic_select_divider(struct omap_dmic *dmic, int sample_rate)
+{
+       int divider = -EINVAL;
+
+       /*
+        * 192KHz rate is only supported with 19.2MHz/3.84MHz clock
+        * configuration.
+        */
+       if (sample_rate == 192000) {
+               if (dmic->fclk_freq == 19200000 && dmic->out_freq == 3840000)
+                       divider = 0x6; /* Divider: 5 (192KHz sampling rate) */
+               else
+                       dev_err(dmic->dev,
+                               "invalid clock configuration for 192KHz\n");
+
+               return divider;
+       }
+
+       switch (dmic->out_freq) {
+       case 1536000:
+               if (dmic->fclk_freq != 24576000)
+                       goto div_err;
+               divider = 0x4; /* Divider: 16 */
+               break;
+       case 2400000:
+               switch (dmic->fclk_freq) {
+               case 12000000:
+                       divider = 0x5; /* Divider: 5 */
+                       break;
+               case 19200000:
+                       divider = 0x0; /* Divider: 8 */
+                       break;
+               case 24000000:
+                       divider = 0x2; /* Divider: 10 */
+                       break;
+               default:
+                       goto div_err;
+               }
+               break;
+       case 3072000:
+               if (dmic->fclk_freq != 24576000)
+                       goto div_err;
+               divider = 0x3; /* Divider: 8 */
+               break;
+       case 3840000:
+               if (dmic->fclk_freq != 19200000)
+                       goto div_err;
+               divider = 0x1; /* Divider: 5 (96KHz sampling rate) */
+               break;
+       default:
+               dev_err(dmic->dev, "invalid out frequency: %dHz\n",
+                       dmic->out_freq);
+               break;
+       }
+
+       return divider;
+
+div_err:
+       dev_err(dmic->dev, "invalid out frequency %dHz for %dHz input\n",
+               dmic->out_freq, dmic->fclk_freq);
+       return -EINVAL;
+}
+
+static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
+                                   struct snd_pcm_hw_params *params,
+                                   struct snd_soc_dai *dai)
+{
+       struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+       int channels;
+
+       dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
+       if (dmic->clk_div < 0) {
+               dev_err(dmic->dev, "no valid divider for %dHz from %dHz\n",
+                       dmic->out_freq, dmic->fclk_freq);
+               return -EINVAL;
+       }
+
+       dmic->ch_enabled = 0;
+       channels = params_channels(params);
+       switch (channels) {
+       case 6:
+               dmic->ch_enabled |= OMAP_DMIC_UP3_ENABLE;
+       case 4:
+               dmic->ch_enabled |= OMAP_DMIC_UP2_ENABLE;
+       case 2:
+               dmic->ch_enabled |= OMAP_DMIC_UP1_ENABLE;
+               break;
+       default:
+               dev_err(dmic->dev, "invalid number of legacy channels\n");
+               return -EINVAL;
+       }
+
+       /* packet size is threshold * channels */
+       omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels;
+       snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
+
+       return 0;
+}
+
+static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
+                                 struct snd_soc_dai *dai)
+{
+       struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+       u32 ctrl;
+
+       /* Configure uplink threshold */
+       omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold);
+
+       ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG);
+
+       /* Set dmic out format */
+       ctrl &= ~(OMAP_DMIC_FORMAT | OMAP_DMIC_POLAR_MASK);
+       ctrl |= (OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 |
+                OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
+
+       /* Configure dmic clock divider */
+       ctrl &= ~OMAP_DMIC_CLK_DIV_MASK;
+       ctrl |= OMAP_DMIC_CLK_DIV(dmic->clk_div);
+
+       omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl);
+
+       omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG,
+                       ctrl | OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 |
+                       OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3);
+
+       return 0;
+}
+
+static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
+                                 int cmd, struct snd_soc_dai *dai)
+{
+       struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               omap_dmic_start(dmic);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               omap_dmic_stop(dmic);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
+                                unsigned int freq)
+{
+       struct clk *parent_clk;
+       char *parent_clk_name;
+       int ret = 0;
+
+       switch (freq) {
+       case 12000000:
+       case 19200000:
+       case 24000000:
+       case 24576000:
+               break;
+       default:
+               dev_err(dmic->dev, "invalid input frequency: %dHz\n", freq);
+               dmic->fclk_freq = 0;
+               return -EINVAL;
+       }
+
+       if (dmic->sysclk == clk_id) {
+               dmic->fclk_freq = freq;
+               return 0;
+       }
+
+       /* re-parent not allowed if a stream is ongoing */
+       if (dmic->active && dmic_is_enabled(dmic)) {
+               dev_err(dmic->dev, "can't re-parent when DMIC active\n");
+               return -EBUSY;
+       }
+
+       switch (clk_id) {
+       case OMAP_DMIC_SYSCLK_PAD_CLKS:
+               parent_clk_name = "pad_clks_ck";
+               break;
+       case OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS:
+               parent_clk_name = "slimbus_clk";
+               break;
+       case OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS:
+               parent_clk_name = "dmic_sync_mux_ck";
+               break;
+       default:
+               dev_err(dmic->dev, "fclk clk_id (%d) not supported\n", clk_id);
+               return -EINVAL;
+       }
+
+       parent_clk = clk_get(dmic->dev, parent_clk_name);
+       if (IS_ERR(parent_clk)) {
+               dev_err(dmic->dev, "can't get %s\n", parent_clk_name);
+               return -ENODEV;
+       }
+
+       mutex_lock(&dmic->mutex);
+       if (dmic->active) {
+               /* disable clock while reparenting */
+               pm_runtime_put_sync(dmic->dev);
+               ret = clk_set_parent(dmic->fclk, parent_clk);
+               pm_runtime_get_sync(dmic->dev);
+       } else {
+               ret = clk_set_parent(dmic->fclk, parent_clk);
+       }
+       mutex_unlock(&dmic->mutex);
+
+       if (ret < 0) {
+               dev_err(dmic->dev, "re-parent failed\n");
+               goto err_busy;
+       }
+
+       dmic->sysclk = clk_id;
+       dmic->fclk_freq = freq;
+
+err_busy:
+       clk_put(parent_clk);
+
+       return ret;
+}
+
+static int omap_dmic_select_outclk(struct omap_dmic *dmic, int clk_id,
+                                   unsigned int freq)
+{
+       int ret = 0;
+
+       if (clk_id != OMAP_DMIC_ABE_DMIC_CLK) {
+               dev_err(dmic->dev, "output clk_id (%d) not supported\n",
+                       clk_id);
+               return -EINVAL;
+       }
+
+       switch (freq) {
+       case 1536000:
+       case 2400000:
+       case 3072000:
+       case 3840000:
+               dmic->out_freq = freq;
+               break;
+       default:
+               dev_err(dmic->dev, "invalid out frequency: %dHz\n", freq);
+               dmic->out_freq = 0;
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int omap_dmic_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+                                   unsigned int freq, int dir)
+{
+       struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+       if (dir == SND_SOC_CLOCK_IN)
+               return omap_dmic_select_fclk(dmic, clk_id, freq);
+       else if (dir == SND_SOC_CLOCK_OUT)
+               return omap_dmic_select_outclk(dmic, clk_id, freq);
+
+       dev_err(dmic->dev, "invalid clock direction (%d)\n", dir);
+       return -EINVAL;
+}
+
+static const struct snd_soc_dai_ops omap_dmic_dai_ops = {
+       .startup        = omap_dmic_dai_startup,
+       .shutdown       = omap_dmic_dai_shutdown,
+       .hw_params      = omap_dmic_dai_hw_params,
+       .prepare        = omap_dmic_dai_prepare,
+       .trigger        = omap_dmic_dai_trigger,
+       .set_sysclk     = omap_dmic_set_dai_sysclk,
+};
+
+static int omap_dmic_probe(struct snd_soc_dai *dai)
+{
+       struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+       pm_runtime_enable(dmic->dev);
+
+       /* Disable lines while request is ongoing */
+       pm_runtime_get_sync(dmic->dev);
+       omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, 0x00);
+       pm_runtime_put_sync(dmic->dev);
+
+       /* Configure DMIC threshold value */
+       dmic->threshold = OMAP_DMIC_THRES_MAX - 3;
+       return 0;
+}
+
+static int omap_dmic_remove(struct snd_soc_dai *dai)
+{
+       struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+
+       pm_runtime_disable(dmic->dev);
+
+       return 0;
+}
+
+static struct snd_soc_dai_driver omap_dmic_dai = {
+       .name = "omap-dmic",
+       .probe = omap_dmic_probe,
+       .remove = omap_dmic_remove,
+       .capture = {
+               .channels_min = 2,
+               .channels_max = 6,
+               .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+               .formats = SNDRV_PCM_FMTBIT_S32_LE,
+       },
+       .ops = &omap_dmic_dai_ops,
+};
+
+static __devinit int asoc_dmic_probe(struct platform_device *pdev)
+{
+       struct omap_dmic *dmic;
+       struct resource *res;
+       int ret;
+
+       dmic = devm_kzalloc(&pdev->dev, sizeof(struct omap_dmic), GFP_KERNEL);
+       if (!dmic)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, dmic);
+       dmic->dev = &pdev->dev;
+       dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS;
+
+       mutex_init(&dmic->mutex);
+
+       dmic->fclk = clk_get(dmic->dev, "dmic_fck");
+       if (IS_ERR(dmic->fclk)) {
+               dev_err(dmic->dev, "cant get dmic_fck\n");
+               return -ENODEV;
+       }
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
+       if (!res) {
+               dev_err(dmic->dev, "invalid dma memory resource\n");
+               ret = -ENODEV;
+               goto err_put_clk;
+       }
+       omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG;
+
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!res) {
+               dev_err(dmic->dev, "invalid dma resource\n");
+               ret = -ENODEV;
+               goto err_put_clk;
+       }
+       omap_dmic_dai_dma_params.dma_req = res->start;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
+       if (!res) {
+               dev_err(dmic->dev, "invalid memory resource\n");
+               ret = -ENODEV;
+               goto err_put_clk;
+       }
+
+       if (!devm_request_mem_region(&pdev->dev, res->start,
+                                    resource_size(res), pdev->name)) {
+               dev_err(dmic->dev, "memory region already claimed\n");
+               ret = -ENODEV;
+               goto err_put_clk;
+       }
+
+       dmic->io_base = devm_ioremap(&pdev->dev, res->start,
+                                    resource_size(res));
+       if (!dmic->io_base) {
+               ret = -ENOMEM;
+               goto err_put_clk;
+       }
+
+       ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai);
+       if (ret)
+               goto err_put_clk;
+
+       return 0;
+
+err_put_clk:
+       clk_put(dmic->fclk);
+       return ret;
+}
+
+static int __devexit asoc_dmic_remove(struct platform_device *pdev)
+{
+       struct omap_dmic *dmic = platform_get_drvdata(pdev);
+
+       snd_soc_unregister_dai(&pdev->dev);
+       clk_put(dmic->fclk);
+
+       return 0;
+}
+
+static struct platform_driver asoc_dmic_driver = {
+       .driver = {
+               .name = "omap-dmic",
+               .owner = THIS_MODULE,
+       },
+       .probe = asoc_dmic_probe,
+       .remove = __devexit_p(asoc_dmic_remove),
+};
+
+module_platform_driver(asoc_dmic_driver);
+
+MODULE_ALIAS("platform:omap-dmic");
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("OMAP DMIC ASoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-dmic.h b/sound/soc/omap/omap-dmic.h
new file mode 100644 (file)
index 0000000..231e728
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * omap-dmic.h  --  OMAP Digital Microphone Controller
+ *
+ * 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 _OMAP_DMIC_H
+#define _OMAP_DMIC_H
+
+#define OMAP_DMIC_REVISION_REG         0x00
+#define OMAP_DMIC_SYSCONFIG_REG                0x10
+#define OMAP_DMIC_IRQSTATUS_RAW_REG    0x24
+#define OMAP_DMIC_IRQSTATUS_REG                0x28
+#define OMAP_DMIC_IRQENABLE_SET_REG    0x2C
+#define OMAP_DMIC_IRQENABLE_CLR_REG    0x30
+#define OMAP_DMIC_IRQWAKE_EN_REG       0x34
+#define OMAP_DMIC_DMAENABLE_SET_REG    0x38
+#define OMAP_DMIC_DMAENABLE_CLR_REG    0x3C
+#define OMAP_DMIC_DMAWAKEEN_REG                0x40
+#define OMAP_DMIC_CTRL_REG             0x44
+#define OMAP_DMIC_DATA_REG             0x48
+#define OMAP_DMIC_FIFO_CTRL_REG                0x4C
+#define OMAP_DMIC_FIFO_DMIC1R_DATA_REG 0x50
+#define OMAP_DMIC_FIFO_DMIC1L_DATA_REG 0x54
+#define OMAP_DMIC_FIFO_DMIC2R_DATA_REG 0x58
+#define OMAP_DMIC_FIFO_DMIC2L_DATA_REG 0x5C
+#define OMAP_DMIC_FIFO_DMIC3R_DATA_REG 0x60
+#define OMAP_DMIC_FIFO_DMIC3L_DATA_REG 0x64
+
+/* IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR bit fields */
+#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           (1 << 0)
+#define OMAP_DMIC_UP2_ENABLE           (1 << 1)
+#define OMAP_DMIC_UP3_ENABLE           (1 << 2)
+#define OMAP_DMIC_UP_ENABLE_MASK       0x7
+#define OMAP_DMIC_FORMAT               (1 << 3)
+#define OMAP_DMIC_POLAR1               (1 << 4)
+#define OMAP_DMIC_POLAR2               (1 << 5)
+#define OMAP_DMIC_POLAR3               (1 << 6)
+#define OMAP_DMIC_POLAR_MASK           (0x7 << 4)
+#define OMAP_DMIC_CLK_DIV(x)           (((x) & 0x7) << 7)
+#define OMAP_DMIC_CLK_DIV_MASK         (0x7 << 7)
+#define        OMAP_DMIC_RESET                 (1 << 10)
+
+#define OMAP_DMICOUTFORMAT_LJUST       (0 << 3)
+#define OMAP_DMICOUTFORMAT_RJUST       (1 << 3)
+
+/* DMIC_FIFO_CTRL bit fields */
+#define OMAP_DMIC_THRES_MAX            0xF
+
+enum omap_dmic_clk {
+       OMAP_DMIC_SYSCLK_PAD_CLKS,              /* PAD_CLKS */
+       OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS,         /* SLIMBUS_CLK */
+       OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS,         /* DMIC_SYNC_MUX_CLK */
+       OMAP_DMIC_ABE_DMIC_CLK,                 /* abe_dmic_clk */
+};
+
+#endif
index 36c6eaeffb026b226d39aedff9b97e4688621362..38e0defa7078a9cf57f4d9c8fd7c2a6c3336fdd0 100644 (file)
@@ -83,7 +83,7 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
        return err;
 }
 
-static struct snd_soc_dai_ops omap_hdmi_dai_ops = {
+static const struct snd_soc_dai_ops omap_hdmi_dai_ops = {
        .startup        = omap_hdmi_dai_startup,
        .hw_params      = omap_hdmi_dai_hw_params,
 };
@@ -139,17 +139,7 @@ static struct platform_driver hdmi_dai_driver = {
        .remove = __devexit_p(omap_hdmi_remove),
 };
 
-static int __init hdmi_dai_init(void)
-{
-       return platform_driver_register(&hdmi_dai_driver);
-}
-module_init(hdmi_dai_init);
-
-static void __exit hdmi_dai_exit(void)
-{
-       platform_driver_unregister(&hdmi_dai_driver);
-}
-module_exit(hdmi_dai_exit);
+module_platform_driver(hdmi_dai_driver);
 
 MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>");
 MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
index 4314647e735eff71a8f038263e2f0e4a640d8d24..bd11d25685847a0e597cfd30db4a75d35d444ced 100644 (file)
@@ -599,7 +599,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
        return err;
 }
 
-static struct snd_soc_dai_ops mcbsp_dai_ops = {
+static const struct snd_soc_dai_ops mcbsp_dai_ops = {
        .startup        = omap_mcbsp_dai_startup,
        .shutdown       = omap_mcbsp_dai_shutdown,
        .trigger        = omap_mcbsp_dai_trigger,
@@ -785,17 +785,7 @@ static struct platform_driver asoc_mcbsp_driver = {
        .remove = __devexit_p(asoc_mcbsp_remove),
 };
 
-static int __init snd_omap_mcbsp_init(void)
-{
-       return platform_driver_register(&asoc_mcbsp_driver);
-}
-module_init(snd_omap_mcbsp_init);
-
-static void __exit snd_omap_mcbsp_exit(void)
-{
-       platform_driver_unregister(&asoc_mcbsp_driver);
-}
-module_exit(snd_omap_mcbsp_exit);
+module_platform_driver(asoc_mcbsp_driver);
 
 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
 MODULE_DESCRIPTION("OMAP I2S SoC Interface");
index 41d17067cc739a05ac085443cdbe1fd6e984593e..b50ac60be7dba5e2e6cf49d6df4e5ba14d51dd21 100644 (file)
@@ -367,7 +367,7 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
+static const struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
        .startup        = omap_mcpdm_dai_startup,
        .shutdown       = omap_mcpdm_dai_shutdown,
        .hw_params      = omap_mcpdm_dai_hw_params,
@@ -520,17 +520,7 @@ static struct platform_driver asoc_mcpdm_driver = {
        .remove = __devexit_p(asoc_mcpdm_remove),
 };
 
-static int __init snd_omap_mcpdm_init(void)
-{
-       return platform_driver_register(&asoc_mcpdm_driver);
-}
-module_init(snd_omap_mcpdm_init);
-
-static void __exit snd_omap_mcpdm_exit(void)
-{
-       platform_driver_unregister(&asoc_mcpdm_driver);
-}
-module_exit(snd_omap_mcpdm_exit);
+module_platform_driver(asoc_mcpdm_driver);
 
 MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
 MODULE_DESCRIPTION("OMAP PDM SoC Interface");
index 6ede7dc6c10a9ef858ef6016c87f0abbd93fa9fe..52a0f634948ed00a368157af966b6fc10453730f 100644 (file)
@@ -433,17 +433,7 @@ static struct platform_driver omap_pcm_driver = {
        .remove = __devexit_p(omap_pcm_remove),
 };
 
-static int __init snd_omap_pcm_init(void)
-{
-       return platform_driver_register(&omap_pcm_driver);
-}
-module_init(snd_omap_pcm_init);
-
-static void __exit snd_omap_pcm_exit(void)
-{
-       platform_driver_unregister(&omap_pcm_driver);
-}
-module_exit(snd_omap_pcm_exit);
+module_platform_driver(omap_pcm_driver);
 
 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
 MODULE_DESCRIPTION("OMAP PCM DMA module");
index 8671261ba16d3d831a72fc9ef74024f34af52939..52d471c1eeedc63b81be42aee5b337dded08725f 100644 (file)
@@ -112,17 +112,7 @@ static struct platform_driver omap4_hdmi_driver = {
        .remove = __devexit_p(omap4_hdmi_remove),
 };
 
-static int __init omap4_hdmi_init(void)
-{
-       return platform_driver_register(&omap4_hdmi_driver);
-}
-module_init(omap4_hdmi_init);
-
-static void __exit omap4_hdmi_exit(void)
-{
-       platform_driver_unregister(&omap4_hdmi_driver);
-}
-module_exit(omap4_hdmi_exit);
+module_platform_driver(omap4_hdmi_driver);
 
 MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
 MODULE_DESCRIPTION("OMAP4 HDMI machine ASoC driver");
index 03d9fa4192fe611a9119986ce17ed9e18648ee4c..2735fa03b74b0dcfb7d1e14f3600e33f5a15176d 100644 (file)
@@ -33,6 +33,7 @@
 #include <plat/hardware.h>
 #include <plat/mux.h>
 
+#include "omap-dmic.h"
 #include "omap-mcpdm.h"
 #include "omap-pcm.h"
 #include "../codecs/twl6040.h"
@@ -67,6 +68,32 @@ static struct snd_soc_ops sdp4430_ops = {
        .hw_params = sdp4430_hw_params,
 };
 
+static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       int ret = 0;
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
+                                    19200000, SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set DMIC cpu system clock\n");
+               return ret;
+       }
+       ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
+                                    SND_SOC_CLOCK_OUT);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set DMIC output clock\n");
+               return ret;
+       }
+       return 0;
+}
+
+static struct snd_soc_ops sdp4430_dmic_ops = {
+       .hw_params = sdp4430_dmic_hw_params,
+};
+
 /* Headset jack */
 static struct snd_soc_jack hs_jack;
 
@@ -148,23 +175,59 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
        return ret;
 }
 
+static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = {
+       SND_SOC_DAPM_MIC("Digital Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route dmic_audio_map[] = {
+       {"DMic", NULL, "Digital Mic1 Bias"},
+       {"Digital Mic1 Bias", NULL, "Digital Mic"},
+};
+
+static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       int ret;
+
+       ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets,
+                               ARRAY_SIZE(sdp4430_dmic_dapm_widgets));
+       if (ret)
+               return ret;
+
+       return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
+                               ARRAY_SIZE(dmic_audio_map));
+}
+
 /* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sdp4430_dai = {
-       .name = "TWL6040",
-       .stream_name = "TWL6040",
-       .cpu_dai_name = "omap-mcpdm",
-       .codec_dai_name = "twl6040-legacy",
-       .platform_name = "omap-pcm-audio",
-       .codec_name = "twl6040-codec",
-       .init = sdp4430_twl6040_init,
-       .ops = &sdp4430_ops,
+static struct snd_soc_dai_link sdp4430_dai[] = {
+       {
+               .name = "TWL6040",
+               .stream_name = "TWL6040",
+               .cpu_dai_name = "omap-mcpdm",
+               .codec_dai_name = "twl6040-legacy",
+               .platform_name = "omap-pcm-audio",
+               .codec_name = "twl6040-codec",
+               .init = sdp4430_twl6040_init,
+               .ops = &sdp4430_ops,
+       },
+       {
+               .name = "DMIC",
+               .stream_name = "DMIC Capture",
+               .cpu_dai_name = "omap-dmic",
+               .codec_dai_name = "dmic-hifi",
+               .platform_name = "omap-pcm-audio",
+               .codec_name = "dmic-codec",
+               .init = sdp4430_dmic_init,
+               .ops = &sdp4430_dmic_ops,
+       },
 };
 
 /* Audio machine driver */
 static struct snd_soc_card snd_soc_sdp4430 = {
        .name = "SDP4430",
-       .dai_link = &sdp4430_dai,
-       .num_links = 1,
+       .dai_link = sdp4430_dai,
+       .num_links = ARRAY_SIZE(sdp4430_dai),
 
        .dapm_widgets = sdp4430_twl6040_dapm_widgets,
        .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets),
index 65c124831a0063f0b645062a13559348e5af367a..e32afaf1ebbb44a467eaf802093902e4fdf9c18d 100644 (file)
@@ -236,18 +236,7 @@ static struct platform_driver hx4700_audio_driver = {
        .remove = __devexit_p(hx4700_audio_remove),
 };
 
-static int __init hx4700_modinit(void)
-{
-       return platform_driver_register(&hx4700_audio_driver);
-}
-module_init(hx4700_modinit);
-
-static void __exit hx4700_modexit(void)
-{
-       platform_driver_unregister(&hx4700_audio_driver);
-}
-
-module_exit(hx4700_modexit);
+module_platform_driver(hx4700_audio_driver);
 
 MODULE_AUTHOR("Philipp Zabel");
 MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700");
index 0b8d1ee738a45ae82c2e3dc22efca0d2ab6c152a..0e73a7f718e42d2f66d47529b9f749685281093e 100644 (file)
@@ -227,18 +227,7 @@ static struct platform_driver mioa701_wm9713_driver = {
        },
 };
 
-static int __init mioa701_asoc_init(void)
-{
-       return platform_driver_register(&mioa701_wm9713_driver);
-}
-
-static void __exit mioa701_asoc_exit(void)
-{
-       platform_driver_unregister(&mioa701_wm9713_driver);
-}
-
-module_init(mioa701_asoc_init);
-module_exit(mioa701_asoc_exit);
+module_platform_driver(mioa701_wm9713_driver);
 
 /* Module information */
 MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)");
index 7edc1fb71fae05288eebd25ce16d82d122c83227..f313eca40fdc96cb5fcd39b1d4df3f4f18ee9358 100644 (file)
@@ -201,18 +201,7 @@ static struct platform_driver palm27x_wm9712_driver = {
        },
 };
 
-static int __init palm27x_asoc_init(void)
-{
-       return platform_driver_register(&palm27x_wm9712_driver);
-}
-
-static void __exit palm27x_asoc_exit(void)
-{
-       platform_driver_unregister(&palm27x_wm9712_driver);
-}
-
-module_init(palm27x_asoc_init);
-module_exit(palm27x_asoc_exit);
+module_platform_driver(palm27x_wm9712_driver);
 
 /* Module information */
 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
index 8ad93ee2e92bfe312157b46eabbe251b9db35f9d..a57cfbc038e3cc1522c33b98d9fd648203948337 100644 (file)
@@ -771,7 +771,7 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai)
                            SNDRV_PCM_FMTBIT_S24_LE |   \
                            SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ssp_dai_ops = {
        .startup        = pxa_ssp_startup,
        .shutdown       = pxa_ssp_shutdown,
        .trigger        = pxa_ssp_trigger,
@@ -825,17 +825,7 @@ static struct platform_driver asoc_ssp_driver = {
        .remove = __devexit_p(asoc_ssp_remove),
 };
 
-static int __init pxa_ssp_init(void)
-{
-       return platform_driver_register(&asoc_ssp_driver);
-}
-module_init(pxa_ssp_init);
-
-static void __exit pxa_ssp_exit(void)
-{
-       platform_driver_unregister(&asoc_ssp_driver);
-}
-module_exit(pxa_ssp_exit);
+module_platform_driver(asoc_ssp_driver);
 
 /* Module information */
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
index ac51c6d25c4291998bd7ffc6b4d51a0c0148923a..837ff341fd6dda45954f2ec34fd263f24a54d62e 100644 (file)
@@ -163,15 +163,15 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
                SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
                SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
        .hw_params      = pxa2xx_ac97_hw_params,
 };
 
-static struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
        .hw_params      = pxa2xx_ac97_hw_aux_params,
 };
 
-static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
+static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
        .hw_params      = pxa2xx_ac97_hw_mic_params,
 };
 
@@ -263,17 +263,7 @@ static struct platform_driver pxa2xx_ac97_driver = {
        },
 };
 
-static int __init pxa_ac97_init(void)
-{
-       return platform_driver_register(&pxa2xx_ac97_driver);
-}
-module_init(pxa_ac97_init);
-
-static void __exit pxa_ac97_exit(void)
-{
-       platform_driver_unregister(&pxa2xx_ac97_driver);
-}
-module_exit(pxa_ac97_exit);
+module_platform_driver(pxa2xx_ac97_driver);
 
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
index 11be5952a5066fa30163a3b51143b9dfb41b05e7..609abd51e55fef65ed8ec34157165b3e1a55b700 100644 (file)
@@ -331,7 +331,7 @@ static int  pxa2xx_i2s_remove(struct snd_soc_dai *dai)
                SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
                SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
 
-static struct snd_soc_dai_ops pxa_i2s_dai_ops = {
+static const struct snd_soc_dai_ops pxa_i2s_dai_ops = {
        .startup        = pxa2xx_i2s_startup,
        .shutdown       = pxa2xx_i2s_shutdown,
        .trigger        = pxa2xx_i2s_trigger,
index 600676f709a927b2c4a568d03fd8869dafff721a..fdd6bedef9bd7d818dadf36049df53ed067d842d 100644 (file)
@@ -141,17 +141,7 @@ static struct platform_driver pxa_pcm_driver = {
        .remove = __devexit_p(pxa2xx_soc_platform_remove),
 };
 
-static int __init snd_pxa_pcm_init(void)
-{
-       return platform_driver_register(&pxa_pcm_driver);
-}
-module_init(snd_pxa_pcm_init);
-
-static void __exit snd_pxa_pcm_exit(void)
-{
-       platform_driver_unregister(&pxa_pcm_driver);
-}
-module_exit(snd_pxa_pcm_exit);
+module_platform_driver(pxa_pcm_driver);
 
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
index 3052f64b2403929a62fec3c8257aedec40c8a7a2..aaabdbaec19c6cf389f887669af54a3558f16aba 100644 (file)
@@ -409,7 +409,7 @@ static int s6000_i2s_dai_probe(struct snd_soc_dai *dai)
                         SNDRV_PCM_RATE_8000_192000)
 #define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
-static struct snd_soc_dai_ops s6000_i2s_dai_ops = {
+static const struct snd_soc_dai_ops s6000_i2s_dai_ops = {
        .set_fmt = s6000_i2s_set_dai_fmt,
        .set_clkdiv = s6000_i2s_set_clkdiv,
        .hw_params = s6000_i2s_hw_params,
@@ -604,17 +604,7 @@ static struct platform_driver s6000_i2s_driver = {
        },
 };
 
-static int __init s6000_i2s_init(void)
-{
-       return platform_driver_register(&s6000_i2s_driver);
-}
-module_init(s6000_i2s_init);
-
-static void __exit s6000_i2s_exit(void)
-{
-       platform_driver_unregister(&s6000_i2s_driver);
-}
-module_exit(s6000_i2s_exit);
+module_platform_driver(s6000_i2s_driver);
 
 MODULE_AUTHOR("Daniel Gloeckner");
 MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface");
index 55efc2bdf0bd0a4fd73f938299764222601a5014..43c014f362f60643a9f5f4d798a2c651b6c0af1b 100644 (file)
@@ -520,17 +520,7 @@ static struct platform_driver s6000_pcm_driver = {
        .remove = __devexit_p(s6000_soc_platform_remove),
 };
 
-static int __init snd_s6000_pcm_init(void)
-{
-       return platform_driver_register(&s6000_pcm_driver);
-}
-module_init(snd_s6000_pcm_init);
-
-static void __exit snd_s6000_pcm_exit(void)
-{
-       platform_driver_unregister(&s6000_pcm_driver);
-}
-module_exit(snd_s6000_pcm_exit);
+module_platform_driver(s6000_pcm_driver);
 
 MODULE_AUTHOR("Daniel Gloeckner");
 MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
index 53aaa69eda0365c40a909573d7cbb23901311d75..7aaaf8e8056f7b8acd912fec109089a1b3c940ee 100644 (file)
@@ -198,3 +198,16 @@ config SND_SOC_SPEYSIDE_WM8962
        depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
        select SND_SAMSUNG_I2S
        select SND_SOC_WM8962
+
+config SND_SOC_LOWLAND
+       tristate "Audio support for Wolfson Lowland"
+       depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+       select SND_SAMSUNG_I2S
+       select SND_SOC_WM5100
+       select SND_SOC_WM9081
+
+config SND_SOC_LITTLEMILL
+       tristate "Audio support for Wolfson Littlemill"
+       depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+       select SND_SAMSUNG_I2S
+       select SND_SOC_WM8994
index 8509d3c4366e76178c5cdb0a1a75573b9934b3a7..c9564e3547bbaba2980f6d640e8ba1baa30d9b91 100644 (file)
@@ -40,6 +40,8 @@ snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
 snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o
 snd-soc-speyside-objs := speyside.o
 snd-soc-speyside-wm8962-objs := speyside_wm8962.o
+snd-soc-lowland-objs := lowland.o
+snd-soc-littlemill-objs := littlemill.o
 
 obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
 obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -61,3 +63,5 @@ obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
 obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o
 obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
 obj-$(CONFIG_SND_SOC_SPEYSIDE_WM8962) += snd-soc-speyside-wm8962.o
+obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
+obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
index 16521e3ffc0c5af67712c1cdc1cd3c00e4ad501a..7b9bf93e3701edf92bd47b74d39c8d58de4f690e 100644 (file)
@@ -329,12 +329,12 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static struct snd_soc_dai_ops s3c_ac97_dai_ops = {
+static const struct snd_soc_dai_ops s3c_ac97_dai_ops = {
        .hw_params      = s3c_ac97_hw_params,
        .trigger        = s3c_ac97_trigger,
 };
 
-static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
+static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
        .hw_params      = s3c_ac97_hw_mic_params,
        .trigger        = s3c_ac97_mic_trigger,
 };
@@ -509,17 +509,7 @@ static struct platform_driver s3c_ac97_driver = {
        },
 };
 
-static int __init s3c_ac97_init(void)
-{
-       return platform_driver_register(&s3c_ac97_driver);
-}
-module_init(s3c_ac97_init);
-
-static void __exit s3c_ac97_exit(void)
-{
-       platform_driver_unregister(&s3c_ac97_driver);
-}
-module_exit(s3c_ac97_exit);
+module_platform_driver(s3c_ac97_driver);
 
 MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
 MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
index a68b2644178477dd7fd6a5c0518498e4ff5da860..797c3d5e79e5a71d44fa07b246e0d851bc902d81 100644 (file)
@@ -458,17 +458,7 @@ static struct platform_driver asoc_dma_driver = {
        .remove = __devexit_p(samsung_asoc_platform_remove),
 };
 
-static int __init samsung_asoc_init(void)
-{
-       return platform_driver_register(&asoc_dma_driver);
-}
-module_init(samsung_asoc_init);
-
-static void __exit samsung_asoc_exit(void)
-{
-       platform_driver_unregister(&asoc_dma_driver);
-}
-module_exit(samsung_asoc_exit);
+module_platform_driver(asoc_dma_driver);
 
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
index bff42bf370b9c8849874db4792150fad27328010..fb80f2886c708b6ce4b5d3f8d96fcebdfbf83188 100644 (file)
@@ -923,7 +923,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
        return 0;
 }
 
-static struct snd_soc_dai_ops samsung_i2s_dai_ops = {
+static const struct snd_soc_dai_ops samsung_i2s_dai_ops = {
        .trigger = i2s_trigger,
        .hw_params = i2s_hw_params,
        .set_fmt = i2s_set_fmt,
@@ -1144,17 +1144,7 @@ static struct platform_driver samsung_i2s_driver = {
        },
 };
 
-static int __init samsung_i2s_init(void)
-{
-       return platform_driver_register(&samsung_i2s_driver);
-}
-module_init(samsung_i2s_init);
-
-static void __exit samsung_i2s_exit(void)
-{
-       platform_driver_unregister(&samsung_i2s_driver);
-}
-module_exit(samsung_i2s_exit);
+module_platform_driver(samsung_i2s_driver);
 
 /* Module information */
 MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
index c41178efc9084b7c5fe3712bbb2e885f527bded5..6ca3d8c221a0efe67a221f5553b9195974b18e2e 100644 (file)
@@ -437,17 +437,7 @@ static struct platform_driver asoc_idma_driver = {
        .remove = __devexit_p(asoc_idma_platform_remove),
 };
 
-static int __init asoc_idma_init(void)
-{
-       return platform_driver_register(&asoc_idma_driver);
-}
-module_init(asoc_idma_init);
-
-static void __exit asoc_idma_exit(void)
-{
-       platform_driver_unregister(&asoc_idma_driver);
-}
-module_exit(asoc_idma_exit);
+module_platform_driver(asoc_idma_driver);
 
 MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
 MODULE_DESCRIPTION("Samsung ASoC IDMA Driver");
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
new file mode 100644 (file)
index 0000000..d2a44ab
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Littlemill audio support
+ *
+ * Copyright 2011 Wolfson Microelectronics
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include "../codecs/wm8994.h"
+
+static int sample_rate = 44100;
+
+static int littlemill_set_bias_level(struct snd_soc_card *card,
+                                         struct snd_soc_dapm_context *dapm,
+                                         enum snd_soc_bias_level level)
+{
+       struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+       int ret;
+
+       if (dapm->dev != codec_dai->dev)
+               return 0;
+
+       switch (level) {
+       case SND_SOC_BIAS_PREPARE:
+               /*
+                * If we've not already clocked things via hw_params()
+                * then do so now, otherwise these are noops.
+                */
+               if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
+                       ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+                                                 WM8994_FLL_SRC_MCLK2, 32768,
+                                                 sample_rate * 512);
+                       if (ret < 0) {
+                               pr_err("Failed to start FLL: %d\n", ret);
+                               return ret;
+                       }
+
+                       ret = snd_soc_dai_set_sysclk(codec_dai,
+                                                    WM8994_SYSCLK_FLL1,
+                                                    sample_rate * 512,
+                                                    SND_SOC_CLOCK_IN);
+                       if (ret < 0) {
+                               pr_err("Failed to set SYSCLK: %d\n", ret);
+                               return ret;
+                       }
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int littlemill_set_bias_level_post(struct snd_soc_card *card,
+                                              struct snd_soc_dapm_context *dapm,
+                                              enum snd_soc_bias_level level)
+{
+       struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+       int ret;
+
+       if (dapm->dev != codec_dai->dev)
+               return 0;
+
+       switch (level) {
+       case SND_SOC_BIAS_STANDBY:
+               ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2,
+                                            32768, SND_SOC_CLOCK_IN);
+               if (ret < 0) {
+                       pr_err("Failed to switch away from FLL: %d\n", ret);
+                       return ret;
+               }
+
+               ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+                                         0, 0, 0);
+               if (ret < 0) {
+                       pr_err("Failed to stop FLL: %d\n", ret);
+                       return ret;
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       dapm->bias_level = level;
+
+       return 0;
+}
+
+static int littlemill_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       int ret;
+
+       sample_rate = params_rate(params);
+
+       ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1,
+                                 WM8994_FLL_SRC_MCLK2, 32768,
+                                 sample_rate * 512);
+       if (ret < 0) {
+               pr_err("Failed to start FLL: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(codec_dai,
+                                    WM8994_SYSCLK_FLL1,
+                                    sample_rate * 512,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               pr_err("Failed to set SYSCLK: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops littlemill_ops = {
+       .hw_params = littlemill_hw_params,
+};
+
+static struct snd_soc_dai_link littlemill_dai[] = {
+       {
+               .name = "CPU",
+               .stream_name = "CPU",
+               .cpu_dai_name = "samsung-i2s.0",
+               .codec_dai_name = "wm8994-aif1",
+               .platform_name = "samsung-audio",
+               .codec_name = "wm8994-codec",
+               .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+                               | SND_SOC_DAIFMT_CBM_CFM,
+               .ops = &littlemill_ops,
+       },
+};
+
+static struct snd_soc_dapm_widget widgets[] = {
+       SND_SOC_DAPM_HP("Headphone", NULL),
+};
+
+static struct snd_soc_dapm_route audio_paths[] = {
+       { "Headphone", NULL, "HPOUT1L" },
+       { "Headphone", NULL, "HPOUT1R" },
+};
+
+static int littlemill_late_probe(struct snd_soc_card *card)
+{
+       struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+       int ret;
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2,
+                                    32768, SND_SOC_CLOCK_IN);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_card littlemill = {
+       .name = "Littlemill",
+       .dai_link = littlemill_dai,
+       .num_links = ARRAY_SIZE(littlemill_dai),
+
+       .set_bias_level = littlemill_set_bias_level,
+       .set_bias_level_post = littlemill_set_bias_level_post,
+
+       .dapm_widgets = widgets,
+       .num_dapm_widgets = ARRAY_SIZE(widgets),
+       .dapm_routes = audio_paths,
+       .num_dapm_routes = ARRAY_SIZE(audio_paths),
+
+       .late_probe = littlemill_late_probe,
+};
+
+static __devinit int littlemill_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &littlemill;
+       int ret;
+
+       card->dev = &pdev->dev;
+
+       ret = snd_soc_register_card(card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int __devexit littlemill_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+       snd_soc_unregister_card(card);
+
+       return 0;
+}
+
+static struct platform_driver littlemill_driver = {
+       .driver = {
+               .name = "littlemill",
+               .owner = THIS_MODULE,
+               .pm = &snd_soc_pm_ops,
+       },
+       .probe = littlemill_probe,
+       .remove = __devexit_p(littlemill_remove),
+};
+
+module_platform_driver(littlemill_driver);
+
+MODULE_DESCRIPTION("Littlemill audio support");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:littlemill");
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c
new file mode 100644 (file)
index 0000000..4216a06
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Lowland audio support
+ *
+ * Copyright 2011 Wolfson Microelectronics
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include "../codecs/wm5100.h"
+#include "../codecs/wm9081.h"
+
+#define MCLK1_RATE (44100 * 512)
+#define CLKOUT_RATE (44100 * 256)
+
+static int lowland_hw_params(struct snd_pcm_substream *substream,
+                            struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       int ret;
+
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+                                        | SND_SOC_DAIFMT_NB_NF
+                                        | SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
+                                        | SND_SOC_DAIFMT_NB_NF
+                                        | SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_ops lowland_ops = {
+       .hw_params = lowland_hw_params,
+};
+
+static struct snd_soc_jack lowland_headset;
+
+/* Headset jack detection DAPM pins */
+static struct snd_soc_jack_pin lowland_headset_pins[] = {
+       {
+               .pin = "Headphone",
+               .mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
+       },
+       {
+               .pin = "Headset Mic",
+               .mask = SND_JACK_MICROPHONE,
+       },
+};
+
+static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_codec *codec = rtd->codec;
+       int ret;
+
+       ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_SYSCLK,
+                                      WM5100_CLKSRC_MCLK1, MCLK1_RATE,
+                                      SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               pr_err("Failed to set SYSCLK clock source: %d\n", ret);
+               return ret;
+       }
+
+       /* Clock OPCLK, used by the other audio components. */
+       ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_OPCLK, 0,
+                                      CLKOUT_RATE, 0);
+       if (ret < 0) {
+               pr_err("Failed to set OPCLK rate: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_jack_new(codec, "Headset",
+                              SND_JACK_LINEOUT | SND_JACK_HEADSET |
+                              SND_JACK_BTN_0,
+                              &lowland_headset);
+       if (ret)
+               return ret;
+
+       ret = snd_soc_jack_add_pins(&lowland_headset,
+                                   ARRAY_SIZE(lowland_headset_pins),
+                                   lowland_headset_pins);
+       if (ret)
+               return ret;
+
+       wm5100_detect(codec, &lowland_headset);
+
+       return 0;
+}
+
+static struct snd_soc_dai_link lowland_dai[] = {
+       {
+               .name = "CPU",
+               .stream_name = "CPU",
+               .cpu_dai_name = "samsung-i2s.0",
+               .codec_dai_name = "wm5100-aif1",
+               .platform_name = "samsung-audio",
+               .codec_name = "wm5100.1-001a",
+               .ops = &lowland_ops,
+               .init = lowland_wm5100_init,
+       },
+       {
+               .name = "Baseband",
+               .stream_name = "Baseband",
+               .cpu_dai_name = "wm5100-aif2",
+               .codec_dai_name = "wm1250-ev1",
+               .codec_name = "wm1250-ev1.1-0027",
+               .ops = &lowland_ops,
+               .ignore_suspend = 1,
+       },
+};
+
+static int lowland_wm9081_init(struct snd_soc_dapm_context *dapm)
+{
+       snd_soc_dapm_nc_pin(dapm, "LINEOUT");
+
+       /* At any time the WM9081 is active it will have this clock */
+       return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
+                                       CLKOUT_RATE, 0);
+}
+
+static struct snd_soc_aux_dev lowland_aux_dev[] = {
+       {
+               .name = "wm9081",
+               .codec_name = "wm9081.1-006c",
+               .init = lowland_wm9081_init,
+       },
+};
+
+static struct snd_soc_codec_conf lowland_codec_conf[] = {
+       {
+               .dev_name = "wm9081.1-006c",
+               .name_prefix = "Sub",
+       },
+};
+
+static const struct snd_kcontrol_new controls[] = {
+       SOC_DAPM_PIN_SWITCH("Main Speaker"),
+       SOC_DAPM_PIN_SWITCH("Main DMIC"),
+       SOC_DAPM_PIN_SWITCH("Main AMIC"),
+       SOC_DAPM_PIN_SWITCH("WM1250 Input"),
+       SOC_DAPM_PIN_SWITCH("WM1250 Output"),
+       SOC_DAPM_PIN_SWITCH("Headphone"),
+};
+
+static struct snd_soc_dapm_widget widgets[] = {
+       SND_SOC_DAPM_HP("Headphone", NULL),
+       SND_SOC_DAPM_MIC("Headset Mic", NULL),
+
+       SND_SOC_DAPM_SPK("Main Speaker", NULL),
+
+       SND_SOC_DAPM_MIC("Main AMIC", NULL),
+       SND_SOC_DAPM_MIC("Main DMIC", NULL),
+};
+
+static struct snd_soc_dapm_route audio_paths[] = {
+       { "Sub IN1", NULL, "HPOUT2L" },
+       { "Sub IN2", NULL, "HPOUT2R" },
+
+       { "Main Speaker", NULL, "Sub SPKN" },
+       { "Main Speaker", NULL, "Sub SPKP" },
+       { "Main Speaker", NULL, "SPKDAT1" },
+};
+
+static struct snd_soc_card lowland = {
+       .name = "Lowland",
+       .dai_link = lowland_dai,
+       .num_links = ARRAY_SIZE(lowland_dai),
+       .aux_dev = lowland_aux_dev,
+       .num_aux_devs = ARRAY_SIZE(lowland_aux_dev),
+       .codec_conf = lowland_codec_conf,
+       .num_configs = ARRAY_SIZE(lowland_codec_conf),
+
+       .controls = controls,
+       .num_controls = ARRAY_SIZE(controls),
+       .dapm_widgets = widgets,
+       .num_dapm_widgets = ARRAY_SIZE(widgets),
+       .dapm_routes = audio_paths,
+       .num_dapm_routes = ARRAY_SIZE(audio_paths),
+};
+
+static __devinit int lowland_probe(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = &lowland;
+       int ret;
+
+       card->dev = &pdev->dev;
+
+       ret = snd_soc_register_card(card);
+       if (ret) {
+               dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+                       ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int __devexit lowland_remove(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+       snd_soc_unregister_card(card);
+
+       return 0;
+}
+
+static struct platform_driver lowland_driver = {
+       .driver = {
+               .name = "lowland",
+               .owner = THIS_MODULE,
+               .pm = &snd_soc_pm_ops,
+       },
+       .probe = lowland_probe,
+       .remove = __devexit_p(lowland_remove),
+};
+
+module_platform_driver(lowland_driver);
+
+MODULE_DESCRIPTION("Lowland audio support");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lowland");
index 05a47cf7f06e9345285fe57d7d1688049c7c23ea..beef63fca052bc8f66595e764b8bc6bafb84e579 100644 (file)
@@ -452,7 +452,7 @@ static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai,
        return 0;
 }
 
-static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
+static const struct snd_soc_dai_ops s3c_pcm_dai_ops = {
        .set_sysclk     = s3c_pcm_set_sysclk,
        .set_clkdiv     = s3c_pcm_set_clkdiv,
        .trigger        = s3c_pcm_trigger,
@@ -632,17 +632,7 @@ static struct platform_driver s3c_pcm_driver = {
        },
 };
 
-static int __init s3c_pcm_init(void)
-{
-       return platform_driver_register(&s3c_pcm_driver);
-}
-module_init(s3c_pcm_init);
-
-static void __exit s3c_pcm_exit(void)
-{
-       platform_driver_unregister(&s3c_pcm_driver);
-}
-module_exit(s3c_pcm_exit);
+module_platform_driver(s3c_pcm_driver);
 
 /* Module information */
 MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
index 7bbec25e6e158b824561da968d91ee811564858a..72185078ddf8ef6f40a78105a6af09a4f33bf1b4 100644 (file)
@@ -142,7 +142,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
        SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
 
-static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
+static const struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
        .hw_params      = s3c2412_i2s_hw_params,
 };
 
@@ -184,17 +184,7 @@ static struct platform_driver s3c2412_iis_driver = {
        },
 };
 
-static int __init s3c2412_i2s_init(void)
-{
-       return platform_driver_register(&s3c2412_iis_driver);
-}
-module_init(s3c2412_i2s_init);
-
-static void __exit s3c2412_i2s_exit(void)
-{
-       platform_driver_unregister(&s3c2412_iis_driver);
-}
-module_exit(s3c2412_i2s_exit);
+module_platform_driver(s3c2412_iis_driver);
 
 /* Module information */
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
index 558c64bbed2e66f0c02d0ecd600605f2bfc1e3fa..c4aa4d412fbf56e94a86b46f3a1775e01d325e1d 100644 (file)
@@ -444,7 +444,7 @@ static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
        SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
 
-static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
        .trigger        = s3c24xx_i2s_trigger,
        .hw_params      = s3c24xx_i2s_hw_params,
        .set_fmt        = s3c24xx_i2s_set_fmt,
@@ -489,17 +489,7 @@ static struct platform_driver s3c24xx_iis_driver = {
        },
 };
 
-static int __init s3c24xx_i2s_init(void)
-{
-       return platform_driver_register(&s3c24xx_iis_driver);
-}
-module_init(s3c24xx_i2s_init);
-
-static void __exit s3c24xx_i2s_exit(void)
-{
-       platform_driver_unregister(&s3c24xx_iis_driver);
-}
-module_exit(s3c24xx_i2s_exit);
+module_platform_driver(s3c24xx_iis_driver);
 
 /* Module information */
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
index d125e79baf7f4bd74e2773402312d88183b1dc00..502798100f2196e79e26e99657da78b50279de13 100644 (file)
@@ -114,21 +114,9 @@ static struct platform_driver simtec_audio_hermes_platdrv = {
        .remove = __devexit_p(simtec_audio_remove),
 };
 
-MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd");
-
-static int __init simtec_hermes_modinit(void)
-{
-       return platform_driver_register(&simtec_audio_hermes_platdrv);
-}
-
-static void __exit simtec_hermes_modexit(void)
-{
-       platform_driver_unregister(&simtec_audio_hermes_platdrv);
-}
-
-module_init(simtec_hermes_modinit);
-module_exit(simtec_hermes_modexit);
+module_platform_driver(simtec_audio_hermes_platdrv);
 
+MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
 MODULE_LICENSE("GPL");
index 5e4fd46b7200066d917e5f0a8e00fe9ffa328394..7324609833d803341b646339881b5004ca7135e0 100644 (file)
@@ -102,21 +102,9 @@ static struct platform_driver simtec_audio_tlv320aic23_platdrv = {
        .remove = __devexit_p(simtec_audio_remove),
 };
 
-MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23");
-
-static int __init simtec_tlv320aic23_modinit(void)
-{
-       return platform_driver_register(&simtec_audio_tlv320aic23_platdrv);
-}
-
-static void __exit simtec_tlv320aic23_modexit(void)
-{
-       platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv);
-}
-
-module_init(simtec_tlv320aic23_modinit);
-module_exit(simtec_tlv320aic23_modexit);
+module_platform_driver(simtec_audio_tlv320aic32_driver);
 
+MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
 MODULE_LICENSE("GPL");
index 548c6ac6e7b06bdc5e9da816836a6bf3a90b7b6a..62b69fb6a08518821a7848c73c1035e325a20017 100644 (file)
@@ -343,19 +343,7 @@ static struct platform_driver s3c24xx_uda134x_driver = {
        },
 };
 
-static int __init s3c24xx_uda134x_init(void)
-{
-       return platform_driver_register(&s3c24xx_uda134x_driver);
-}
-
-static void __exit s3c24xx_uda134x_exit(void)
-{
-       platform_driver_unregister(&s3c24xx_uda134x_driver);
-}
-
-
-module_init(s3c24xx_uda134x_init);
-module_exit(s3c24xx_uda134x_exit);
+module_platform_driver(s3c24xx_uda134x_driver);
 
 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
 MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
index 0677473e6b608ef5df677214258c87680687e640..49dfafbf3df6d6302537222a6695d62398023df9 100644 (file)
@@ -188,19 +188,7 @@ static struct platform_driver snd_smdk_driver = {
        .remove = __devexit_p(snd_smdk_remove),
 };
 
-static int __init smdk_audio_init(void)
-{
-       return platform_driver_register(&snd_smdk_driver);
-}
-
-module_init(smdk_audio_init);
-
-static void __exit smdk_audio_exit(void)
-{
-       platform_driver_unregister(&snd_smdk_driver);
-}
-
-module_exit(smdk_audio_exit);
+module_platform_driver(snd_smdk_driver);
 
 MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
 MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
index 468cff1bb1af62b24372a4abcb6a9d9ad4536c78..a5a56a12034554255cbe520313268ab617eef292 100644 (file)
@@ -334,7 +334,7 @@ static int spdif_resume(struct snd_soc_dai *cpu_dai)
 #define spdif_resume NULL
 #endif
 
-static struct snd_soc_dai_ops spdif_dai_ops = {
+static const struct snd_soc_dai_ops spdif_dai_ops = {
        .set_sysclk     = spdif_set_sysclk,
        .trigger        = spdif_trigger,
        .hw_params      = spdif_hw_params,
@@ -483,17 +483,7 @@ static struct platform_driver samsung_spdif_driver = {
        },
 };
 
-static int __init spdif_init(void)
-{
-       return platform_driver_register(&samsung_spdif_driver);
-}
-module_init(spdif_init);
-
-static void __exit spdif_exit(void)
-{
-       platform_driver_unregister(&samsung_spdif_driver);
-}
-module_exit(spdif_exit);
+module_platform_driver(samsung_spdif_driver);
 
 MODULE_AUTHOR("Seungwhan Youn, <sw.youn@samsung.com>");
 MODULE_DESCRIPTION("Samsung S/PDIF Controller Driver");
index 4b8e35410eb1962623cc31882967397747e5b3e7..18e6356e86db57f9383c68c1f79a5ff69efe770c 100644 (file)
@@ -222,8 +222,6 @@ static struct snd_soc_dai_link speyside_dai[] = {
 
 static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
 {
-       snd_soc_dapm_nc_pin(dapm, "LINEOUT");
-
        /* At any time the WM9081 is active it will have this clock */
        return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
                                        48000 * 256, 0);
@@ -308,6 +306,7 @@ static struct snd_soc_card speyside = {
        .num_dapm_widgets = ARRAY_SIZE(widgets),
        .dapm_routes = audio_paths,
        .num_dapm_routes = ARRAY_SIZE(audio_paths),
+       .fully_routed = true,
 
        .late_probe = speyside_late_probe,
 };
@@ -348,17 +347,7 @@ static struct platform_driver speyside_driver = {
        .remove = __devexit_p(speyside_remove),
 };
 
-static int __init speyside_audio_init(void)
-{
-       return platform_driver_register(&speyside_driver);
-}
-module_init(speyside_audio_init);
-
-static void __exit speyside_audio_exit(void)
-{
-       platform_driver_unregister(&speyside_driver);
-}
-module_exit(speyside_audio_exit);
+module_platform_driver(speyside_driver);
 
 MODULE_DESCRIPTION("Speyside audio support");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
index e3e27166cc508e5caf9b054832b0a132d6ed3fe3..c09648efab614e4f246824515cfad482de410987 100644 (file)
@@ -208,6 +208,7 @@ static struct snd_soc_card speyside_wm8962 = {
        .num_dapm_widgets = ARRAY_SIZE(widgets),
        .dapm_routes = audio_paths,
        .num_dapm_routes = ARRAY_SIZE(audio_paths),
+       .fully_routed = true,
 
        .late_probe = speyside_wm8962_late_probe,
 };
@@ -248,17 +249,7 @@ static struct platform_driver speyside_wm8962_driver = {
        .remove = __devexit_p(speyside_wm8962_remove),
 };
 
-static int __init speyside_wm8962_audio_init(void)
-{
-       return platform_driver_register(&speyside_wm8962_driver);
-}
-module_init(speyside_wm8962_audio_init);
-
-static void __exit speyside_wm8962_audio_exit(void)
-{
-       platform_driver_unregister(&speyside_wm8962_driver);
-}
-module_exit(speyside_wm8962_audio_exit);
+module_platform_driver(speyside_wm8962_driver);
 
 MODULE_DESCRIPTION("Speyside WM8962 audio support");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
index db74005f37ce78b69d7dffd873d4bc82775e8a64..7da20186b19e63bdf7efe6372a33b41190e82a2f 100644 (file)
@@ -369,17 +369,7 @@ static struct platform_driver sh7760_pcm_driver = {
        .remove = __devexit_p(sh7760_soc_platform_remove),
 };
 
-static int __init snd_sh7760_pcm_init(void)
-{
-       return platform_driver_register(&sh7760_pcm_driver);
-}
-module_init(snd_sh7760_pcm_init);
-
-static void __exit snd_sh7760_pcm_exit(void)
-{
-       platform_driver_unregister(&sh7760_pcm_driver);
-}
-module_exit(snd_sh7760_pcm_exit);
+module_platform_driver(sh7760_pcm_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
index dff64b95f5dcf11671c282f850ea83af520c365b..eb52778d0f90c81bfd81cdf0c6edd7a5151215be 100644 (file)
@@ -58,27 +58,23 @@ static struct platform_device *fsi_snd_device;
 static int fsi_ak4642_probe(struct platform_device *pdev)
 {
        int ret = -ENOMEM;
-       const struct platform_device_id *id_entry;
-       struct fsi_ak4642_data *pdata;
+       struct fsi_ak4642_info *pinfo = pdev->dev.platform_data;
 
-       id_entry = pdev->id_entry;
-       if (!id_entry) {
-               dev_err(&pdev->dev, "unknown fsi ak4642\n");
-               return -ENODEV;
+       if (!pinfo) {
+               dev_err(&pdev->dev, "no info for fsi ak4642\n");
+               goto out;
        }
 
-       pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
-
-       fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
+       fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id);
        if (!fsi_snd_device)
                goto out;
 
-       fsi_dai_link.name               = pdata->name;
-       fsi_dai_link.stream_name        = pdata->name;
-       fsi_dai_link.cpu_dai_name       = pdata->cpu_dai;
-       fsi_dai_link.platform_name      = pdata->platform;
-       fsi_dai_link.codec_name         = pdata->codec;
-       fsi_soc_card.name               = pdata->card;
+       fsi_dai_link.name               = pinfo->name;
+       fsi_dai_link.stream_name        = pinfo->name;
+       fsi_dai_link.cpu_dai_name       = pinfo->cpu_dai;
+       fsi_dai_link.platform_name      = pinfo->platform;
+       fsi_dai_link.codec_name         = pinfo->codec;
+       fsi_soc_card.name               = pinfo->card;
 
        platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
        ret = platform_device_add(fsi_snd_device);
@@ -96,114 +92,15 @@ static int fsi_ak4642_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct fsi_ak4642_data fsi_a_ak4642 = {
-       .name           = "AK4642",
-       .card           = "FSIA-AK4642",
-       .cpu_dai        = "fsia-dai",
-       .codec          = "ak4642-codec.0-0012",
-       .platform       = "sh_fsi.0",
-       .id             = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi_b_ak4642 = {
-       .name           = "AK4642",
-       .card           = "FSIB-AK4642",
-       .cpu_dai        = "fsib-dai",
-       .codec          = "ak4642-codec.0-0012",
-       .platform       = "sh_fsi.0",
-       .id             = FSI_PORT_B,
-};
-
-static struct fsi_ak4642_data fsi_a_ak4643 = {
-       .name           = "AK4643",
-       .card           = "FSIA-AK4643",
-       .cpu_dai        = "fsia-dai",
-       .codec          = "ak4642-codec.0-0013",
-       .platform       = "sh_fsi.0",
-       .id             = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi_b_ak4643 = {
-       .name           = "AK4643",
-       .card           = "FSIB-AK4643",
-       .cpu_dai        = "fsib-dai",
-       .codec          = "ak4642-codec.0-0013",
-       .platform       = "sh_fsi.0",
-       .id             = FSI_PORT_B,
-};
-
-static struct fsi_ak4642_data fsi2_a_ak4642 = {
-       .name           = "AK4642",
-       .card           = "FSI2A-AK4642",
-       .cpu_dai        = "fsia-dai",
-       .codec          = "ak4642-codec.0-0012",
-       .platform       = "sh_fsi2",
-       .id             = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi2_b_ak4642 = {
-       .name           = "AK4642",
-       .card           = "FSI2B-AK4642",
-       .cpu_dai        = "fsib-dai",
-       .codec          = "ak4642-codec.0-0012",
-       .platform       = "sh_fsi2",
-       .id             = FSI_PORT_B,
-};
-
-static struct fsi_ak4642_data fsi2_a_ak4643 = {
-       .name           = "AK4643",
-       .card           = "FSI2A-AK4643",
-       .cpu_dai        = "fsia-dai",
-       .codec          = "ak4642-codec.0-0013",
-       .platform       = "sh_fsi2",
-       .id             = FSI_PORT_A,
-};
-
-static struct fsi_ak4642_data fsi2_b_ak4643 = {
-       .name           = "AK4643",
-       .card           = "FSI2B-AK4643",
-       .cpu_dai        = "fsib-dai",
-       .codec          = "ak4642-codec.0-0013",
-       .platform       = "sh_fsi2",
-       .id             = FSI_PORT_B,
-};
-
-static struct platform_device_id fsi_id_table[] = {
-       /* FSI */
-       { "sh_fsi_a_ak4642",    (kernel_ulong_t)&fsi_a_ak4642 },
-       { "sh_fsi_b_ak4642",    (kernel_ulong_t)&fsi_b_ak4642 },
-       { "sh_fsi_a_ak4643",    (kernel_ulong_t)&fsi_a_ak4643 },
-       { "sh_fsi_b_ak4643",    (kernel_ulong_t)&fsi_b_ak4643 },
-
-       /* FSI 2 */
-       { "sh_fsi2_a_ak4642",   (kernel_ulong_t)&fsi2_a_ak4642 },
-       { "sh_fsi2_b_ak4642",   (kernel_ulong_t)&fsi2_b_ak4642 },
-       { "sh_fsi2_a_ak4643",   (kernel_ulong_t)&fsi2_a_ak4643 },
-       { "sh_fsi2_b_ak4643",   (kernel_ulong_t)&fsi2_b_ak4643 },
-       {},
-};
-
 static struct platform_driver fsi_ak4642 = {
        .driver = {
                .name   = "fsi-ak4642-audio",
        },
        .probe          = fsi_ak4642_probe,
        .remove         = fsi_ak4642_remove,
-       .id_table       = fsi_id_table,
 };
 
-static int __init fsi_ak4642_init(void)
-{
-       return platform_driver_register(&fsi_ak4642);
-}
-
-static void __exit fsi_ak4642_exit(void)
-{
-       platform_driver_unregister(&fsi_ak4642);
-}
-
-module_init(fsi_ak4642_init);
-module_exit(fsi_ak4642_exit);
+module_platform_driver(fsi_ak4642);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
index 3ebebe706ad3bf732114cfd06ede04cf412b183d..621aea155ac1a27a7ad9f62478c5fbfee205215b 100644 (file)
@@ -110,18 +110,7 @@ static struct platform_driver fsi_hdmi = {
        .id_table       = fsi_id_table,
 };
 
-static int __init fsi_hdmi_init(void)
-{
-       return platform_driver_register(&fsi_hdmi);
-}
-
-static void __exit fsi_hdmi_exit(void)
-{
-       platform_driver_unregister(&fsi_hdmi);
-}
-
-module_init(fsi_hdmi_init);
-module_exit(fsi_hdmi_exit);
+module_platform_driver(fsi_hdmi);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
index 3d7016e128f9374d2febb9564f404ed02db6b4db..a27c30636b824d5d9289e4a4367fe4cf1e23f556 100644 (file)
@@ -32,7 +32,9 @@
 #define REG_DIDT       0x0020
 #define REG_DODT       0x0024
 #define REG_MUTE_ST    0x0028
+#define REG_OUT_DMAC   0x002C
 #define REG_OUT_SEL    0x0030
+#define REG_IN_DMAC    0x0038
 
 /* master register */
 #define MST_CLK_RST    0x0210
@@ -235,13 +237,13 @@ static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
 }
 
 #define fsi_reg_write(p, r, d)\
-       __fsi_reg_write((u32)(p->base + REG_##r), d)
+       __fsi_reg_write((p->base + REG_##r), d)
 
 #define fsi_reg_read(p, r)\
-       __fsi_reg_read((u32)(p->base + REG_##r))
+       __fsi_reg_read((p->base + REG_##r))
 
 #define fsi_reg_mask_set(p, r, m, d)\
-       __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
+       __fsi_reg_mask_set((p->base + REG_##r), m, d)
 
 #define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
 #define fsi_core_read(p, r)   _fsi_master_read(p, p->core->r)
@@ -886,6 +888,8 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
                          int is_play,
                          struct device *dev)
 {
+       struct fsi_master *master = fsi_get_master(fsi);
+       int fsi_ver = master->core->ver;
        u32 flags = fsi_get_info_flags(fsi);
        u32 data = 0;
 
@@ -920,6 +924,17 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
                fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
        }
 
+       /*
+        * FIXME
+        *
+        * FSI driver assumed that data package is in-back.
+        * FSI2 chip can select it.
+        */
+       if (fsi_ver >= 2) {
+               fsi_reg_write(fsi, OUT_DMAC,    (1 << 4));
+               fsi_reg_write(fsi, IN_DMAC,     (1 << 4));
+       }
+
        /* irq clear */
        fsi_irq_disable(fsi, is_play);
        fsi_irq_clear_status(fsi);
@@ -1081,7 +1096,7 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
        return ret;
 }
 
-static struct snd_soc_dai_ops fsi_dai_ops = {
+static const struct snd_soc_dai_ops fsi_dai_ops = {
        .startup        = fsi_dai_startup,
        .shutdown       = fsi_dai_shutdown,
        .trigger        = fsi_dai_trigger,
@@ -1453,18 +1468,7 @@ static struct platform_driver fsi_driver = {
        .id_table       = fsi_id_table,
 };
 
-static int __init fsi_mobile_init(void)
-{
-       return platform_driver_register(&fsi_driver);
-}
-
-static void __exit fsi_mobile_exit(void)
-{
-       platform_driver_unregister(&fsi_driver);
-}
-
-module_init(fsi_mobile_init);
-module_exit(fsi_mobile_exit);
+module_platform_driver(fsi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
index c87e3ff28a0a02957bbd37c2de21d96b661e569e..3474d7befe5ae537fc6e9862050f5e81dcce9daa 100644 (file)
@@ -266,7 +266,7 @@ static int hac_hw_params(struct snd_pcm_substream *substream,
 #define AC97_FMTS      \
        SNDRV_PCM_FMTBIT_S16_LE
 
-static struct snd_soc_dai_ops hac_dai_ops = {
+static const struct snd_soc_dai_ops hac_dai_ops = {
        .hw_params      = hac_hw_params,
 };
 
@@ -332,17 +332,7 @@ static struct platform_driver hac_pcm_driver = {
        .remove = __devexit_p(hac_soc_platform_remove),
 };
 
-static int __init sh4_hac_pcm_init(void)
-{
-       return platform_driver_register(&hac_pcm_driver);
-}
-module_init(sh4_hac_pcm_init);
-
-static void __exit sh4_hac_pcm_exit(void)
-{
-       platform_driver_unregister(&hac_pcm_driver);
-}
-module_exit(sh4_hac_pcm_exit);
+module_platform_driver(hac_pcm_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
index edacfeb13b94e3956589a999aeb78de2e2815635..11c608570820734f30eafd31d2bba8525f6a7e38 100644 (file)
@@ -707,7 +707,7 @@ epclkget:
        return ret;
 }
 
-static struct snd_soc_dai_ops siu_dai_ops = {
+static const struct snd_soc_dai_ops siu_dai_ops = {
        .startup        = siu_dai_startup,
        .shutdown       = siu_dai_shutdown,
        .prepare        = siu_dai_prepare,
@@ -852,18 +852,7 @@ static struct platform_driver siu_driver = {
        .remove         = __devexit_p(siu_remove),
 };
 
-static int __init siu_init(void)
-{
-       return platform_driver_register(&siu_driver);
-}
-
-static void __exit siu_exit(void)
-{
-       platform_driver_unregister(&siu_driver);
-}
-
-module_init(siu_init)
-module_exit(siu_exit)
+module_platform_driver(siu_driver);
 
 MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
 MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
index e0c621c0553b5606afab9530628c94b994f9e847..ff82b56a886093e43c5456b14592452478d5d4a2 100644 (file)
@@ -332,7 +332,7 @@ static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
         SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE |  \
         SNDRV_PCM_FMTBIT_S32_LE  | SNDRV_PCM_FMTBIT_U32_LE)
 
-static struct snd_soc_dai_ops ssi_dai_ops = {
+static const struct snd_soc_dai_ops ssi_dai_ops = {
        .startup        = ssi_startup,
        .shutdown       = ssi_shutdown,
        .trigger        = ssi_trigger,
@@ -401,17 +401,7 @@ static struct platform_driver sh4_ssi_driver = {
        .remove = __devexit_p(sh4_soc_dai_remove),
 };
 
-static int __init snd_sh4_ssi_init(void)
-{
-       return platform_driver_register(&sh4_ssi_driver);
-}
-module_init(snd_sh4_ssi_init);
-
-static void __exit snd_sh4_ssi_exit(void)
-{
-       platform_driver_unregister(&sh4_ssi_driver);
-}
-module_exit(snd_sh4_ssi_exit);
+module_platform_driver(sh4_ssi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
index 9077aa4b3b4ed975da4430789ff3961810e8df0e..18bb6b3335e0424ad5a9830d466c930dc8560fcc 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <sound/soc.h>
-#include <linux/lzo.h>
 #include <linux/bitmap.h>
 #include <linux/rbtree.h>
 #include <linux/export.h>
@@ -439,378 +438,6 @@ err:
        return ret;
 }
 
-#ifdef CONFIG_SND_SOC_CACHE_LZO
-struct snd_soc_lzo_ctx {
-       void *wmem;
-       void *dst;
-       const void *src;
-       size_t src_len;
-       size_t dst_len;
-       size_t decompressed_size;
-       unsigned long *sync_bmp;
-       int sync_bmp_nbits;
-};
-
-#define LZO_BLOCK_NUM 8
-static int snd_soc_lzo_block_count(void)
-{
-       return LZO_BLOCK_NUM;
-}
-
-static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
-{
-       lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
-       if (!lzo_ctx->wmem)
-               return -ENOMEM;
-       return 0;
-}
-
-static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
-{
-       size_t compress_size;
-       int ret;
-
-       ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
-                              lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
-       if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
-               return -EINVAL;
-       lzo_ctx->dst_len = compress_size;
-       return 0;
-}
-
-static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
-{
-       size_t dst_len;
-       int ret;
-
-       dst_len = lzo_ctx->dst_len;
-       ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
-                                   lzo_ctx->dst, &dst_len);
-       if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
-               return -EINVAL;
-       return 0;
-}
-
-static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
-               struct snd_soc_lzo_ctx *lzo_ctx)
-{
-       int ret;
-
-       lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
-       lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
-       if (!lzo_ctx->dst) {
-               lzo_ctx->dst_len = 0;
-               return -ENOMEM;
-       }
-
-       ret = snd_soc_lzo_compress(lzo_ctx);
-       if (ret < 0)
-               return ret;
-       return 0;
-}
-
-static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
-               struct snd_soc_lzo_ctx *lzo_ctx)
-{
-       int ret;
-
-       lzo_ctx->dst_len = lzo_ctx->decompressed_size;
-       lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
-       if (!lzo_ctx->dst) {
-               lzo_ctx->dst_len = 0;
-               return -ENOMEM;
-       }
-
-       ret = snd_soc_lzo_decompress(lzo_ctx);
-       if (ret < 0)
-               return ret;
-       return 0;
-}
-
-static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
-               unsigned int reg)
-{
-       const struct snd_soc_codec_driver *codec_drv;
-
-       codec_drv = codec->driver;
-       return (reg * codec_drv->reg_word_size) /
-              DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
-}
-
-static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
-               unsigned int reg)
-{
-       const struct snd_soc_codec_driver *codec_drv;
-
-       codec_drv = codec->driver;
-       return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) /
-                     codec_drv->reg_word_size);
-}
-
-static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
-{
-       return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count());
-}
-
-static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
-{
-       struct snd_soc_lzo_ctx **lzo_blocks;
-       unsigned int val;
-       int i;
-       int ret;
-
-       lzo_blocks = codec->reg_cache;
-       for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
-               WARN_ON(!snd_soc_codec_writable_register(codec, i));
-               ret = snd_soc_cache_read(codec, i, &val);
-               if (ret)
-                       return ret;
-               codec->cache_bypass = 1;
-               ret = snd_soc_write(codec, i, val);
-               codec->cache_bypass = 0;
-               if (ret)
-                       return ret;
-               dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
-                       i, val);
-       }
-
-       return 0;
-}
-
-static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
-                                  unsigned int reg, unsigned int value)
-{
-       struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
-       int ret, blkindex, blkpos;
-       size_t blksize, tmp_dst_len;
-       void *tmp_dst;
-
-       /* index of the compressed lzo block */
-       blkindex = snd_soc_lzo_get_blkindex(codec, reg);
-       /* register index within the decompressed block */
-       blkpos = snd_soc_lzo_get_blkpos(codec, reg);
-       /* size of the compressed block */
-       blksize = snd_soc_lzo_get_blksize(codec);
-       lzo_blocks = codec->reg_cache;
-       lzo_block = lzo_blocks[blkindex];
-
-       /* save the pointer and length of the compressed block */
-       tmp_dst = lzo_block->dst;
-       tmp_dst_len = lzo_block->dst_len;
-
-       /* prepare the source to be the compressed block */
-       lzo_block->src = lzo_block->dst;
-       lzo_block->src_len = lzo_block->dst_len;
-
-       /* decompress the block */
-       ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
-       if (ret < 0) {
-               kfree(lzo_block->dst);
-               goto out;
-       }
-
-       /* write the new value to the cache */
-       if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
-                                 codec->driver->reg_word_size)) {
-               kfree(lzo_block->dst);
-               goto out;
-       }
-
-       /* prepare the source to be the decompressed block */
-       lzo_block->src = lzo_block->dst;
-       lzo_block->src_len = lzo_block->dst_len;
-
-       /* compress the block */
-       ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
-       if (ret < 0) {
-               kfree(lzo_block->dst);
-               kfree(lzo_block->src);
-               goto out;
-       }
-
-       /* set the bit so we know we have to sync this register */
-       set_bit(reg, lzo_block->sync_bmp);
-       kfree(tmp_dst);
-       kfree(lzo_block->src);
-       return 0;
-out:
-       lzo_block->dst = tmp_dst;
-       lzo_block->dst_len = tmp_dst_len;
-       return ret;
-}
-
-static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
-                                 unsigned int reg, unsigned int *value)
-{
-       struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
-       int ret, blkindex, blkpos;
-       size_t blksize, tmp_dst_len;
-       void *tmp_dst;
-
-       *value = 0;
-       /* index of the compressed lzo block */
-       blkindex = snd_soc_lzo_get_blkindex(codec, reg);
-       /* register index within the decompressed block */
-       blkpos = snd_soc_lzo_get_blkpos(codec, reg);
-       /* size of the compressed block */
-       blksize = snd_soc_lzo_get_blksize(codec);
-       lzo_blocks = codec->reg_cache;
-       lzo_block = lzo_blocks[blkindex];
-
-       /* save the pointer and length of the compressed block */
-       tmp_dst = lzo_block->dst;
-       tmp_dst_len = lzo_block->dst_len;
-
-       /* prepare the source to be the compressed block */
-       lzo_block->src = lzo_block->dst;
-       lzo_block->src_len = lzo_block->dst_len;
-
-       /* decompress the block */
-       ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
-       if (ret >= 0)
-               /* fetch the value from the cache */
-               *value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
-                                              codec->driver->reg_word_size);
-
-       kfree(lzo_block->dst);
-       /* restore the pointer and length of the compressed block */
-       lzo_block->dst = tmp_dst;
-       lzo_block->dst_len = tmp_dst_len;
-       return 0;
-}
-
-static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
-{
-       struct snd_soc_lzo_ctx **lzo_blocks;
-       int i, blkcount;
-
-       lzo_blocks = codec->reg_cache;
-       if (!lzo_blocks)
-               return 0;
-
-       blkcount = snd_soc_lzo_block_count();
-       /*
-        * the pointer to the bitmap used for syncing the cache
-        * is shared amongst all lzo_blocks.  Ensure it is freed
-        * only once.
-        */
-       if (lzo_blocks[0])
-               kfree(lzo_blocks[0]->sync_bmp);
-       for (i = 0; i < blkcount; ++i) {
-               if (lzo_blocks[i]) {
-                       kfree(lzo_blocks[i]->wmem);
-                       kfree(lzo_blocks[i]->dst);
-               }
-               /* each lzo_block is a pointer returned by kmalloc or NULL */
-               kfree(lzo_blocks[i]);
-       }
-       kfree(lzo_blocks);
-       codec->reg_cache = NULL;
-       return 0;
-}
-
-static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
-{
-       struct snd_soc_lzo_ctx **lzo_blocks;
-       size_t bmp_size;
-       const struct snd_soc_codec_driver *codec_drv;
-       int ret, tofree, i, blksize, blkcount;
-       const char *p, *end;
-       unsigned long *sync_bmp;
-
-       ret = 0;
-       codec_drv = codec->driver;
-
-       /*
-        * If we have not been given a default register cache
-        * then allocate a dummy zero-ed out region, compress it
-        * and remember to free it afterwards.
-        */
-       tofree = 0;
-       if (!codec->reg_def_copy)
-               tofree = 1;
-
-       if (!codec->reg_def_copy) {
-               codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL);
-               if (!codec->reg_def_copy)
-                       return -ENOMEM;
-       }
-
-       blkcount = snd_soc_lzo_block_count();
-       codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
-                                  GFP_KERNEL);
-       if (!codec->reg_cache) {
-               ret = -ENOMEM;
-               goto err_tofree;
-       }
-       lzo_blocks = codec->reg_cache;
-
-       /*
-        * allocate a bitmap to be used when syncing the cache with
-        * the hardware.  Each time a register is modified, the corresponding
-        * bit is set in the bitmap, so we know that we have to sync
-        * that register.
-        */
-       bmp_size = codec_drv->reg_cache_size;
-       sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
-                          GFP_KERNEL);
-       if (!sync_bmp) {
-               ret = -ENOMEM;
-               goto err;
-       }
-       bitmap_zero(sync_bmp, bmp_size);
-
-       /* allocate the lzo blocks and initialize them */
-       for (i = 0; i < blkcount; ++i) {
-               lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
-                                       GFP_KERNEL);
-               if (!lzo_blocks[i]) {
-                       kfree(sync_bmp);
-                       ret = -ENOMEM;
-                       goto err;
-               }
-               lzo_blocks[i]->sync_bmp = sync_bmp;
-               lzo_blocks[i]->sync_bmp_nbits = bmp_size;
-               /* alloc the working space for the compressed block */
-               ret = snd_soc_lzo_prepare(lzo_blocks[i]);
-               if (ret < 0)
-                       goto err;
-       }
-
-       blksize = snd_soc_lzo_get_blksize(codec);
-       p = codec->reg_def_copy;
-       end = codec->reg_def_copy + codec->reg_size;
-       /* compress the register map and fill the lzo blocks */
-       for (i = 0; i < blkcount; ++i, p += blksize) {
-               lzo_blocks[i]->src = p;
-               if (p + blksize > end)
-                       lzo_blocks[i]->src_len = end - p;
-               else
-                       lzo_blocks[i]->src_len = blksize;
-               ret = snd_soc_lzo_compress_cache_block(codec,
-                                                      lzo_blocks[i]);
-               if (ret < 0)
-                       goto err;
-               lzo_blocks[i]->decompressed_size =
-                       lzo_blocks[i]->src_len;
-       }
-
-       if (tofree) {
-               kfree(codec->reg_def_copy);
-               codec->reg_def_copy = NULL;
-       }
-       return 0;
-err:
-       snd_soc_cache_exit(codec);
-err_tofree:
-       if (tofree) {
-               kfree(codec->reg_def_copy);
-               codec->reg_def_copy = NULL;
-       }
-       return ret;
-}
-#endif
-
 static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
 {
        int i;
@@ -889,17 +516,6 @@ static const struct snd_soc_cache_ops cache_types[] = {
                .write = snd_soc_flat_cache_write,
                .sync = snd_soc_flat_cache_sync
        },
-#ifdef CONFIG_SND_SOC_CACHE_LZO
-       {
-               .id = SND_SOC_LZO_COMPRESSION,
-               .name = "LZO",
-               .init = snd_soc_lzo_cache_init,
-               .exit = snd_soc_lzo_cache_exit,
-               .read = snd_soc_lzo_cache_read,
-               .write = snd_soc_lzo_cache_write,
-               .sync = snd_soc_lzo_cache_sync
-       },
-#endif
        {
                .id = SND_SOC_RBTREE_COMPRESSION,
                .name = "rbtree",
index a25fa63ce9a27501a4f2d4a6334911076200532e..ec783f0a27e9d00925ceb494c1864aa34c4b2ff9 100644 (file)
@@ -741,7 +741,7 @@ EXPORT_SYMBOL_GPL(snd_soc_resume);
 #define snd_soc_resume NULL
 #endif
 
-static struct snd_soc_dai_ops null_dai_ops = {
+static const struct snd_soc_dai_ops null_dai_ops = {
 };
 
 static int soc_bind_dai_link(struct snd_soc_card *card, int num)
@@ -1488,6 +1488,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 
        snd_soc_dapm_new_widgets(&card->dapm);
 
+       if (card->fully_routed)
+               list_for_each_entry(codec, &card->codec_dev_list, card_list)
+                       snd_soc_dapm_auto_nc_codec_pins(codec);
+
        ret = snd_card_register(card->snd_card);
        if (ret < 0) {
                printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
index f42e8b9fb17db7baeabaf7152f81123773cdecd0..da5c1ae7cc300af44559d23910d32f9c1ff3e19e 100644 (file)
@@ -2947,6 +2947,79 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
 
+static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card,
+                                             struct snd_soc_dapm_widget *w)
+{
+       struct snd_soc_dapm_path *p;
+
+       list_for_each_entry(p, &card->paths, list) {
+               if ((p->source == w) || (p->sink == w)) {
+                       dev_dbg(card->dev,
+                           "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n",
+                           p->source->name, p->source->id, p->source->dapm,
+                           p->sink->name, p->sink->id, p->sink->dapm);
+
+                       /* Connected to something other than the codec */
+                       if (p->source->dapm != p->sink->dapm)
+                               return true;
+                       /*
+                        * Loopback connection from codec external pin to
+                        * codec external pin
+                        */
+                       if (p->sink->id == snd_soc_dapm_input) {
+                               switch (p->source->id) {
+                               case snd_soc_dapm_output:
+                               case snd_soc_dapm_micbias:
+                                       return true;
+                               default:
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       return false;
+}
+
+/**
+ * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins
+ * @codec: The codec whose pins should be processed
+ *
+ * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec
+ * which are unused. Pins are used if they are connected externally to the
+ * codec, whether that be to some other device, or a loop-back connection to
+ * the codec itself.
+ */
+void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec)
+{
+       struct snd_soc_card *card = codec->card;
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct snd_soc_dapm_widget *w;
+
+       dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n",
+               &card->dapm, &codec->dapm);
+
+       list_for_each_entry(w, &card->widgets, list) {
+               if (w->dapm != dapm)
+                       continue;
+               switch (w->id) {
+               case snd_soc_dapm_input:
+               case snd_soc_dapm_output:
+               case snd_soc_dapm_micbias:
+                       dev_dbg(codec->dev, "Auto NC: Checking widget %s\n",
+                               w->name);
+                       if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
+                               dev_dbg(codec->dev,
+                                       "... Not in map; disabling\n");
+                               snd_soc_dapm_nc_pin(dapm, w->name);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
 /**
  * snd_soc_dapm_free - free dapm resources
  * @dapm: DAPM context
index ee15337353fae5f2cf16f5ab86f94d13440dc6bd..49aa71e0d7e653d70e4102394f3ae6190bfcb22e 100644 (file)
@@ -319,7 +319,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
        cpu_dai->runtime = NULL;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (unlikely(codec->ignore_pmdown_time)) {
+               if (codec->ignore_pmdown_time ||
+                   rtd->dai_link->ignore_pmdown_time) {
                        /* powered down playback stream now */
                        snd_soc_dapm_stream_event(rtd,
                                codec_dai->driver->playback.stream_name,
index 3b55a44146afc419c99fedd7d834dd826bd738e8..5b82b4e792311a6dcdae0c03d7100c71461716b1 100644 (file)
@@ -172,11 +172,11 @@ static int __devinit tegra_das_probe(struct platform_device *pdev)
        if (das)
                return -ENODEV;
 
-       das = kzalloc(sizeof(struct tegra_das), GFP_KERNEL);
+       das = devm_kzalloc(&pdev->dev, sizeof(struct tegra_das), GFP_KERNEL);
        if (!das) {
                dev_err(&pdev->dev, "Can't allocate tegra_das\n");
                ret = -ENOMEM;
-               goto exit;
+               goto err;
        }
        das->dev = &pdev->dev;
 
@@ -184,22 +184,22 @@ static int __devinit tegra_das_probe(struct platform_device *pdev)
        if (!res) {
                dev_err(&pdev->dev, "No memory resource\n");
                ret = -ENODEV;
-               goto err_free;
+               goto err;
        }
 
-       region = request_mem_region(res->start, resource_size(res),
-                                       pdev->name);
+       region = devm_request_mem_region(&pdev->dev, res->start,
+                                        resource_size(res), pdev->name);
        if (!region) {
                dev_err(&pdev->dev, "Memory region already claimed\n");
                ret = -EBUSY;
-               goto err_free;
+               goto err;
        }
 
-       das->regs = ioremap(res->start, resource_size(res));
+       das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
        if (!das->regs) {
                dev_err(&pdev->dev, "ioremap failed\n");
                ret = -ENOMEM;
-               goto err_release;
+               goto err;
        }
 
        tegra_das_debug_add(das);
@@ -208,58 +208,41 @@ static int __devinit tegra_das_probe(struct platform_device *pdev)
 
        return 0;
 
-err_release:
-       release_mem_region(res->start, resource_size(res));
-err_free:
-       kfree(das);
+err:
        das = NULL;
-exit:
        return ret;
 }
 
 static int __devexit tegra_das_remove(struct platform_device *pdev)
 {
-       struct resource *res;
-
        if (!das)
                return -ENODEV;
 
-       platform_set_drvdata(pdev, NULL);
-
        tegra_das_debug_remove(das);
 
-       iounmap(das->regs);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, resource_size(res));
-
-       kfree(das);
        das = NULL;
 
        return 0;
 }
 
+static const struct of_device_id tegra_das_of_match[] __devinitconst = {
+       { .compatible = "nvidia,tegra20-das", },
+       {},
+};
+
 static struct platform_driver tegra_das_driver = {
        .probe = tegra_das_probe,
        .remove = __devexit_p(tegra_das_remove),
        .driver = {
                .name = DRV_NAME,
+               .owner = THIS_MODULE,
+               .of_match_table = tegra_das_of_match,
        },
 };
-
-static int __init tegra_das_modinit(void)
-{
-       return platform_driver_register(&tegra_das_driver);
-}
-module_init(tegra_das_modinit);
-
-static void __exit tegra_das_modexit(void)
-{
-       platform_driver_unregister(&tegra_das_driver);
-}
-module_exit(tegra_das_modexit);
+module_platform_driver(tegra_das_driver);
 
 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 MODULE_DESCRIPTION("Tegra DAS driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_das_of_match);
index 6728fab8c411f05a4a7c10032ba9d0e87aa04c3b..ca4d0c0a913edb31ad06368ab6cd3afa92c08166 100644 (file)
@@ -42,7 +42,6 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
-#include "tegra_das.h"
 #include "tegra_i2s.h"
 
 #define DRV_NAME "tegra-i2s"
@@ -99,13 +98,11 @@ static const struct file_operations tegra_i2s_debug_fops = {
        .release = single_release,
 };
 
-static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id)
+static void tegra_i2s_debug_add(struct tegra_i2s *i2s)
 {
-       char name[] = DRV_NAME ".0";
-
-       snprintf(name, sizeof(name), DRV_NAME".%1d", id);
-       i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
-                                               i2s, &tegra_i2s_debug_fops);
+       i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO,
+                                        snd_soc_debugfs_root, i2s,
+                                        &tegra_i2s_debug_fops);
 }
 
 static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
@@ -306,49 +303,28 @@ static int tegra_i2s_probe(struct snd_soc_dai *dai)
        return 0;
 }
 
-static struct snd_soc_dai_ops tegra_i2s_dai_ops = {
+static const struct snd_soc_dai_ops tegra_i2s_dai_ops = {
        .set_fmt        = tegra_i2s_set_fmt,
        .hw_params      = tegra_i2s_hw_params,
        .trigger        = tegra_i2s_trigger,
 };
 
-static struct snd_soc_dai_driver tegra_i2s_dai[] = {
-       {
-               .name = DRV_NAME ".0",
-               .probe = tegra_i2s_probe,
-               .playback = {
-                       .channels_min = 2,
-                       .channels_max = 2,
-                       .rates = SNDRV_PCM_RATE_8000_96000,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
-               },
-               .capture = {
-                       .channels_min = 2,
-                       .channels_max = 2,
-                       .rates = SNDRV_PCM_RATE_8000_96000,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
-               },
-               .ops = &tegra_i2s_dai_ops,
-               .symmetric_rates = 1,
+static const struct snd_soc_dai_driver tegra_i2s_dai_template = {
+       .probe = tegra_i2s_probe,
+       .playback = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_96000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
        },
-       {
-               .name = DRV_NAME ".1",
-               .probe = tegra_i2s_probe,
-               .playback = {
-                       .channels_min = 2,
-                       .channels_max = 2,
-                       .rates = SNDRV_PCM_RATE_8000_96000,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
-               },
-               .capture = {
-                       .channels_min = 2,
-                       .channels_max = 2,
-                       .rates = SNDRV_PCM_RATE_8000_96000,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
-               },
-               .ops = &tegra_i2s_dai_ops,
-               .symmetric_rates = 1,
+       .capture = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = SNDRV_PCM_RATE_8000_96000,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
        },
+       .ops = &tegra_i2s_dai_ops,
+       .symmetric_rates = 1,
 };
 
 static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
@@ -357,42 +333,22 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
        struct resource *mem, *memregion, *dmareq;
        int ret;
 
-       if ((pdev->id < 0) ||
-               (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) {
-               dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
-               return -EINVAL;
-       }
-
-       /*
-        * FIXME: Until a codec driver exists for the tegra DAS, hard-code a
-        * 1:1 mapping between audio controllers and audio ports.
-        */
-       ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id,
-                                       TEGRA_DAS_DAP_SEL_DAC1 + pdev->id);
-       if (ret) {
-               dev_err(&pdev->dev, "Can't set up DAP connection\n");
-               return ret;
-       }
-       ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id,
-                                       TEGRA_DAS_DAC_SEL_DAP1 + pdev->id);
-       if (ret) {
-               dev_err(&pdev->dev, "Can't set up DAC connection\n");
-               return ret;
-       }
-
-       i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL);
+       i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL);
        if (!i2s) {
                dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
                ret = -ENOMEM;
-               goto exit;
+               goto err;
        }
        dev_set_drvdata(&pdev->dev, i2s);
 
+       i2s->dai = tegra_i2s_dai_template;
+       i2s->dai.name = dev_name(&pdev->dev);
+
        i2s->clk_i2s = clk_get(&pdev->dev, NULL);
        if (IS_ERR(i2s->clk_i2s)) {
                dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
                ret = PTR_ERR(i2s->clk_i2s);
-               goto err_free;
+               goto err;
        }
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -409,19 +365,19 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
                goto err_clk_put;
        }
 
-       memregion = request_mem_region(mem->start, resource_size(mem),
-                                       DRV_NAME);
+       memregion = devm_request_mem_region(&pdev->dev, mem->start,
+                                           resource_size(mem), DRV_NAME);
        if (!memregion) {
                dev_err(&pdev->dev, "Memory region already claimed\n");
                ret = -EBUSY;
                goto err_clk_put;
        }
 
-       i2s->regs = ioremap(mem->start, resource_size(mem));
+       i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
        if (!i2s->regs) {
                dev_err(&pdev->dev, "ioremap failed\n");
                ret = -ENOMEM;
-               goto err_release;
+               goto err_clk_put;
        }
 
        i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
@@ -436,47 +392,33 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
 
        i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
 
-       ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]);
+       ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
        if (ret) {
                dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
                ret = -ENOMEM;
-               goto err_unmap;
+               goto err_clk_put;
        }
 
-       tegra_i2s_debug_add(i2s, pdev->id);
+       tegra_i2s_debug_add(i2s);
 
        return 0;
 
-err_unmap:
-       iounmap(i2s->regs);
-err_release:
-       release_mem_region(mem->start, resource_size(mem));
 err_clk_put:
        clk_put(i2s->clk_i2s);
-err_free:
-       kfree(i2s);
-exit:
+err:
        return ret;
 }
 
 static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
 {
        struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
-       struct resource *res;
 
        snd_soc_unregister_dai(&pdev->dev);
 
        tegra_i2s_debug_remove(i2s);
 
-       iounmap(i2s->regs);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, resource_size(res));
-
        clk_put(i2s->clk_i2s);
 
-       kfree(i2s);
-
        return 0;
 }
 
@@ -488,18 +430,7 @@ static struct platform_driver tegra_i2s_driver = {
        .probe = tegra_i2s_platform_probe,
        .remove = __devexit_p(tegra_i2s_platform_remove),
 };
-
-static int __init snd_tegra_i2s_init(void)
-{
-       return platform_driver_register(&tegra_i2s_driver);
-}
-module_init(snd_tegra_i2s_init);
-
-static void __exit snd_tegra_i2s_exit(void)
-{
-       platform_driver_unregister(&tegra_i2s_driver);
-}
-module_exit(snd_tegra_i2s_exit);
+module_platform_driver(tegra_i2s_driver);
 
 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 MODULE_DESCRIPTION("Tegra I2S ASoC driver");
index 2b38a096f46cfb4427e03646a0fa3a51df53bb6c..15ce1e2e8bde1500d0641a8239eef0cca75e6003 100644 (file)
 #define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS  (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
 
 struct tegra_i2s {
+       struct snd_soc_dai_driver dai;
        struct clk *clk_i2s;
        int clk_refs;
        struct tegra_pcm_dma_params capture_dma_data;
index 436def1dfa39fee8b988fcbab0f14a74f277a438..90345ee138f3197121bbb353655f071f5b606a7f 100644 (file)
@@ -392,18 +392,7 @@ static struct platform_driver tegra_pcm_driver = {
        .probe = tegra_pcm_platform_probe,
        .remove = __devexit_p(tegra_pcm_platform_remove),
 };
-
-static int __init snd_tegra_pcm_init(void)
-{
-       return platform_driver_register(&tegra_pcm_driver);
-}
-module_init(snd_tegra_pcm_init);
-
-static void __exit snd_tegra_pcm_exit(void)
-{
-       platform_driver_unregister(&tegra_pcm_driver);
-}
-module_exit(snd_tegra_pcm_exit);
+module_platform_driver(tegra_pcm_driver);
 
 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 MODULE_DESCRIPTION("Tegra PCM ASoC driver");
index dd11d0c63474cd6fb8b2b19fea96e4ab07c42829..475428cf270e01eba85cff0a042c2d358669e7aa 100644 (file)
@@ -226,7 +226,7 @@ static int tegra_spdif_probe(struct snd_soc_dai *dai)
        return 0;
 }
 
-static struct snd_soc_dai_ops tegra_spdif_dai_ops = {
+static const struct snd_soc_dai_ops tegra_spdif_dai_ops = {
        .hw_params      = tegra_spdif_hw_params,
        .trigger        = tegra_spdif_trigger,
 };
@@ -352,17 +352,7 @@ static struct platform_driver tegra_spdif_driver = {
        .remove = __devexit_p(tegra_spdif_platform_remove),
 };
 
-static int __init snd_tegra_spdif_init(void)
-{
-       return platform_driver_register(&tegra_spdif_driver);
-}
-module_init(snd_tegra_spdif_init);
-
-static void __exit snd_tegra_spdif_exit(void)
-{
-       platform_driver_unregister(&tegra_spdif_driver);
-}
-module_exit(snd_tegra_spdif_exit);
+module_platform_driver(tegra_spdif_driver);
 
 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 MODULE_DESCRIPTION("Tegra SPDIF ASoC driver");
index a81cf39257bf2ff8aa68df2b7a9ef408887f0ed7..2f5b1074a8d95c3bc354f2be86ba6836421fc96d 100644 (file)
@@ -201,8 +201,8 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = {
        {"Int Spk", NULL, "RON"},
        {"Int Spk", NULL, "LOP"},
        {"Int Spk", NULL, "LON"},
-       {"Mic Bias", NULL, "Mic Jack"},
-       {"IN1L", NULL, "Mic Bias"},
+       {"Mic Jack", NULL, "MICBIAS"},
+       {"IN1L", NULL, "Mic Jack"},
 };
 
 static const struct snd_soc_dapm_route seaboard_audio_map[] = {
@@ -212,8 +212,8 @@ static const struct snd_soc_dapm_route seaboard_audio_map[] = {
        {"Int Spk", NULL, "RON"},
        {"Int Spk", NULL, "LOP"},
        {"Int Spk", NULL, "LON"},
-       {"Mic Bias", NULL, "Mic Jack"},
-       {"IN1R", NULL, "Mic Bias"},
+       {"Mic Jack", NULL, "MICBIAS"},
+       {"IN1R", NULL, "Mic Jack"},
 };
 
 static const struct snd_soc_dapm_route kaen_audio_map[] = {
@@ -223,8 +223,8 @@ static const struct snd_soc_dapm_route kaen_audio_map[] = {
        {"Int Spk", NULL, "RON"},
        {"Int Spk", NULL, "LOP"},
        {"Int Spk", NULL, "LON"},
-       {"Mic Bias", NULL, "Mic Jack"},
-       {"IN2R", NULL, "Mic Bias"},
+       {"Mic Jack", NULL, "MICBIAS"},
+       {"IN2R", NULL, "Mic Jack"},
 };
 
 static const struct snd_soc_dapm_route aebl_audio_map[] = {
@@ -232,8 +232,8 @@ static const struct snd_soc_dapm_route aebl_audio_map[] = {
        {"Headphone Jack", NULL, "HPOUTL"},
        {"Int Spk", NULL, "LINEOUTR"},
        {"Int Spk", NULL, "LINEOUTL"},
-       {"Mic Bias", NULL, "Mic Jack"},
-       {"IN1R", NULL, "Mic Bias"},
+       {"Mic Jack", NULL, "MICBIAS"},
+       {"IN1R", NULL, "Mic Jack"},
 };
 
 static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
@@ -249,6 +249,19 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
        struct tegra_wm8903_platform_data *pdata = machine->pdata;
        int ret;
 
+       ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
+                                          TEGRA_DAS_DAP_SEL_DAC1);
+       if (ret) {
+               dev_err(card->dev, "Can't set up DAS DAP connection\n");
+               return ret;
+       }
+       ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
+                                          TEGRA_DAS_DAC_SEL_DAP1);
+       if (ret) {
+               dev_err(card->dev, "Can't set up DAS DAC connection\n");
+               return ret;
+       }
+
        if (gpio_is_valid(pdata->gpio_spkr_en)) {
                ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
                if (ret) {
@@ -316,28 +329,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
        wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
                                0);
 
-       snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
-
-       /* FIXME: Calculate automatically based on DAPM routes? */
-       if (!machine_is_harmony())
-               snd_soc_dapm_nc_pin(dapm, "IN1L");
-       if (!machine_is_seaboard() && !machine_is_aebl())
-               snd_soc_dapm_nc_pin(dapm, "IN1R");
-       snd_soc_dapm_nc_pin(dapm, "IN2L");
-       if (!machine_is_kaen())
-               snd_soc_dapm_nc_pin(dapm, "IN2R");
-       snd_soc_dapm_nc_pin(dapm, "IN3L");
-       snd_soc_dapm_nc_pin(dapm, "IN3R");
-
-       if (machine_is_aebl()) {
-               snd_soc_dapm_nc_pin(dapm, "LON");
-               snd_soc_dapm_nc_pin(dapm, "RON");
-               snd_soc_dapm_nc_pin(dapm, "ROP");
-               snd_soc_dapm_nc_pin(dapm, "LOP");
-       } else {
-               snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
-               snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
-       }
+       snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
 
        return 0;
 }
@@ -362,6 +354,7 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = {
        .num_controls = ARRAY_SIZE(tegra_wm8903_controls),
        .dapm_widgets = tegra_wm8903_dapm_widgets,
        .num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_dapm_widgets),
+       .fully_routed = true,
 };
 
 static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
@@ -377,17 +370,19 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       machine = kzalloc(sizeof(struct tegra_wm8903), GFP_KERNEL);
+       machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
+                              GFP_KERNEL);
        if (!machine) {
                dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err;
        }
 
        machine->pdata = pdata;
 
        ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
        if (ret)
-               goto err_free_machine;
+               goto err;
 
        card->dev = &pdev->dev;
        platform_set_drvdata(pdev, card);
@@ -418,8 +413,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
 
 err_fini_utils:
        tegra_asoc_utils_fini(&machine->util_data);
-err_free_machine:
-       kfree(machine);
+err:
        return ret;
 }
 
@@ -447,8 +441,6 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
 
        tegra_asoc_utils_fini(&machine->util_data);
 
-       kfree(machine);
-
        return 0;
 }
 
@@ -461,18 +453,7 @@ static struct platform_driver tegra_wm8903_driver = {
        .probe = tegra_wm8903_driver_probe,
        .remove = __devexit_p(tegra_wm8903_driver_remove),
 };
-
-static int __init tegra_wm8903_modinit(void)
-{
-       return platform_driver_register(&tegra_wm8903_driver);
-}
-module_init(tegra_wm8903_modinit);
-
-static void __exit tegra_wm8903_modexit(void)
-{
-       platform_driver_unregister(&tegra_wm8903_driver);
-}
-module_exit(tegra_wm8903_modexit);
+module_platform_driver(tegra_wm8903_driver);
 
 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver");
index b3a7efa6d960c75eed9f764000eea0fd1f8d46fa..043eb7c7eb73303e36ae889616f65ad2c054d209 100644 (file)
@@ -118,11 +118,21 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = {
 static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct snd_soc_card *card = codec->card;
+       int ret;
 
-       snd_soc_dapm_nc_pin(dapm, "LHPOUT");
-       snd_soc_dapm_nc_pin(dapm, "RHPOUT");
-       snd_soc_dapm_nc_pin(dapm, "MICIN");
+       ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
+                                          TEGRA_DAS_DAP_SEL_DAC1);
+       if (ret) {
+               dev_err(card->dev, "Can't set up DAS DAP connection\n");
+               return ret;
+       }
+       ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
+                                          TEGRA_DAS_DAC_SEL_DAP1);
+       if (ret) {
+               dev_err(card->dev, "Can't set up DAS DAC connection\n");
+               return ret;
+       }
 
        return 0;
 }
@@ -147,6 +157,7 @@ static struct snd_soc_card snd_soc_trimslice = {
        .num_dapm_widgets = ARRAY_SIZE(trimslice_dapm_widgets),
        .dapm_routes = trimslice_audio_map,
        .num_dapm_routes = ARRAY_SIZE(trimslice_audio_map),
+       .fully_routed = true,
 };
 
 static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
@@ -155,15 +166,17 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
        struct tegra_trimslice *trimslice;
        int ret;
 
-       trimslice = kzalloc(sizeof(struct tegra_trimslice), GFP_KERNEL);
+       trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice),
+                                GFP_KERNEL);
        if (!trimslice) {
                dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err;
        }
 
        ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
        if (ret)
-               goto err_free_trimslice;
+               goto err;
 
        card->dev = &pdev->dev;
        platform_set_drvdata(pdev, card);
@@ -180,8 +193,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
 
 err_fini_utils:
        tegra_asoc_utils_fini(&trimslice->util_data);
-err_free_trimslice:
-       kfree(trimslice);
+err:
        return ret;
 }
 
@@ -194,8 +206,6 @@ static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev)
 
        tegra_asoc_utils_fini(&trimslice->util_data);
 
-       kfree(trimslice);
-
        return 0;
 }
 
@@ -207,18 +217,7 @@ static struct platform_driver tegra_snd_trimslice_driver = {
        .probe = tegra_snd_trimslice_probe,
        .remove = __devexit_p(tegra_snd_trimslice_remove),
 };
-
-static int __init snd_tegra_trimslice_init(void)
-{
-       return platform_driver_register(&tegra_snd_trimslice_driver);
-}
-module_init(snd_tegra_trimslice_init);
-
-static void __exit snd_tegra_trimslice_exit(void)
-{
-       platform_driver_unregister(&tegra_snd_trimslice_driver);
-}
-module_exit(snd_tegra_trimslice_exit);
+module_platform_driver(tegra_snd_trimslice_driver);
 
 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 MODULE_DESCRIPTION("Trimslice machine ASoC driver");
index a4e3f5501847ec640e2851ce4a786668044405eb..28db4ca997ca2b6c3f768de842ea84f567f4fd25 100644 (file)
@@ -223,18 +223,7 @@ static struct platform_driver txx9aclc_ac97_driver = {
        },
 };
 
-static int __init txx9aclc_ac97_init(void)
-{
-       return platform_driver_register(&txx9aclc_ac97_driver);
-}
-
-static void __exit txx9aclc_ac97_exit(void)
-{
-       platform_driver_unregister(&txx9aclc_ac97_driver);
-}
-
-module_init(txx9aclc_ac97_init);
-module_exit(txx9aclc_ac97_exit);
+module_platform_driver(txx9aclc_ac97_driver);
 
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
index 3de99af8cb82ccf6def128632603825e57c9ab77..93931def0dce62b3a5e162d7c759ac82f33745f2 100644 (file)
@@ -438,17 +438,7 @@ static struct platform_driver txx9aclc_pcm_driver = {
        .remove = __devexit_p(txx9aclc_soc_platform_remove),
 };
 
-static int __init snd_txx9aclc_pcm_init(void)
-{
-       return platform_driver_register(&txx9aclc_pcm_driver);
-}
-module_init(snd_txx9aclc_pcm_init);
-
-static void __exit snd_txx9aclc_pcm_exit(void)
-{
-       platform_driver_unregister(&txx9aclc_pcm_driver);
-}
-module_exit(snd_txx9aclc_pcm_exit);
+module_platform_driver(txx9aclc_pcm_driver);
 
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver");