aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/intel_sst/intel_sst_drv_interface.c1
-rw-r--r--drivers/staging/intel_sst/intelmid.c4
-rw-r--r--include/linux/mfd/wm8994/pdata.h49
-rw-r--r--include/sound/max98095.h26
-rw-r--r--include/sound/soc.h25
-rw-r--r--include/sound/wm8915.h55
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/au1x/db1200.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c13
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c166
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c42
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c56
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c45
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c42
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c23
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c172
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c159
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h16
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c42
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c23
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c110
-rw-r--r--sound/soc/codecs/Kconfig16
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ad193x.c23
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/ad73311.c2
-rw-r--r--sound/soc/codecs/ak4535.c19
-rw-r--r--sound/soc/codecs/ak4671.c18
-rw-r--r--sound/soc/codecs/cx20442.c18
-rw-r--r--sound/soc/codecs/jz4740.c18
-rw-r--r--sound/soc/codecs/max98088.c25
-rw-r--r--sound/soc/codecs/max98095.c2009
-rw-r--r--sound/soc/codecs/max98095.h284
-rw-r--r--sound/soc/codecs/sn95031.c17
-rw-r--r--sound/soc/codecs/ssm2602.c196
-rw-r--r--sound/soc/codecs/tlv320aic23.c19
-rw-r--r--sound/soc/codecs/wm1250-ev1.c108
-rw-r--r--sound/soc/codecs/wm8711.c18
-rw-r--r--sound/soc/codecs/wm8728.c18
-rw-r--r--sound/soc/codecs/wm8731.c22
-rw-r--r--sound/soc/codecs/wm8903.c18
-rw-r--r--sound/soc/codecs/wm8915.c2924
-rw-r--r--sound/soc/codecs/wm8915.h3717
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c1028
-rw-r--r--sound/soc/codecs/wm8994.c364
-rw-r--r--sound/soc/codecs/wm8994.h97
-rw-r--r--sound/soc/codecs/wm9705.c18
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c19
-rw-r--r--sound/soc/imx/imx-ssi.c6
-rw-r--r--sound/soc/jz4740/qi_lb60.c46
-rw-r--r--sound/soc/mid-x86/sst_platform.c4
-rw-r--r--sound/soc/pxa/corgi.c2
-rw-r--r--sound/soc/pxa/poodle.c2
-rw-r--r--sound/soc/pxa/spitz.c41
-rw-r--r--sound/soc/samsung/Kconfig15
-rw-r--r--sound/soc/samsung/Makefile4
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c206
-rw-r--r--sound/soc/samsung/speyside.c333
-rw-r--r--sound/soc/soc-cache.c572
-rw-r--r--sound/soc/soc-core.c80
-rw-r--r--sound/soc/soc-dapm.c181
-rw-r--r--sound/soc/soc-jack.c2
63 files changed, 11975 insertions, 1635 deletions
diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c
index e9c182108243..971588ce26d3 100644
--- a/drivers/staging/intel_sst/intel_sst_drv_interface.c
+++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c
@@ -508,7 +508,6 @@ int register_sst_card(struct intel_sst_card_ops *card)
508 sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE; 508 sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE;
509 sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/ 509 sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/
510 card->pcm_control = sst_pmic_ops.pcm_control; 510 card->pcm_control = sst_pmic_ops.pcm_control;
511 sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
512 return 0; 511 return 0;
513 } else { 512 } else {
514 pr_err("strcmp fail %s\n", card->module_name); 513 pr_err("strcmp fail %s\n", card->module_name);
diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c
index d207636a7b6d..ebb6d03552c4 100644
--- a/drivers/staging/intel_sst/intelmid.c
+++ b/drivers/staging/intel_sst/intelmid.c
@@ -32,6 +32,7 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/interrupt.h> 33#include <linux/interrupt.h>
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/firmware.h>
35#include <sound/control.h> 36#include <sound/control.h>
36#include <asm/mrst.h> 37#include <asm/mrst.h>
37#include <sound/pcm.h> 38#include <sound/pcm.h>
@@ -40,6 +41,8 @@
40#include <sound/initval.h> 41#include <sound/initval.h>
41#include "intel_sst.h" 42#include "intel_sst.h"
42#include "intel_sst_ioctl.h" 43#include "intel_sst_ioctl.h"
44#include "intel_sst_fw_ipc.h"
45#include "intel_sst_common.h"
43#include "intelmid_snd_control.h" 46#include "intelmid_snd_control.h"
44#include "intelmid.h" 47#include "intelmid.h"
45 48
@@ -802,6 +805,7 @@ static int __devinit snd_intelmad_sst_register(
802 pr_err("sst card registration failed\n"); 805 pr_err("sst card registration failed\n");
803 return ret_val; 806 return ret_val;
804 } 807 }
808 sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
805 809
806 sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id; 810 sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id;
807 intelmaddata->pmic_status = PMIC_UNINIT; 811 intelmaddata->pmic_status = PMIC_UNINIT;
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 466b1c777aff..d12f8d635a81 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -32,6 +32,10 @@ struct wm8994_ldo_pdata {
32#define WM8994_EQ_REGS 20 32#define WM8994_EQ_REGS 20
33#define WM8958_MBC_CUTOFF_REGS 20 33#define WM8958_MBC_CUTOFF_REGS 20
34#define WM8958_MBC_COEFF_REGS 48 34#define WM8958_MBC_COEFF_REGS 48
35#define WM8958_MBC_COMBINED_REGS 56
36#define WM8958_VSS_HPF_REGS 2
37#define WM8958_VSS_REGS 148
38#define WM8958_ENH_EQ_REGS 32
35 39
36/** 40/**
37 * DRC configurations are specified with a label and a set of register 41 * DRC configurations are specified with a label and a set of register
@@ -71,6 +75,42 @@ struct wm8958_mbc_cfg {
71 const char *name; 75 const char *name;
72 u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS]; 76 u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS];
73 u16 coeff_regs[WM8958_MBC_COEFF_REGS]; 77 u16 coeff_regs[WM8958_MBC_COEFF_REGS];
78
79 /* Coefficient layout when using MBC+VSS firmware */
80 u16 combined_regs[WM8958_MBC_COMBINED_REGS];
81};
82
83/**
84 * VSS HPF configurations are specified with a label and two values to
85 * write. Configurations are expected to be generated using the
86 * multiband compressor configuration panel in WISCE - see
87 * http://www.wolfsonmicro.com/wisce/
88 */
89struct wm8958_vss_hpf_cfg {
90 const char *name;
91 u16 regs[WM8958_VSS_HPF_REGS];
92};
93
94/**
95 * VSS configurations are specified with a label and array of values
96 * to write. Configurations are expected to be generated using the
97 * multiband compressor configuration panel in WISCE - see
98 * http://www.wolfsonmicro.com/wisce/
99 */
100struct wm8958_vss_cfg {
101 const char *name;
102 u16 regs[WM8958_VSS_REGS];
103};
104
105/**
106 * Enhanced EQ configurations are specified with a label and array of
107 * values to write. Configurations are expected to be generated using
108 * the multiband compressor configuration panel in WISCE - see
109 * http://www.wolfsonmicro.com/wisce/
110 */
111struct wm8958_enh_eq_cfg {
112 const char *name;
113 u16 regs[WM8958_ENH_EQ_REGS];
74}; 114};
75 115
76struct wm8994_pdata { 116struct wm8994_pdata {
@@ -95,6 +135,15 @@ struct wm8994_pdata {
95 int num_mbc_cfgs; 135 int num_mbc_cfgs;
96 struct wm8958_mbc_cfg *mbc_cfgs; 136 struct wm8958_mbc_cfg *mbc_cfgs;
97 137
138 int num_vss_cfgs;
139 struct wm8958_vss_cfg *vss_cfgs;
140
141 int num_vss_hpf_cfgs;
142 struct wm8958_vss_hpf_cfg *vss_hpf_cfgs;
143
144 int num_enh_eq_cfgs;
145 struct wm8958_enh_eq_cfg *enh_eq_cfgs;
146
98 /* LINEOUT can be differential or single ended */ 147 /* LINEOUT can be differential or single ended */
99 unsigned int lineout1_diff:1; 148 unsigned int lineout1_diff:1;
100 unsigned int lineout2_diff:1; 149 unsigned int lineout2_diff:1;
diff --git a/include/sound/max98095.h b/include/sound/max98095.h
new file mode 100644
index 000000000000..3381765b503e
--- /dev/null
+++ b/include/sound/max98095.h
@@ -0,0 +1,26 @@
1/*
2 * Platform data for MAX98095
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#ifndef __SOUND_MAX98095_PDATA_H__
14#define __SOUND_MAX98095_PDATA_H__
15
16/* codec platform data */
17struct max98095_pdata {
18 /* Analog/digital microphone configuration:
19 * 0 = analog microphone input (normal setting)
20 * 1 = digital microphone input
21 */
22 unsigned int digmic_left_mode:1;
23 unsigned int digmic_right_mode:1;
24};
25
26#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index bfa4836ea107..cb6b18b6eece 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -248,7 +248,7 @@ typedef int (*hw_write_t)(void *,const char* ,int);
248extern struct snd_ac97_bus_ops soc_ac97_ops; 248extern struct snd_ac97_bus_ops soc_ac97_ops;
249 249
250enum snd_soc_control_type { 250enum snd_soc_control_type {
251 SND_SOC_CUSTOM, 251 SND_SOC_CUSTOM = 1,
252 SND_SOC_I2C, 252 SND_SOC_I2C,
253 SND_SOC_SPI, 253 SND_SOC_SPI,
254}; 254};
@@ -278,6 +278,10 @@ int snd_soc_register_codec(struct device *dev,
278void snd_soc_unregister_codec(struct device *dev); 278void snd_soc_unregister_codec(struct device *dev);
279int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, 279int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
280 unsigned int reg); 280 unsigned int reg);
281int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
282 unsigned int reg);
283int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
284 unsigned int reg);
281int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, 285int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
282 int addr_bits, int data_bits, 286 int addr_bits, int data_bits,
283 enum snd_soc_control_type control); 287 enum snd_soc_control_type control);
@@ -292,6 +296,8 @@ int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
292 unsigned int reg); 296 unsigned int reg);
293int snd_soc_default_readable_register(struct snd_soc_codec *codec, 297int snd_soc_default_readable_register(struct snd_soc_codec *codec,
294 unsigned int reg); 298 unsigned int reg);
299int snd_soc_default_writable_register(struct snd_soc_codec *codec,
300 unsigned int reg);
295 301
296/* Utility functions to get clock rates from various things */ 302/* Utility functions to get clock rates from various things */
297int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); 303int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
@@ -523,6 +529,7 @@ struct snd_soc_codec {
523 size_t reg_size; /* reg_cache_size * reg_word_size */ 529 size_t reg_size; /* reg_cache_size * reg_word_size */
524 int (*volatile_register)(struct snd_soc_codec *, unsigned int); 530 int (*volatile_register)(struct snd_soc_codec *, unsigned int);
525 int (*readable_register)(struct snd_soc_codec *, unsigned int); 531 int (*readable_register)(struct snd_soc_codec *, unsigned int);
532 int (*writable_register)(struct snd_soc_codec *, unsigned int);
526 533
527 /* runtime */ 534 /* runtime */
528 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 535 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
@@ -539,10 +546,12 @@ struct snd_soc_codec {
539 546
540 /* codec IO */ 547 /* codec IO */
541 void *control_data; /* codec control (i2c/3wire) data */ 548 void *control_data; /* codec control (i2c/3wire) data */
549 enum snd_soc_control_type control_type;
542 hw_write_t hw_write; 550 hw_write_t hw_write;
543 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); 551 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
544 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 552 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
545 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); 553 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
554 int (*bulk_write_raw)(struct snd_soc_codec *, unsigned int, const void *, size_t);
546 void *reg_cache; 555 void *reg_cache;
547 const void *reg_def_copy; 556 const void *reg_def_copy;
548 const struct snd_soc_cache_ops *cache_ops; 557 const struct snd_soc_cache_ops *cache_ops;
@@ -568,7 +577,9 @@ struct snd_soc_codec_driver {
568 pm_message_t state); 577 pm_message_t state);
569 int (*resume)(struct snd_soc_codec *); 578 int (*resume)(struct snd_soc_codec *);
570 579
571 /* Default DAPM setup, added after probe() is run */ 580 /* Default control and setup, added after probe() is run */
581 const struct snd_kcontrol_new *controls;
582 int num_controls;
572 const struct snd_soc_dapm_widget *dapm_widgets; 583 const struct snd_soc_dapm_widget *dapm_widgets;
573 int num_dapm_widgets; 584 int num_dapm_widgets;
574 const struct snd_soc_dapm_route *dapm_routes; 585 const struct snd_soc_dapm_route *dapm_routes;
@@ -587,6 +598,7 @@ struct snd_soc_codec_driver {
587 size_t, unsigned int); 598 size_t, unsigned int);
588 int (*volatile_register)(struct snd_soc_codec *, unsigned int); 599 int (*volatile_register)(struct snd_soc_codec *, unsigned int);
589 int (*readable_register)(struct snd_soc_codec *, unsigned int); 600 int (*readable_register)(struct snd_soc_codec *, unsigned int);
601 int (*writable_register)(struct snd_soc_codec *, unsigned int);
590 short reg_cache_size; 602 short reg_cache_size;
591 short reg_cache_step; 603 short reg_cache_step;
592 short reg_word_size; 604 short reg_word_size;
@@ -737,12 +749,15 @@ struct snd_soc_card {
737 struct snd_soc_pcm_runtime *rtd_aux; 749 struct snd_soc_pcm_runtime *rtd_aux;
738 int num_aux_rtd; 750 int num_aux_rtd;
739 751
752 const struct snd_kcontrol_new *controls;
753 int num_controls;
754
740 /* 755 /*
741 * Card-specific routes and widgets. 756 * Card-specific routes and widgets.
742 */ 757 */
743 struct snd_soc_dapm_widget *dapm_widgets; 758 const struct snd_soc_dapm_widget *dapm_widgets;
744 int num_dapm_widgets; 759 int num_dapm_widgets;
745 struct snd_soc_dapm_route *dapm_routes; 760 const struct snd_soc_dapm_route *dapm_routes;
746 int num_dapm_routes; 761 int num_dapm_routes;
747 762
748 struct work_struct deferred_resume_work; 763 struct work_struct deferred_resume_work;
@@ -814,6 +829,8 @@ struct soc_enum {
814unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); 829unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
815unsigned int snd_soc_write(struct snd_soc_codec *codec, 830unsigned int snd_soc_write(struct snd_soc_codec *codec,
816 unsigned int reg, unsigned int val); 831 unsigned int reg, unsigned int val);
832unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
833 unsigned int reg, const void *data, size_t len);
817 834
818/* device driver data */ 835/* device driver data */
819 836
diff --git a/include/sound/wm8915.h b/include/sound/wm8915.h
new file mode 100644
index 000000000000..5817d762f6f3
--- /dev/null
+++ b/include/sound/wm8915.h
@@ -0,0 +1,55 @@
1/*
2 * linux/sound/wm8915.h -- Platform data for WM8915
3 *
4 * Copyright 2011 Wolfson Microelectronics. PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_WM8903_H
12#define __LINUX_SND_WM8903_H
13
14enum wm8915_inmode {
15 WM8915_DIFFERRENTIAL_1 = 0, /* IN1xP - IN1xN */
16 WM8915_INVERTING = 1, /* IN1xN */
17 WM8915_NON_INVERTING = 2, /* IN1xP */
18 WM8915_DIFFERENTIAL_2 = 3, /* IN2xP - IN2xP */
19};
20
21/**
22 * ReTune Mobile configurations are specified with a label, sample
23 * rate and set of values to write (the enable bits will be ignored).
24 *
25 * Configurations are expected to be generated using the ReTune Mobile
26 * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
27 */
28struct wm8915_retune_mobile_config {
29 const char *name;
30 int rate;
31 u16 regs[20];
32};
33
34#define WM8915_SET_DEFAULT 0x10000
35
36struct wm8915_pdata {
37 int irq_flags; /** Set IRQ trigger flags; default active low */
38
39 int ldo_ena; /** GPIO for LDO1; -1 for none */
40
41 int micdet_def; /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */
42
43 enum wm8915_inmode inl_mode;
44 enum wm8915_inmode inr_mode;
45
46 u32 spkmute_seq; /** Value for register 0x802 */
47
48 int gpio_base;
49 u32 gpio_default[5];
50
51 int num_retune_mobile_cfgs;
52 struct wm8915_retune_mobile_config *retune_mobile_cfgs;
53};
54
55#endif
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index af3c73053ee4..28afbbf69ce0 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -184,7 +184,7 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
184 .codec_dai_name = "wm8731-hifi", 184 .codec_dai_name = "wm8731-hifi",
185 .init = at91sam9g20ek_wm8731_init, 185 .init = at91sam9g20ek_wm8731_init,
186 .platform_name = "atmel-pcm-audio", 186 .platform_name = "atmel-pcm-audio",
187 .codec_name = "wm8731-codec.0-001b", 187 .codec_name = "wm8731.0-001b",
188 .ops = &at91sam9g20ek_ops, 188 .ops = &at91sam9g20ek_ops,
189}; 189};
190 190
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index cb99f04abe88..1d3e258c9ea8 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -77,7 +77,7 @@ static struct snd_soc_dai_link db1200_i2s_dai = {
77 .codec_dai_name = "wm8731-hifi", 77 .codec_dai_name = "wm8731-hifi",
78 .cpu_dai_name = "au1xpsc_i2s.1", 78 .cpu_dai_name = "au1xpsc_i2s.1",
79 .platform_name = "au1xpsc-pcm.1", 79 .platform_name = "au1xpsc-pcm.1",
80 .codec_name = "wm8731-codec.0-001b", 80 .codec_name = "wm8731.0-001b",
81 .ops = &db1200_i2s_wm8731_ops, 81 .ops = &db1200_i2s_wm8731_ops,
82}; 82};
83 83
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 5a2fd8abaefa..98b44b316e78 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -243,6 +243,9 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
243 243
244static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 244static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
245{ 245{
246 struct snd_soc_pcm_runtime *rtd = substream->private_data;
247 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
248 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
246 struct snd_pcm_runtime *runtime = substream->runtime; 249 struct snd_pcm_runtime *runtime = substream->runtime;
247 int ret; 250 int ret;
248 251
@@ -314,6 +317,9 @@ static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
314 317
315static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 318static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316{ 319{
320 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
321 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
322 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
317 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 323 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
318 struct snd_dma_buffer *buf = &substream->dma_buffer; 324 struct snd_dma_buffer *buf = &substream->dma_buffer;
319 size_t size = bf5xx_pcm_hardware.buffer_bytes_max 325 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
@@ -377,6 +383,9 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
377 struct snd_dma_buffer *buf; 383 struct snd_dma_buffer *buf;
378 int stream; 384 int stream;
379#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT) 385#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
386 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
387 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
388 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
380 size_t size = bf5xx_pcm_hardware.buffer_bytes_max * 389 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
381 sizeof(struct ac97_frame) / 4; 390 sizeof(struct ac97_frame) / 4;
382#endif 391#endif
@@ -405,8 +414,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
405 } 414 }
406#endif 415#endif
407 } 416 }
408 if (sport_handle)
409 sport_done(sport_handle);
410} 417}
411 418
412static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 419static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -458,7 +465,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
458 465
459static struct platform_driver bf5xx_pcm_driver = { 466static struct platform_driver bf5xx_pcm_driver = {
460 .driver = { 467 .driver = {
461 .name = "bf5xx-pcm-audio", 468 .name = "bfin-ac97-pcm-audio",
462 .owner = THIS_MODULE, 469 .owner = THIS_MODULE,
463 }, 470 },
464 471
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index ffbac26b9bce..6d2162590889 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -41,48 +41,7 @@
41 * anomaly does not affect blackfin sound drivers. 41 * anomaly does not affect blackfin sound drivers.
42*/ 42*/
43 43
44static int *cmd_count; 44static struct sport_device *ac97_sport_handle;
45static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
46
47#define SPORT_REQ(x) \
48 [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
49 P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
50static u16 sport_req[][7] = {
51#ifdef SPORT0_TCR1
52 SPORT_REQ(0),
53#endif
54#ifdef SPORT1_TCR1
55 SPORT_REQ(1),
56#endif
57#ifdef SPORT2_TCR1
58 SPORT_REQ(2),
59#endif
60#ifdef SPORT3_TCR1
61 SPORT_REQ(3),
62#endif
63};
64
65#define SPORT_PARAMS(x) \
66 [x] = { \
67 .dma_rx_chan = CH_SPORT##x##_RX, \
68 .dma_tx_chan = CH_SPORT##x##_TX, \
69 .err_irq = IRQ_SPORT##x##_ERROR, \
70 .regs = (struct sport_register *)SPORT##x##_TCR1, \
71 }
72static struct sport_param sport_params[4] = {
73#ifdef SPORT0_TCR1
74 SPORT_PARAMS(0),
75#endif
76#ifdef SPORT1_TCR1
77 SPORT_PARAMS(1),
78#endif
79#ifdef SPORT2_TCR1
80 SPORT_PARAMS(2),
81#endif
82#ifdef SPORT3_TCR1
83 SPORT_PARAMS(3),
84#endif
85};
86 45
87void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, 46void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
88 size_t count, unsigned int chan_mask) 47 size_t count, unsigned int chan_mask)
@@ -140,7 +99,8 @@ static unsigned int sport_tx_curr_frag(struct sport_device *sport)
140 99
141static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data) 100static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
142{ 101{
143 struct sport_device *sport = sport_handle; 102 struct sport_device *sport = ac97_sport_handle;
103 int *cmd_count = sport->private_data;
144 int nextfrag = sport_tx_curr_frag(sport); 104 int nextfrag = sport_tx_curr_frag(sport);
145 struct ac97_frame *nextwrite; 105 struct ac97_frame *nextwrite;
146 106
@@ -161,6 +121,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
161static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97, 121static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
162 unsigned short reg) 122 unsigned short reg)
163{ 123{
124 struct sport_device *sport_handle = ac97_sport_handle;
164 struct ac97_frame out_frame[2], in_frame[2]; 125 struct ac97_frame out_frame[2], in_frame[2];
165 126
166 pr_debug("%s enter 0x%x\n", __func__, reg); 127 pr_debug("%s enter 0x%x\n", __func__, reg);
@@ -185,6 +146,8 @@ static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
185void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 146void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
186 unsigned short val) 147 unsigned short val)
187{ 148{
149 struct sport_device *sport_handle = ac97_sport_handle;
150
188 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val); 151 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
189 152
190 if (sport_handle->tx_run) { 153 if (sport_handle->tx_run) {
@@ -203,28 +166,19 @@ void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
203 166
204static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97) 167static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
205{ 168{
206#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \ 169 struct sport_device *sport_handle = ac97_sport_handle;
207 (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1)) 170 u16 gpio = P_IDENT(sport_handle->pin_req[3]);
208
209#define CONCAT(a, b, c) a ## b ## c
210#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS)
211
212 u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM);
213 u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM));
214 171
215 pr_debug("%s enter\n", __func__); 172 pr_debug("%s enter\n", __func__);
216 173
217 peripheral_free(per); 174 peripheral_free_list(sport_handle->pin_req);
218 gpio_request(gpio, "bf5xx-ac97"); 175 gpio_request(gpio, "bf5xx-ac97");
219 gpio_direction_output(gpio, 1); 176 gpio_direction_output(gpio, 1);
220 udelay(2); 177 udelay(2);
221 gpio_set_value(gpio, 0); 178 gpio_set_value(gpio, 0);
222 udelay(1); 179 udelay(1);
223 gpio_free(gpio); 180 gpio_free(gpio);
224 peripheral_request(per, "soc-audio"); 181 peripheral_request_list(sport_handle->pin_req, "soc-audio");
225#else
226 pr_info("%s: Not implemented\n", __func__);
227#endif
228} 182}
229 183
230static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97) 184static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
@@ -306,18 +260,32 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
306#define bf5xx_ac97_resume NULL 260#define bf5xx_ac97_resume NULL
307#endif 261#endif
308 262
309static int bf5xx_ac97_probe(struct snd_soc_dai *dai) 263static struct snd_soc_dai_driver bfin_ac97_dai = {
264 .ac97_control = 1,
265 .suspend = bf5xx_ac97_suspend,
266 .resume = bf5xx_ac97_resume,
267 .playback = {
268 .stream_name = "AC97 Playback",
269 .channels_min = 2,
270#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
271 .channels_max = 6,
272#else
273 .channels_max = 2,
274#endif
275 .rates = SNDRV_PCM_RATE_48000,
276 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
277 .capture = {
278 .stream_name = "AC97 Capture",
279 .channels_min = 2,
280 .channels_max = 2,
281 .rates = SNDRV_PCM_RATE_48000,
282 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
283};
284
285static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev)
310{ 286{
311 int ret = 0; 287 struct sport_device *sport_handle;
312 cmd_count = (int *)get_zeroed_page(GFP_KERNEL); 288 int ret;
313 if (cmd_count == NULL)
314 return -ENOMEM;
315
316 if (peripheral_request_list(sport_req[sport_num], "soc-audio")) {
317 pr_err("Requesting Peripherals failed\n");
318 ret = -EFAULT;
319 goto peripheral_err;
320 }
321 289
322#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 290#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
323 /* Request PB3 as reset pin */ 291 /* Request PB3 as reset pin */
@@ -329,12 +297,14 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
329 } 297 }
330 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); 298 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
331#endif 299#endif
332 sport_handle = sport_init(&sport_params[sport_num], 2, \ 300
333 sizeof(struct ac97_frame), NULL); 301 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
302 PAGE_SIZE);
334 if (!sport_handle) { 303 if (!sport_handle) {
335 ret = -ENODEV; 304 ret = -ENODEV;
336 goto sport_err; 305 goto sport_err;
337 } 306 }
307
338 /*SPORT works in TDM mode to simulate AC97 transfers*/ 308 /*SPORT works in TDM mode to simulate AC97 transfers*/
339#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT) 309#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
340 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1); 310 ret = sport_set_multichannel(sport_handle, 16, 0x3FF, 1);
@@ -361,67 +331,37 @@ static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
361 goto sport_config_err; 331 goto sport_config_err;
362 } 332 }
363 333
334 ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
335 if (ret) {
336 pr_err("Failed to register DAI: %d\n", ret);
337 goto sport_config_err;
338 }
339
340 ac97_sport_handle = sport_handle;
341
364 return 0; 342 return 0;
365 343
366sport_config_err: 344sport_config_err:
367 kfree(sport_handle); 345 sport_done(sport_handle);
368sport_err: 346sport_err:
369#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 347#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
370 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 348 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
371gpio_err: 349gpio_err:
372#endif 350#endif
373 peripheral_free_list(sport_req[sport_num]);
374peripheral_err:
375 free_page((unsigned long)cmd_count);
376 cmd_count = NULL;
377 351
378 return ret; 352 return ret;
379} 353}
380 354
381static int bf5xx_ac97_remove(struct snd_soc_dai *dai) 355static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
382{ 356{
383 free_page((unsigned long)cmd_count); 357 struct sport_device *sport_handle = platform_get_drvdata(pdev);
384 cmd_count = NULL; 358
385 peripheral_free_list(sport_req[sport_num]); 359 snd_soc_unregister_dai(&pdev->dev);
360 sport_done(sport_handle);
386#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 361#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
387 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 362 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
388#endif 363#endif
389 return 0;
390}
391
392struct snd_soc_dai_driver bfin_ac97_dai = {
393 .ac97_control = 1,
394 .probe = bf5xx_ac97_probe,
395 .remove = bf5xx_ac97_remove,
396 .suspend = bf5xx_ac97_suspend,
397 .resume = bf5xx_ac97_resume,
398 .playback = {
399 .stream_name = "AC97 Playback",
400 .channels_min = 2,
401#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
402 .channels_max = 6,
403#else
404 .channels_max = 2,
405#endif
406 .rates = SNDRV_PCM_RATE_48000,
407 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
408 .capture = {
409 .stream_name = "AC97 Capture",
410 .channels_min = 2,
411 .channels_max = 2,
412 .rates = SNDRV_PCM_RATE_48000,
413 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
414};
415EXPORT_SYMBOL_GPL(bfin_ac97_dai);
416
417static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
418{
419 return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
420}
421 364
422static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
423{
424 snd_soc_unregister_dai(&pdev->dev);
425 return 0; 365 return 0;
426} 366}
427 367
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 83012da9dfc2..ea4951cf5526 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -29,22 +29,12 @@
29#include <asm/portmux.h> 29#include <asm/portmux.h>
30 30
31#include "../codecs/ad1836.h" 31#include "../codecs/ad1836.h"
32#include "bf5xx-sport.h"
33 32
34#include "bf5xx-tdm-pcm.h" 33#include "bf5xx-tdm-pcm.h"
35#include "bf5xx-tdm.h" 34#include "bf5xx-tdm.h"
36 35
37static struct snd_soc_card bf5xx_ad1836; 36static struct snd_soc_card bf5xx_ad1836;
38 37
39static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43
44 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
45 return 0;
46}
47
48static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, 38static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
49 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
50{ 40{
@@ -75,23 +65,33 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
75} 65}
76 66
77static struct snd_soc_ops bf5xx_ad1836_ops = { 67static struct snd_soc_ops bf5xx_ad1836_ops = {
78 .startup = bf5xx_ad1836_startup,
79 .hw_params = bf5xx_ad1836_hw_params, 68 .hw_params = bf5xx_ad1836_hw_params,
80}; 69};
81 70
82static struct snd_soc_dai_link bf5xx_ad1836_dai = { 71static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
83 .name = "ad1836", 72 {
84 .stream_name = "AD1836", 73 .name = "ad1836",
85 .cpu_dai_name = "bf5xx-tdm", 74 .stream_name = "AD1836",
86 .codec_dai_name = "ad1836-hifi", 75 .cpu_dai_name = "bfin-tdm.0",
87 .platform_name = "bf5xx-tdm-pcm-audio", 76 .codec_dai_name = "ad1836-hifi",
88 .codec_name = "ad1836-codec.0", 77 .platform_name = "bfin-tdm-pcm-audio",
89 .ops = &bf5xx_ad1836_ops, 78 .codec_name = "ad1836.0",
79 .ops = &bf5xx_ad1836_ops,
80 },
81 {
82 .name = "ad1836",
83 .stream_name = "AD1836",
84 .cpu_dai_name = "bfin-tdm.1",
85 .codec_dai_name = "ad1836-hifi",
86 .platform_name = "bfin-tdm-pcm-audio",
87 .codec_name = "ad1836.0",
88 .ops = &bf5xx_ad1836_ops,
89 },
90}; 90};
91 91
92static struct snd_soc_card bf5xx_ad1836 = { 92static struct snd_soc_card bf5xx_ad1836 = {
93 .name = "bf5xx_ad1836", 93 .name = "bfin-ad1836",
94 .dai_link = &bf5xx_ad1836_dai, 94 .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
95 .num_links = 1, 95 .num_links = 1,
96}; 96};
97 97
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index d3ccb926b5e4..d6651c033cb7 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -38,30 +38,28 @@
38#include <asm/portmux.h> 38#include <asm/portmux.h>
39 39
40#include "../codecs/ad193x.h" 40#include "../codecs/ad193x.h"
41#include "bf5xx-sport.h"
42 41
43#include "bf5xx-tdm-pcm.h" 42#include "bf5xx-tdm-pcm.h"
44#include "bf5xx-tdm.h" 43#include "bf5xx-tdm.h"
45 44
46static struct snd_soc_card bf5xx_ad193x; 45static struct snd_soc_card bf5xx_ad193x;
47 46
48static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52
53 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
54 return 0;
55}
56
57static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 48 struct snd_pcm_hw_params *params)
59{ 49{
60 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
61 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
62 struct snd_soc_dai *codec_dai = rtd->codec_dai; 52 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 unsigned int clk = 0;
63 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7}; 54 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
64 int ret = 0; 55 int ret = 0;
56
57 switch (params_rate(params)) {
58 case 48000:
59 clk = 12288000;
60 break;
61 }
62
65 /* set cpu DAI configuration */ 63 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 64 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
67 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); 65 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
@@ -74,6 +72,12 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
74 if (ret < 0) 72 if (ret < 0)
75 return ret; 73 return ret;
76 74
75 /* set the codec system clock for DAC and ADC */
76 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
77 SND_SOC_CLOCK_IN);
78 if (ret < 0)
79 return ret;
80
77 /* set codec DAI slots, 8 channels, all channels are enabled */ 81 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32); 82 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
79 if (ret < 0) 83 if (ret < 0)
@@ -89,23 +93,33 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
89} 93}
90 94
91static struct snd_soc_ops bf5xx_ad193x_ops = { 95static struct snd_soc_ops bf5xx_ad193x_ops = {
92 .startup = bf5xx_ad193x_startup,
93 .hw_params = bf5xx_ad193x_hw_params, 96 .hw_params = bf5xx_ad193x_hw_params,
94}; 97};
95 98
96static struct snd_soc_dai_link bf5xx_ad193x_dai = { 99static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
97 .name = "ad193x", 100 {
98 .stream_name = "AD193X", 101 .name = "ad193x",
99 .cpu_dai_name = "bf5xx-tdm", 102 .stream_name = "AD193X",
100 .codec_dai_name ="ad193x-hifi", 103 .cpu_dai_name = "bfin-tdm.0",
101 .platform_name = "bf5xx-tdm-pcm-audio", 104 .codec_dai_name ="ad193x-hifi",
102 .codec_name = "ad193x-codec.5", 105 .platform_name = "bfin-tdm-pcm-audio",
103 .ops = &bf5xx_ad193x_ops, 106 .codec_name = "ad193x.5",
107 .ops = &bf5xx_ad193x_ops,
108 },
109 {
110 .name = "ad193x",
111 .stream_name = "AD193X",
112 .cpu_dai_name = "bfin-tdm.1",
113 .codec_dai_name ="ad193x-hifi",
114 .platform_name = "bfin-tdm-pcm-audio",
115 .codec_name = "ad193x.5",
116 .ops = &bf5xx_ad193x_ops,
117 },
104}; 118};
105 119
106static struct snd_soc_card bf5xx_ad193x = { 120static struct snd_soc_card bf5xx_ad193x = {
107 .name = "bf5xx_ad193x", 121 .name = "bfin-ad193x",
108 .dai_link = &bf5xx_ad193x_dai, 122 .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM],
109 .num_links = 1, 123 .num_links = 1,
110}; 124};
111 125
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index d57c9c9c9883..06a84b211b52 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -47,39 +47,34 @@
47#include <asm/portmux.h> 47#include <asm/portmux.h>
48 48
49#include "../codecs/ad1980.h" 49#include "../codecs/ad1980.h"
50#include "bf5xx-sport.h" 50
51#include "bf5xx-ac97-pcm.h" 51#include "bf5xx-ac97-pcm.h"
52#include "bf5xx-ac97.h" 52#include "bf5xx-ac97.h"
53 53
54static struct snd_soc_card bf5xx_board; 54static struct snd_soc_card bf5xx_board;
55 55
56static int bf5xx_board_startup(struct snd_pcm_substream *substream) 56static struct snd_soc_dai_link bf5xx_board_dai[] = {
57{ 57 {
58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 58 .name = "AC97",
59 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 59 .stream_name = "AC97 HiFi",
60 60 .cpu_dai_name = "bfin-ac97.0",
61 pr_debug("%s enter\n", __func__); 61 .codec_dai_name = "ad1980-hifi",
62 snd_soc_dai_set_drvdata(cpu_dai, sport_handle); 62 .platform_name = "bfin-ac97-pcm-audio",
63 return 0; 63 .codec_name = "ad1980",
64} 64 },
65 65 {
66static struct snd_soc_ops bf5xx_board_ops = { 66 .name = "AC97",
67 .startup = bf5xx_board_startup, 67 .stream_name = "AC97 HiFi",
68}; 68 .cpu_dai_name = "bfin-ac97.1",
69 69 .codec_dai_name = "ad1980-hifi",
70static struct snd_soc_dai_link bf5xx_board_dai = { 70 .platform_name = "bfin-ac97-pcm-audio",
71 .name = "AC97", 71 .codec_name = "ad1980",
72 .stream_name = "AC97 HiFi", 72 },
73 .cpu_dai_name = "bfin-ac97",
74 .codec_dai_name = "ad1980-hifi",
75 .platform_name = "bfin-pcm-audio",
76 .codec_name = "ad1980-codec",
77 .ops = &bf5xx_board_ops,
78}; 73};
79 74
80static struct snd_soc_card bf5xx_board = { 75static struct snd_soc_card bf5xx_board = {
81 .name = "bf5xx-board", 76 .name = "bfin-ad1980",
82 .dai_link = &bf5xx_board_dai, 77 .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM],
83 .num_links = 1, 78 .num_links = 1,
84}; 79};
85 80
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 732fb8bad076..732a247f2527 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -145,16 +145,6 @@ static int bf5xx_probe(struct platform_device *pdev)
145 return 0; 145 return 0;
146} 146}
147 147
148static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
149{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
152
153 pr_debug("%s enter\n", __func__);
154 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
155 return 0;
156}
157
158static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, 148static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
159 struct snd_pcm_hw_params *params) 149 struct snd_pcm_hw_params *params)
160{ 150{
@@ -176,24 +166,34 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
176 166
177 167
178static struct snd_soc_ops bf5xx_ad73311_ops = { 168static struct snd_soc_ops bf5xx_ad73311_ops = {
179 .startup = bf5xx_ad73311_startup,
180 .hw_params = bf5xx_ad73311_hw_params, 169 .hw_params = bf5xx_ad73311_hw_params,
181}; 170};
182 171
183static struct snd_soc_dai_link bf5xx_ad73311_dai = { 172static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
184 .name = "ad73311", 173 {
185 .stream_name = "AD73311", 174 .name = "ad73311",
186 .cpu_dai_name = "bf5xx-i2s", 175 .stream_name = "AD73311",
187 .codec_dai_name = "ad73311-hifi", 176 .cpu_dai_name = "bfin-i2s.0",
188 .platform_name = "bfin-pcm-audio", 177 .codec_dai_name = "ad73311-hifi",
189 .codec_name = "ad73311-codec", 178 .platform_name = "bfin-i2s-pcm-audio",
190 .ops = &bf5xx_ad73311_ops, 179 .codec_name = "ad73311",
180 .ops = &bf5xx_ad73311_ops,
181 },
182 {
183 .name = "ad73311",
184 .stream_name = "AD73311",
185 .cpu_dai_name = "bfin-i2s.1",
186 .codec_dai_name = "ad73311-hifi",
187 .platform_name = "bfin-i2s-pcm-audio",
188 .codec_name = "ad73311",
189 .ops = &bf5xx_ad73311_ops,
190 },
191}; 191};
192 192
193static struct snd_soc_card bf5xx_ad73311 = { 193static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311", 194 .name = "bfin-ad73311",
195 .probe = bf5xx_probe, 195 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai, 196 .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],
197 .num_links = 1, 197 .num_links = 1,
198}; 198};
199 199
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 890a0dccf902..b5101efd1c87 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -148,10 +148,15 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
148 148
149static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 149static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
150{ 150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
153 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
151 struct snd_pcm_runtime *runtime = substream->runtime; 154 struct snd_pcm_runtime *runtime = substream->runtime;
155 struct snd_dma_buffer *buf = &substream->dma_buffer;
152 int ret; 156 int ret;
153 157
154 pr_debug("%s enter\n", __func__); 158 pr_debug("%s enter\n", __func__);
159
155 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
156 161
157 ret = snd_pcm_hw_constraint_integer(runtime, \ 162 ret = snd_pcm_hw_constraint_integer(runtime, \
@@ -159,9 +164,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
159 if (ret < 0) 164 if (ret < 0)
160 goto out; 165 goto out;
161 166
162 if (sport_handle != NULL) 167 if (sport_handle != NULL) {
168 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169 sport_handle->tx_buf = buf->area;
170 else
171 sport_handle->rx_buf = buf->area;
172
163 runtime->private_data = sport_handle; 173 runtime->private_data = sport_handle;
164 else { 174 } else {
165 pr_err("sport_handle is NULL\n"); 175 pr_err("sport_handle is NULL\n");
166 return -1; 176 return -1;
167 } 177 }
@@ -214,11 +224,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
214 pr_debug("%s, area:%p, size:0x%08lx\n", __func__, 224 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
215 buf->area, buf->bytes); 225 buf->area, buf->bytes);
216 226
217 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
218 sport_handle->tx_buf = buf->area;
219 else
220 sport_handle->rx_buf = buf->area;
221
222 return 0; 227 return 0;
223} 228}
224 229
@@ -239,8 +244,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
239 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 244 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
240 buf->area = NULL; 245 buf->area = NULL;
241 } 246 }
242 if (sport_handle)
243 sport_done(sport_handle);
244} 247}
245 248
246static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 249static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -292,7 +295,7 @@ static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
292 295
293static struct platform_driver bfin_i2s_pcm_driver = { 296static struct platform_driver bfin_i2s_pcm_driver = {
294 .driver = { 297 .driver = {
295 .name = "bfin-pcm-audio", 298 .name = "bfin-i2s-pcm-audio",
296 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
297 }, 300 },
298 301
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index d453b1e9d607..00cc3e00b2fe 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -51,59 +51,24 @@ struct bf5xx_i2s_port {
51 int configured; 51 int configured;
52}; 52};
53 53
54static struct bf5xx_i2s_port bf5xx_i2s;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56
57static struct sport_param sport_params[2] = {
58 {
59 .dma_rx_chan = CH_SPORT0_RX,
60 .dma_tx_chan = CH_SPORT0_TX,
61 .err_irq = IRQ_SPORT0_ERROR,
62 .regs = (struct sport_register *)SPORT0_TCR1,
63 },
64 {
65 .dma_rx_chan = CH_SPORT1_RX,
66 .dma_tx_chan = CH_SPORT1_TX,
67 .err_irq = IRQ_SPORT1_ERROR,
68 .regs = (struct sport_register *)SPORT1_TCR1,
69 }
70};
71
72/*
73 * Setting the TFS pin selector for SPORT 0 based on whether the selected
74 * port id F or G. If the port is F then no conflict should exist for the
75 * TFS. When Port G is selected and EMAC then there is a conflict between
76 * the PHY interrupt line and TFS. Current settings prevent the conflict
77 * by ignoring the TFS pin when Port G is selected. This allows both
78 * codecs and EMAC using Port G concurrently.
79 */
80#ifdef CONFIG_BF527_SPORT0_PORTG
81#define LOCAL_SPORT0_TFS (0)
82#else
83#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
84#endif
85
86static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
87 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
88 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
89 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
90
91static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 54static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
92 unsigned int fmt) 55 unsigned int fmt)
93{ 56{
57 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
58 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
94 int ret = 0; 59 int ret = 0;
95 60
96 /* interface format:support I2S,slave mode */ 61 /* interface format:support I2S,slave mode */
97 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 62 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
98 case SND_SOC_DAIFMT_I2S: 63 case SND_SOC_DAIFMT_I2S:
99 bf5xx_i2s.tcr1 |= TFSR | TCKFE; 64 bf5xx_i2s->tcr1 |= TFSR | TCKFE;
100 bf5xx_i2s.rcr1 |= RFSR | RCKFE; 65 bf5xx_i2s->rcr1 |= RFSR | RCKFE;
101 bf5xx_i2s.tcr2 |= TSFSE; 66 bf5xx_i2s->tcr2 |= TSFSE;
102 bf5xx_i2s.rcr2 |= RSFSE; 67 bf5xx_i2s->rcr2 |= RSFSE;
103 break; 68 break;
104 case SND_SOC_DAIFMT_DSP_A: 69 case SND_SOC_DAIFMT_DSP_A:
105 bf5xx_i2s.tcr1 |= TFSR; 70 bf5xx_i2s->tcr1 |= TFSR;
106 bf5xx_i2s.rcr1 |= RFSR; 71 bf5xx_i2s->rcr1 |= RFSR;
107 break; 72 break;
108 case SND_SOC_DAIFMT_LEFT_J: 73 case SND_SOC_DAIFMT_LEFT_J:
109 ret = -EINVAL; 74 ret = -EINVAL;
@@ -135,29 +100,35 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params, 100 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai) 101 struct snd_soc_dai *dai)
137{ 102{
103 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
104 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
138 int ret = 0; 105 int ret = 0;
139 106
140 bf5xx_i2s.tcr2 &= ~0x1f; 107 bf5xx_i2s->tcr2 &= ~0x1f;
141 bf5xx_i2s.rcr2 &= ~0x1f; 108 bf5xx_i2s->rcr2 &= ~0x1f;
142 switch (params_format(params)) { 109 switch (params_format(params)) {
110 case SNDRV_PCM_FORMAT_S8:
111 bf5xx_i2s->tcr2 |= 7;
112 bf5xx_i2s->rcr2 |= 7;
113 sport_handle->wdsize = 1;
143 case SNDRV_PCM_FORMAT_S16_LE: 114 case SNDRV_PCM_FORMAT_S16_LE:
144 bf5xx_i2s.tcr2 |= 15; 115 bf5xx_i2s->tcr2 |= 15;
145 bf5xx_i2s.rcr2 |= 15; 116 bf5xx_i2s->rcr2 |= 15;
146 sport_handle->wdsize = 2; 117 sport_handle->wdsize = 2;
147 break; 118 break;
148 case SNDRV_PCM_FORMAT_S24_LE: 119 case SNDRV_PCM_FORMAT_S24_LE:
149 bf5xx_i2s.tcr2 |= 23; 120 bf5xx_i2s->tcr2 |= 23;
150 bf5xx_i2s.rcr2 |= 23; 121 bf5xx_i2s->rcr2 |= 23;
151 sport_handle->wdsize = 3; 122 sport_handle->wdsize = 3;
152 break; 123 break;
153 case SNDRV_PCM_FORMAT_S32_LE: 124 case SNDRV_PCM_FORMAT_S32_LE:
154 bf5xx_i2s.tcr2 |= 31; 125 bf5xx_i2s->tcr2 |= 31;
155 bf5xx_i2s.rcr2 |= 31; 126 bf5xx_i2s->rcr2 |= 31;
156 sport_handle->wdsize = 4; 127 sport_handle->wdsize = 4;
157 break; 128 break;
158 } 129 }
159 130
160 if (!bf5xx_i2s.configured) { 131 if (!bf5xx_i2s->configured) {
161 /* 132 /*
162 * TX and RX are not independent,they are enabled at the 133 * TX and RX are not independent,they are enabled at the
163 * same time, even if only one side is running. So, we 134 * same time, even if only one side is running. So, we
@@ -166,16 +137,16 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
166 * 137 *
167 * CPU DAI:slave mode. 138 * CPU DAI:slave mode.
168 */ 139 */
169 bf5xx_i2s.configured = 1; 140 bf5xx_i2s->configured = 1;
170 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, 141 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
171 bf5xx_i2s.rcr2, 0, 0); 142 bf5xx_i2s->rcr2, 0, 0);
172 if (ret) { 143 if (ret) {
173 pr_err("SPORT is busy!\n"); 144 pr_err("SPORT is busy!\n");
174 return -EBUSY; 145 return -EBUSY;
175 } 146 }
176 147
177 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, 148 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
178 bf5xx_i2s.tcr2, 0, 0); 149 bf5xx_i2s->tcr2, 0, 0);
179 if (ret) { 150 if (ret) {
180 pr_err("SPORT is busy!\n"); 151 pr_err("SPORT is busy!\n");
181 return -EBUSY; 152 return -EBUSY;
@@ -188,41 +159,19 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
188static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream, 159static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
189 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
190{ 161{
162 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
163 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
164
191 pr_debug("%s enter\n", __func__); 165 pr_debug("%s enter\n", __func__);
192 /* No active stream, SPORT is allowed to be configured again. */ 166 /* No active stream, SPORT is allowed to be configured again. */
193 if (!dai->active) 167 if (!dai->active)
194 bf5xx_i2s.configured = 0; 168 bf5xx_i2s->configured = 0;
195}
196
197static int bf5xx_i2s_probe(struct snd_soc_dai *dai)
198{
199 pr_debug("%s enter\n", __func__);
200 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
201 pr_err("Requesting Peripherals failed\n");
202 return -EFAULT;
203 }
204
205 /* request DMA for SPORT */
206 sport_handle = sport_init(&sport_params[sport_num], 4, \
207 2 * sizeof(u32), NULL);
208 if (!sport_handle) {
209 peripheral_free_list(&sport_req[sport_num][0]);
210 return -ENODEV;
211 }
212
213 return 0;
214}
215
216static int bf5xx_i2s_remove(struct snd_soc_dai *dai)
217{
218 pr_debug("%s enter\n", __func__);
219 peripheral_free_list(&sport_req[sport_num][0]);
220 return 0;
221} 169}
222 170
223#ifdef CONFIG_PM 171#ifdef CONFIG_PM
224static int bf5xx_i2s_suspend(struct snd_soc_dai *dai) 172static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
225{ 173{
174 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
226 175
227 pr_debug("%s : sport %d\n", __func__, dai->id); 176 pr_debug("%s : sport %d\n", __func__, dai->id);
228 177
@@ -235,19 +184,21 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
235 184
236static int bf5xx_i2s_resume(struct snd_soc_dai *dai) 185static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
237{ 186{
187 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
188 struct bf5xx_i2s_port *bf5xx_i2s = sport_handle->private_data;
238 int ret; 189 int ret;
239 190
240 pr_debug("%s : sport %d\n", __func__, dai->id); 191 pr_debug("%s : sport %d\n", __func__, dai->id);
241 192
242 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1, 193 ret = sport_config_rx(sport_handle, bf5xx_i2s->rcr1,
243 bf5xx_i2s.rcr2, 0, 0); 194 bf5xx_i2s->rcr2, 0, 0);
244 if (ret) { 195 if (ret) {
245 pr_err("SPORT is busy!\n"); 196 pr_err("SPORT is busy!\n");
246 return -EBUSY; 197 return -EBUSY;
247 } 198 }
248 199
249 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1, 200 ret = sport_config_tx(sport_handle, bf5xx_i2s->tcr1,
250 bf5xx_i2s.tcr2, 0, 0); 201 bf5xx_i2s->tcr2, 0, 0);
251 if (ret) { 202 if (ret) {
252 pr_err("SPORT is busy!\n"); 203 pr_err("SPORT is busy!\n");
253 return -EBUSY; 204 return -EBUSY;
@@ -266,8 +217,11 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
266 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ 217 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
267 SNDRV_PCM_RATE_96000) 218 SNDRV_PCM_RATE_96000)
268 219
269#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\ 220#define BF5XX_I2S_FORMATS \
270 SNDRV_PCM_FMTBIT_S32_LE) 221 (SNDRV_PCM_FMTBIT_S8 | \
222 SNDRV_PCM_FMTBIT_S16_LE | \
223 SNDRV_PCM_FMTBIT_S24_LE | \
224 SNDRV_PCM_FMTBIT_S32_LE)
271 225
272static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 226static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
273 .shutdown = bf5xx_i2s_shutdown, 227 .shutdown = bf5xx_i2s_shutdown,
@@ -276,8 +230,6 @@ static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
276}; 230};
277 231
278static struct snd_soc_dai_driver bf5xx_i2s_dai = { 232static struct snd_soc_dai_driver bf5xx_i2s_dai = {
279 .probe = bf5xx_i2s_probe,
280 .remove = bf5xx_i2s_remove,
281 .suspend = bf5xx_i2s_suspend, 233 .suspend = bf5xx_i2s_suspend,
282 .resume = bf5xx_i2s_resume, 234 .resume = bf5xx_i2s_resume,
283 .playback = { 235 .playback = {
@@ -293,23 +245,45 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = {
293 .ops = &bf5xx_i2s_dai_ops, 245 .ops = &bf5xx_i2s_dai_ops,
294}; 246};
295 247
296static int bfin_i2s_drv_probe(struct platform_device *pdev) 248static int __devinit bf5xx_i2s_probe(struct platform_device *pdev)
297{ 249{
298 return snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); 250 struct sport_device *sport_handle;
251 int ret;
252
253 /* configure SPORT for I2S */
254 sport_handle = sport_init(pdev, 4, 2 * sizeof(u32),
255 sizeof(struct bf5xx_i2s_port));
256 if (!sport_handle)
257 return -ENODEV;
258
259 /* register with the ASoC layers */
260 ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai);
261 if (ret) {
262 pr_err("Failed to register DAI: %d\n", ret);
263 sport_done(sport_handle);
264 return ret;
265 }
266
267 return 0;
299} 268}
300 269
301static int __devexit bfin_i2s_drv_remove(struct platform_device *pdev) 270static int __devexit bf5xx_i2s_remove(struct platform_device *pdev)
302{ 271{
272 struct sport_device *sport_handle = platform_get_drvdata(pdev);
273
274 pr_debug("%s enter\n", __func__);
275
303 snd_soc_unregister_dai(&pdev->dev); 276 snd_soc_unregister_dai(&pdev->dev);
277 sport_done(sport_handle);
278
304 return 0; 279 return 0;
305} 280}
306 281
307static struct platform_driver bfin_i2s_driver = { 282static struct platform_driver bfin_i2s_driver = {
308 .probe = bfin_i2s_drv_probe, 283 .probe = bf5xx_i2s_probe,
309 .remove = __devexit_p(bfin_i2s_drv_remove), 284 .remove = __devexit_p(bf5xx_i2s_remove),
310
311 .driver = { 285 .driver = {
312 .name = "bf5xx-i2s", 286 .name = "bfin-i2s",
313 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
314 }, 288 },
315}; 289};
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
index 99051ff0954e..a2d40349fcc4 100644
--- a/sound/soc/blackfin/bf5xx-sport.c
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -42,8 +42,6 @@
42/* delay between frame sync pulse and first data bit in multichannel mode */ 42/* delay between frame sync pulse and first data bit in multichannel mode */
43#define FRAME_DELAY (1<<12) 43#define FRAME_DELAY (1<<12)
44 44
45struct sport_device *sport_handle;
46EXPORT_SYMBOL(sport_handle);
47/* note: multichannel is in units of 8 channels, 45/* note: multichannel is in units of 8 channels,
48 * tdm_count is # channels NOT / 8 ! */ 46 * tdm_count is # channels NOT / 8 ! */
49int sport_set_multichannel(struct sport_device *sport, 47int sport_set_multichannel(struct sport_device *sport,
@@ -798,86 +796,164 @@ int sport_set_err_callback(struct sport_device *sport,
798} 796}
799EXPORT_SYMBOL(sport_set_err_callback); 797EXPORT_SYMBOL(sport_set_err_callback);
800 798
801struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, 799static int sport_config_pdev(struct platform_device *pdev, struct sport_param *param)
802 unsigned dummy_count, void *private_data)
803{ 800{
804 int ret; 801 /* Extract settings from platform data */
802 struct device *dev = &pdev->dev;
803 struct bfin_snd_platform_data *pdata = dev->platform_data;
804 struct resource *res;
805
806 param->num = pdev->id;
807
808 if (!pdata) {
809 dev_err(dev, "no platform_data\n");
810 return -ENODEV;
811 }
812 param->pin_req = pdata->pin_req;
813
814 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
815 if (!res) {
816 dev_err(dev, "no MEM resource\n");
817 return -ENODEV;
818 }
819 param->regs = (struct sport_register *)res->start;
820
821 /* first RX, then TX */
822 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
823 if (!res) {
824 dev_err(dev, "no rx DMA resource\n");
825 return -ENODEV;
826 }
827 param->dma_rx_chan = res->start;
828
829 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
830 if (!res) {
831 dev_err(dev, "no tx DMA resource\n");
832 return -ENODEV;
833 }
834 param->dma_tx_chan = res->start;
835
836 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
837 if (!res) {
838 dev_err(dev, "no irq resource\n");
839 return -ENODEV;
840 }
841 param->err_irq = res->start;
842
843 return 0;
844}
845
846struct sport_device *sport_init(struct platform_device *pdev,
847 unsigned int wdsize, unsigned int dummy_count, size_t priv_size)
848{
849 struct device *dev = &pdev->dev;
850 struct sport_param param;
805 struct sport_device *sport; 851 struct sport_device *sport;
806 pr_debug("%s enter\n", __func__); 852 int ret;
807 BUG_ON(param == NULL); 853
808 BUG_ON(wdsize == 0 || dummy_count == 0); 854 dev_dbg(dev, "%s enter\n", __func__);
809 sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL); 855
810 if (!sport) { 856 param.wdsize = wdsize;
811 pr_err("Failed to allocate for sport device\n"); 857 param.dummy_count = dummy_count;
858 BUG_ON(param.wdsize == 0 || param.dummy_count == 0);
859
860 ret = sport_config_pdev(pdev, &param);
861 if (ret)
862 return NULL;
863
864 if (peripheral_request_list(param.pin_req, "soc-audio")) {
865 dev_err(dev, "requesting Peripherals failed\n");
812 return NULL; 866 return NULL;
813 } 867 }
814 868
815 memset(sport, 0, sizeof(struct sport_device)); 869 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
816 sport->dma_rx_chan = param->dma_rx_chan; 870 if (!sport) {
817 sport->dma_tx_chan = param->dma_tx_chan; 871 dev_err(dev, "failed to allocate for sport device\n");
818 sport->err_irq = param->err_irq; 872 goto __init_err0;
819 sport->regs = param->regs; 873 }
820 sport->private_data = private_data; 874
875 sport->num = param.num;
876 sport->dma_rx_chan = param.dma_rx_chan;
877 sport->dma_tx_chan = param.dma_tx_chan;
878 sport->err_irq = param.err_irq;
879 sport->regs = param.regs;
880 sport->pin_req = param.pin_req;
821 881
822 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) { 882 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
823 pr_err("Failed to request RX dma %d\n", \ 883 dev_err(dev, "failed to request RX dma %d\n", sport->dma_rx_chan);
824 sport->dma_rx_chan);
825 goto __init_err1; 884 goto __init_err1;
826 } 885 }
827 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) { 886 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
828 pr_err("Failed to request RX irq %d\n", \ 887 dev_err(dev, "failed to request RX irq %d\n", sport->dma_rx_chan);
829 sport->dma_rx_chan);
830 goto __init_err2; 888 goto __init_err2;
831 } 889 }
832 890
833 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) { 891 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
834 pr_err("Failed to request TX dma %d\n", \ 892 dev_err(dev, "failed to request TX dma %d\n", sport->dma_tx_chan);
835 sport->dma_tx_chan);
836 goto __init_err2; 893 goto __init_err2;
837 } 894 }
838 895
839 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) { 896 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
840 pr_err("Failed to request TX irq %d\n", \ 897 dev_err(dev, "failed to request TX irq %d\n", sport->dma_tx_chan);
841 sport->dma_tx_chan);
842 goto __init_err3; 898 goto __init_err3;
843 } 899 }
844 900
845 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err", 901 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
846 sport) < 0) { 902 sport) < 0) {
847 pr_err("Failed to request err irq:%d\n", \ 903 dev_err(dev, "failed to request err irq %d\n", sport->err_irq);
848 sport->err_irq);
849 goto __init_err3; 904 goto __init_err3;
850 } 905 }
851 906
852 pr_err("dma rx:%d tx:%d, err irq:%d, regs:%p\n", 907 dev_info(dev, "dma rx:%d tx:%d, err irq:%d, regs:%p\n",
853 sport->dma_rx_chan, sport->dma_tx_chan, 908 sport->dma_rx_chan, sport->dma_tx_chan,
854 sport->err_irq, sport->regs); 909 sport->err_irq, sport->regs);
855 910
856 sport->wdsize = wdsize; 911 sport->wdsize = param.wdsize;
857 sport->dummy_count = dummy_count; 912 sport->dummy_count = param.dummy_count;
913
914 sport->private_data = kzalloc(priv_size, GFP_KERNEL);
915 if (!sport->private_data) {
916 dev_err(dev, "could not alloc priv data %zu bytes\n", priv_size);
917 goto __init_err4;
918 }
858 919
859 if (L1_DATA_A_LENGTH) 920 if (L1_DATA_A_LENGTH)
860 sport->dummy_buf = l1_data_sram_zalloc(dummy_count * 2); 921 sport->dummy_buf = l1_data_sram_zalloc(param.dummy_count * 2);
861 else 922 else
862 sport->dummy_buf = kzalloc(dummy_count * 2, GFP_KERNEL); 923 sport->dummy_buf = kzalloc(param.dummy_count * 2, GFP_KERNEL);
863 if (sport->dummy_buf == NULL) { 924 if (sport->dummy_buf == NULL) {
864 pr_err("Failed to allocate dummy buffer\n"); 925 dev_err(dev, "failed to allocate dummy buffer\n");
865 goto __error; 926 goto __error1;
866 } 927 }
867 928
868 ret = sport_config_rx_dummy(sport); 929 ret = sport_config_rx_dummy(sport);
869 if (ret) { 930 if (ret) {
870 pr_err("Failed to config rx dummy ring\n"); 931 dev_err(dev, "failed to config rx dummy ring\n");
871 goto __error; 932 goto __error2;
872 } 933 }
873 ret = sport_config_tx_dummy(sport); 934 ret = sport_config_tx_dummy(sport);
874 if (ret) { 935 if (ret) {
875 pr_err("Failed to config tx dummy ring\n"); 936 dev_err(dev, "failed to config tx dummy ring\n");
876 goto __error; 937 goto __error3;
877 } 938 }
878 939
940 platform_set_drvdata(pdev, sport);
941
879 return sport; 942 return sport;
880__error: 943__error3:
944 if (L1_DATA_A_LENGTH)
945 l1_data_sram_free(sport->dummy_rx_desc);
946 else
947 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
948 sport->dummy_rx_desc, 0);
949__error2:
950 if (L1_DATA_A_LENGTH)
951 l1_data_sram_free(sport->dummy_buf);
952 else
953 kfree(sport->dummy_buf);
954__error1:
955 kfree(sport->private_data);
956__init_err4:
881 free_irq(sport->err_irq, sport); 957 free_irq(sport->err_irq, sport);
882__init_err3: 958__init_err3:
883 free_dma(sport->dma_tx_chan); 959 free_dma(sport->dma_tx_chan);
@@ -885,6 +961,8 @@ __init_err2:
885 free_dma(sport->dma_rx_chan); 961 free_dma(sport->dma_rx_chan);
886__init_err1: 962__init_err1:
887 kfree(sport); 963 kfree(sport);
964__init_err0:
965 peripheral_free_list(param.pin_req);
888 return NULL; 966 return NULL;
889} 967}
890EXPORT_SYMBOL(sport_init); 968EXPORT_SYMBOL(sport_init);
@@ -917,8 +995,9 @@ void sport_done(struct sport_device *sport)
917 free_dma(sport->dma_tx_chan); 995 free_dma(sport->dma_tx_chan);
918 free_irq(sport->err_irq, sport); 996 free_irq(sport->err_irq, sport);
919 997
998 kfree(sport->private_data);
999 peripheral_free_list(sport->pin_req);
920 kfree(sport); 1000 kfree(sport);
921 sport = NULL;
922} 1001}
923EXPORT_SYMBOL(sport_done); 1002EXPORT_SYMBOL(sport_done);
924 1003
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index a86e8cc0b2d3..5ab60bd613ea 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * File: bf5xx_ac97_sport.h 2 * File: bf5xx_sport.h
3 * Based on: 3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com> 4 * Author: Roy Huang <roy.huang@analog.com>
5 * 5 *
@@ -33,15 +33,18 @@
33#include <linux/types.h> 33#include <linux/types.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <linux/platform_device.h>
36#include <asm/dma.h> 37#include <asm/dma.h>
37#include <asm/bfin_sport.h> 38#include <asm/bfin_sport.h>
38 39
39#define DESC_ELEMENT_COUNT 9 40#define DESC_ELEMENT_COUNT 9
40 41
41struct sport_device { 42struct sport_device {
43 int num;
42 int dma_rx_chan; 44 int dma_rx_chan;
43 int dma_tx_chan; 45 int dma_tx_chan;
44 int err_irq; 46 int err_irq;
47 const unsigned short *pin_req;
45 struct sport_register *regs; 48 struct sport_register *regs;
46 49
47 unsigned char *rx_buf; 50 unsigned char *rx_buf;
@@ -103,17 +106,20 @@ struct sport_device {
103 void *private_data; 106 void *private_data;
104}; 107};
105 108
106extern struct sport_device *sport_handle;
107
108struct sport_param { 109struct sport_param {
110 int num;
109 int dma_rx_chan; 111 int dma_rx_chan;
110 int dma_tx_chan; 112 int dma_tx_chan;
111 int err_irq; 113 int err_irq;
114 const unsigned short *pin_req;
112 struct sport_register *regs; 115 struct sport_register *regs;
116 unsigned int wdsize;
117 unsigned int dummy_count;
118 void *private_data;
113}; 119};
114 120
115struct sport_device *sport_init(struct sport_param *param, unsigned wdsize, 121struct sport_device *sport_init(struct platform_device *pdev,
116 unsigned dummy_count, void *private_data); 122 unsigned int wdsize, unsigned int dummy_count, size_t priv_size);
117 123
118void sport_done(struct sport_device *sport); 124void sport_done(struct sport_device *sport);
119 125
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index ad28663f5bbd..767e772a815d 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,16 +44,6 @@
44 44
45static struct snd_soc_card bf5xx_ssm2602; 45static struct snd_soc_card bf5xx_ssm2602;
46 46
47static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51
52 pr_debug("%s enter\n", __func__);
53 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
54 return 0;
55}
56
57static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 48 struct snd_pcm_hw_params *params)
59{ 49{
@@ -109,23 +99,33 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
109} 99}
110 100
111static struct snd_soc_ops bf5xx_ssm2602_ops = { 101static struct snd_soc_ops bf5xx_ssm2602_ops = {
112 .startup = bf5xx_ssm2602_startup,
113 .hw_params = bf5xx_ssm2602_hw_params, 102 .hw_params = bf5xx_ssm2602_hw_params,
114}; 103};
115 104
116static struct snd_soc_dai_link bf5xx_ssm2602_dai = { 105static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
117 .name = "ssm2602", 106 {
118 .stream_name = "SSM2602", 107 .name = "ssm2602",
119 .cpu_dai_name = "bf5xx-i2s", 108 .stream_name = "SSM2602",
120 .codec_dai_name = "ssm2602-hifi", 109 .cpu_dai_name = "bfin-i2s.0",
121 .platform_name = "bf5xx-pcm-audio", 110 .codec_dai_name = "ssm2602-hifi",
122 .codec_name = "ssm2602-codec.0-001b", 111 .platform_name = "bfin-i2s-pcm-audio",
123 .ops = &bf5xx_ssm2602_ops, 112 .codec_name = "ssm2602.0-001b",
113 .ops = &bf5xx_ssm2602_ops,
114 },
115 {
116 .name = "ssm2602",
117 .stream_name = "SSM2602",
118 .cpu_dai_name = "bfin-i2s.1",
119 .codec_dai_name = "ssm2602-hifi",
120 .platform_name = "bfin-i2s-pcm-audio",
121 .codec_name = "ssm2602.0-001b",
122 .ops = &bf5xx_ssm2602_ops,
123 },
124}; 124};
125 125
126static struct snd_soc_card bf5xx_ssm2602 = { 126static struct snd_soc_card bf5xx_ssm2602 = {
127 .name = "bf5xx_ssm2602", 127 .name = "bfin-ssm2602",
128 .dai_link = &bf5xx_ssm2602_dai, 128 .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM],
129 .num_links = 1, 129 .num_links = 1,
130}; 130};
131 131
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 74cf759b78a6..07cfc7a9e49a 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -154,7 +154,12 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
154 154
155static int bf5xx_pcm_open(struct snd_pcm_substream *substream) 155static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
156{ 156{
157 struct snd_soc_pcm_runtime *rtd = substream->private_data;
158 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
159 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(cpu_dai);
157 struct snd_pcm_runtime *runtime = substream->runtime; 160 struct snd_pcm_runtime *runtime = substream->runtime;
161 struct snd_dma_buffer *buf = &substream->dma_buffer;
162
158 int ret = 0; 163 int ret = 0;
159 164
160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware); 165 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
@@ -164,9 +169,14 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
164 if (ret < 0) 169 if (ret < 0)
165 goto out; 170 goto out;
166 171
167 if (sport_handle != NULL) 172 if (sport_handle != NULL) {
173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
174 sport_handle->tx_buf = buf->area;
175 else
176 sport_handle->rx_buf = buf->area;
177
168 runtime->private_data = sport_handle; 178 runtime->private_data = sport_handle;
169 else { 179 } else {
170 pr_err("sport_handle is NULL\n"); 180 pr_err("sport_handle is NULL\n");
171 ret = -ENODEV; 181 ret = -ENODEV;
172 } 182 }
@@ -249,11 +259,6 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
249 } 259 }
250 buf->bytes = size; 260 buf->bytes = size;
251 261
252 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
253 sport_handle->tx_buf = buf->area;
254 else
255 sport_handle->rx_buf = buf->area;
256
257 return 0; 262 return 0;
258} 263}
259 264
@@ -274,8 +279,6 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
274 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 279 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
275 buf->area = NULL; 280 buf->area = NULL;
276 } 281 }
277 if (sport_handle)
278 sport_done(sport_handle);
279} 282}
280 283
281static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); 284static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
@@ -326,7 +329,7 @@ static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
326 329
327static struct platform_driver bfin_tdm_driver = { 330static struct platform_driver bfin_tdm_driver = {
328 .driver = { 331 .driver = {
329 .name = "bf5xx-tdm-pcm-audio", 332 .name = "bfin-tdm-pcm-audio",
330 .owner = THIS_MODULE, 333 .owner = THIS_MODULE,
331 }, 334 },
332 335
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 5515ac9e05c7..a822d1ee1380 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -46,43 +46,6 @@
46#include "bf5xx-sport.h" 46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h" 47#include "bf5xx-tdm.h"
48 48
49static struct bf5xx_tdm_port bf5xx_tdm;
50static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
51
52static struct sport_param sport_params[2] = {
53 {
54 .dma_rx_chan = CH_SPORT0_RX,
55 .dma_tx_chan = CH_SPORT0_TX,
56 .err_irq = IRQ_SPORT0_ERROR,
57 .regs = (struct sport_register *)SPORT0_TCR1,
58 },
59 {
60 .dma_rx_chan = CH_SPORT1_RX,
61 .dma_tx_chan = CH_SPORT1_TX,
62 .err_irq = IRQ_SPORT1_ERROR,
63 .regs = (struct sport_register *)SPORT1_TCR1,
64 }
65};
66
67/*
68 * Setting the TFS pin selector for SPORT 0 based on whether the selected
69 * port id F or G. If the port is F then no conflict should exist for the
70 * TFS. When Port G is selected and EMAC then there is a conflict between
71 * the PHY interrupt line and TFS. Current settings prevent the conflict
72 * by ignoring the TFS pin when Port G is selected. This allows both
73 * codecs and EMAC using Port G concurrently.
74 */
75#ifdef CONFIG_BF527_SPORT0_PORTG
76#define LOCAL_SPORT0_TFS (0)
77#else
78#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
79#endif
80
81static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
82 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
83 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
84 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
85
86static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai, 49static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
87 unsigned int fmt) 50 unsigned int fmt)
88{ 51{
@@ -119,14 +82,16 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params, 82 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai) 83 struct snd_soc_dai *dai)
121{ 84{
85 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
86 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
122 int ret = 0; 87 int ret = 0;
123 88
124 bf5xx_tdm.tcr2 &= ~0x1f; 89 bf5xx_tdm->tcr2 &= ~0x1f;
125 bf5xx_tdm.rcr2 &= ~0x1f; 90 bf5xx_tdm->rcr2 &= ~0x1f;
126 switch (params_format(params)) { 91 switch (params_format(params)) {
127 case SNDRV_PCM_FORMAT_S32_LE: 92 case SNDRV_PCM_FORMAT_S32_LE:
128 bf5xx_tdm.tcr2 |= 31; 93 bf5xx_tdm->tcr2 |= 31;
129 bf5xx_tdm.rcr2 |= 31; 94 bf5xx_tdm->rcr2 |= 31;
130 sport_handle->wdsize = 4; 95 sport_handle->wdsize = 4;
131 break; 96 break;
132 /* at present, we only support 32bit transfer */ 97 /* at present, we only support 32bit transfer */
@@ -136,7 +101,7 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
136 break; 101 break;
137 } 102 }
138 103
139 if (!bf5xx_tdm.configured) { 104 if (!bf5xx_tdm->configured) {
140 /* 105 /*
141 * TX and RX are not independent,they are enabled at the 106 * TX and RX are not independent,they are enabled at the
142 * same time, even if only one side is running. So, we 107 * same time, even if only one side is running. So, we
@@ -145,21 +110,21 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
145 * 110 *
146 * CPU DAI:slave mode. 111 * CPU DAI:slave mode.
147 */ 112 */
148 ret = sport_config_rx(sport_handle, bf5xx_tdm.rcr1, 113 ret = sport_config_rx(sport_handle, bf5xx_tdm->rcr1,
149 bf5xx_tdm.rcr2, 0, 0); 114 bf5xx_tdm->rcr2, 0, 0);
150 if (ret) { 115 if (ret) {
151 pr_err("SPORT is busy!\n"); 116 pr_err("SPORT is busy!\n");
152 return -EBUSY; 117 return -EBUSY;
153 } 118 }
154 119
155 ret = sport_config_tx(sport_handle, bf5xx_tdm.tcr1, 120 ret = sport_config_tx(sport_handle, bf5xx_tdm->tcr1,
156 bf5xx_tdm.tcr2, 0, 0); 121 bf5xx_tdm->tcr2, 0, 0);
157 if (ret) { 122 if (ret) {
158 pr_err("SPORT is busy!\n"); 123 pr_err("SPORT is busy!\n");
159 return -EBUSY; 124 return -EBUSY;
160 } 125 }
161 126
162 bf5xx_tdm.configured = 1; 127 bf5xx_tdm->configured = 1;
163 } 128 }
164 129
165 return 0; 130 return 0;
@@ -168,15 +133,20 @@ static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
168static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream, 133static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *dai) 134 struct snd_soc_dai *dai)
170{ 135{
136 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
137 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
138
171 /* No active stream, SPORT is allowed to be configured again. */ 139 /* No active stream, SPORT is allowed to be configured again. */
172 if (!dai->active) 140 if (!dai->active)
173 bf5xx_tdm.configured = 0; 141 bf5xx_tdm->configured = 0;
174} 142}
175 143
176static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai, 144static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
177 unsigned int tx_num, unsigned int *tx_slot, 145 unsigned int tx_num, unsigned int *tx_slot,
178 unsigned int rx_num, unsigned int *rx_slot) 146 unsigned int rx_num, unsigned int *rx_slot)
179{ 147{
148 struct sport_device *sport_handle = snd_soc_dai_get_drvdata(dai);
149 struct bf5xx_tdm_port *bf5xx_tdm = sport_handle->private_data;
180 int i; 150 int i;
181 unsigned int slot; 151 unsigned int slot;
182 unsigned int tx_mapped = 0, rx_mapped = 0; 152 unsigned int tx_mapped = 0, rx_mapped = 0;
@@ -189,7 +159,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
189 slot = tx_slot[i]; 159 slot = tx_slot[i];
190 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && 160 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
191 (!(tx_mapped & (1 << slot)))) { 161 (!(tx_mapped & (1 << slot)))) {
192 bf5xx_tdm.tx_map[i] = slot; 162 bf5xx_tdm->tx_map[i] = slot;
193 tx_mapped |= 1 << slot; 163 tx_mapped |= 1 << slot;
194 } else 164 } else
195 return -EINVAL; 165 return -EINVAL;
@@ -198,7 +168,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
198 slot = rx_slot[i]; 168 slot = rx_slot[i];
199 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) && 169 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
200 (!(rx_mapped & (1 << slot)))) { 170 (!(rx_mapped & (1 << slot)))) {
201 bf5xx_tdm.rx_map[i] = slot; 171 bf5xx_tdm->rx_map[i] = slot;
202 rx_mapped |= 1 << slot; 172 rx_mapped |= 1 << slot;
203 } else 173 } else
204 return -EINVAL; 174 return -EINVAL;
@@ -212,12 +182,14 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
212{ 182{
213 struct sport_device *sport = snd_soc_dai_get_drvdata(dai); 183 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
214 184
215 if (!dai->active)
216 return 0;
217 if (dai->capture_active)
218 sport_rx_stop(sport);
219 if (dai->playback_active) 185 if (dai->playback_active)
220 sport_tx_stop(sport); 186 sport_tx_stop(sport);
187 if (dai->capture_active)
188 sport_rx_stop(sport);
189
190 /* isolate sync/clock pins from codec while sports resume */
191 peripheral_free_list(sport->pin_req);
192
221 return 0; 193 return 0;
222} 194}
223 195
@@ -226,9 +198,6 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
226 int ret; 198 int ret;
227 struct sport_device *sport = snd_soc_dai_get_drvdata(dai); 199 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
228 200
229 if (!dai->active)
230 return 0;
231
232 ret = sport_set_multichannel(sport, 8, 0xFF, 1); 201 ret = sport_set_multichannel(sport, 8, 0xFF, 1);
233 if (ret) { 202 if (ret) {
234 pr_err("SPORT is busy!\n"); 203 pr_err("SPORT is busy!\n");
@@ -247,6 +216,8 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
247 ret = -EBUSY; 216 ret = -EBUSY;
248 } 217 }
249 218
219 peripheral_request_list(sport->pin_req, "soc-audio");
220
250 return 0; 221 return 0;
251} 222}
252 223
@@ -280,20 +251,14 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = {
280 251
281static int __devinit bfin_tdm_probe(struct platform_device *pdev) 252static int __devinit bfin_tdm_probe(struct platform_device *pdev)
282{ 253{
283 int ret = 0; 254 struct sport_device *sport_handle;
284 255 int ret;
285 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
286 pr_err("Requesting Peripherals failed\n");
287 return -EFAULT;
288 }
289 256
290 /* request DMA for SPORT */ 257 /* configure SPORT for TDM */
291 sport_handle = sport_init(&sport_params[sport_num], 4, \ 258 sport_handle = sport_init(pdev, 4, 8 * sizeof(u32),
292 8 * sizeof(u32), NULL); 259 sizeof(struct bf5xx_tdm_port));
293 if (!sport_handle) { 260 if (!sport_handle)
294 peripheral_free_list(&sport_req[sport_num][0]);
295 return -ENODEV; 261 return -ENODEV;
296 }
297 262
298 /* SPORT works in TDM mode */ 263 /* SPORT works in TDM mode */
299 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1); 264 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
@@ -323,18 +288,19 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
323 goto sport_config_err; 288 goto sport_config_err;
324 } 289 }
325 290
326 sport_handle->private_data = &bf5xx_tdm;
327 return 0; 291 return 0;
328 292
329sport_config_err: 293sport_config_err:
330 peripheral_free_list(&sport_req[sport_num][0]); 294 sport_done(sport_handle);
331 return ret; 295 return ret;
332} 296}
333 297
334static int __devexit bfin_tdm_remove(struct platform_device *pdev) 298static int __devexit bfin_tdm_remove(struct platform_device *pdev)
335{ 299{
336 peripheral_free_list(&sport_req[sport_num][0]); 300 struct sport_device *sport_handle = platform_get_drvdata(pdev);
301
337 snd_soc_unregister_dai(&pdev->dev); 302 snd_soc_unregister_dai(&pdev->dev);
303 sport_done(sport_handle);
338 304
339 return 0; 305 return 0;
340} 306}
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6943e24a74a1..2a6971891d31 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -16,8 +16,8 @@ config SND_SOC_ALL_CODECS
16 select SND_SOC_AD1836 if SPI_MASTER 16 select SND_SOC_AD1836 if SPI_MASTER
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311
19 select SND_SOC_ADS117X 20 select SND_SOC_ADS117X
20 select SND_SOC_AD73311 if I2C
21 select SND_SOC_AK4104 if SPI_MASTER 21 select SND_SOC_AK4104 if SPI_MASTER
22 select SND_SOC_AK4535 if I2C 22 select SND_SOC_AK4535 if I2C
23 select SND_SOC_AK4642 if I2C 23 select SND_SOC_AK4642 if I2C
@@ -33,13 +33,14 @@ config SND_SOC_ALL_CODECS
33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740 33 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
34 select SND_SOC_LM4857 if I2C 34 select SND_SOC_LM4857 if I2C
35 select SND_SOC_MAX98088 if I2C 35 select SND_SOC_MAX98088 if I2C
36 select SND_SOC_MAX98095 if I2C
36 select SND_SOC_MAX9850 if I2C 37 select SND_SOC_MAX9850 if I2C
37 select SND_SOC_MAX9877 if I2C 38 select SND_SOC_MAX9877 if I2C
38 select SND_SOC_PCM3008 39 select SND_SOC_PCM3008
39 select SND_SOC_SGTL5000 if I2C 40 select SND_SOC_SGTL5000 if I2C
40 select SND_SOC_SN95031 if INTEL_SCU_IPC 41 select SND_SOC_SN95031 if INTEL_SCU_IPC
41 select SND_SOC_SPDIF 42 select SND_SOC_SPDIF
42 select SND_SOC_SSM2602 if I2C 43 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
43 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 44 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
44 select SND_SOC_TLV320AIC23 if I2C 45 select SND_SOC_TLV320AIC23 if I2C
45 select SND_SOC_TLV320AIC26 if SPI_MASTER 46 select SND_SOC_TLV320AIC26 if SPI_MASTER
@@ -52,6 +53,7 @@ config SND_SOC_ALL_CODECS
52 select SND_SOC_UDA134X 53 select SND_SOC_UDA134X
53 select SND_SOC_UDA1380 if I2C 54 select SND_SOC_UDA1380 if I2C
54 select SND_SOC_WL1273 if MFD_WL1273_CORE 55 select SND_SOC_WL1273 if MFD_WL1273_CORE
56 select SND_SOC_WM1250_EV1 if I2C
55 select SND_SOC_WM2000 if I2C 57 select SND_SOC_WM2000 if I2C
56 select SND_SOC_WM8350 if MFD_WM8350 58 select SND_SOC_WM8350 if MFD_WM8350
57 select SND_SOC_WM8400 if MFD_WM8400 59 select SND_SOC_WM8400 if MFD_WM8400
@@ -72,6 +74,7 @@ config SND_SOC_ALL_CODECS
72 select SND_SOC_WM8900 if I2C 74 select SND_SOC_WM8900 if I2C
73 select SND_SOC_WM8903 if I2C 75 select SND_SOC_WM8903 if I2C
74 select SND_SOC_WM8904 if I2C 76 select SND_SOC_WM8904 if I2C
77 select SND_SOC_WM8915 if I2C
75 select SND_SOC_WM8940 if I2C 78 select SND_SOC_WM8940 if I2C
76 select SND_SOC_WM8955 if I2C 79 select SND_SOC_WM8955 if I2C
77 select SND_SOC_WM8960 if I2C 80 select SND_SOC_WM8960 if I2C
@@ -187,6 +190,9 @@ config SND_SOC_DMIC
187config SND_SOC_MAX98088 190config SND_SOC_MAX98088
188 tristate 191 tristate
189 192
193config SND_SOC_MAX98095
194 tristate
195
190config SND_SOC_MAX9850 196config SND_SOC_MAX9850
191 tristate 197 tristate
192 198
@@ -241,6 +247,9 @@ config SND_SOC_UDA1380
241config SND_SOC_WL1273 247config SND_SOC_WL1273
242 tristate 248 tristate
243 249
250config SND_SOC_WM1250_EV1
251 tristate
252
244config SND_SOC_WM8350 253config SND_SOC_WM8350
245 tristate 254 tristate
246 255
@@ -298,6 +307,9 @@ config SND_SOC_WM8903
298config SND_SOC_WM8904 307config SND_SOC_WM8904
299 tristate 308 tristate
300 309
310config SND_SOC_WM8915
311 tristate
312
301config SND_SOC_WM8940 313config SND_SOC_WM8940
302 tristate 314 tristate
303 315
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 379bc55f0723..4cb2f42dbffa 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -19,6 +19,7 @@ snd-soc-dfbmcs320-objs := dfbmcs320.o
19snd-soc-dmic-objs := dmic.o 19snd-soc-dmic-objs := dmic.o
20snd-soc-l3-objs := l3.o 20snd-soc-l3-objs := l3.o
21snd-soc-max98088-objs := max98088.o 21snd-soc-max98088-objs := max98088.o
22snd-soc-max98095-objs := max98095.o
22snd-soc-max9850-objs := max9850.o 23snd-soc-max9850-objs := max9850.o
23snd-soc-pcm3008-objs := pcm3008.o 24snd-soc-pcm3008-objs := pcm3008.o
24snd-soc-sgtl5000-objs := sgtl5000.o 25snd-soc-sgtl5000-objs := sgtl5000.o
@@ -37,6 +38,7 @@ snd-soc-twl6040-objs := twl6040.o
37snd-soc-uda134x-objs := uda134x.o 38snd-soc-uda134x-objs := uda134x.o
38snd-soc-uda1380-objs := uda1380.o 39snd-soc-uda1380-objs := uda1380.o
39snd-soc-wl1273-objs := wl1273.o 40snd-soc-wl1273-objs := wl1273.o
41snd-soc-wm1250-ev1-objs := wm1250-ev1.o
40snd-soc-wm8350-objs := wm8350.o 42snd-soc-wm8350-objs := wm8350.o
41snd-soc-wm8400-objs := wm8400.o 43snd-soc-wm8400-objs := wm8400.o
42snd-soc-wm8510-objs := wm8510.o 44snd-soc-wm8510-objs := wm8510.o
@@ -56,6 +58,7 @@ snd-soc-wm8804-objs := wm8804.o
56snd-soc-wm8900-objs := wm8900.o 58snd-soc-wm8900-objs := wm8900.o
57snd-soc-wm8903-objs := wm8903.o 59snd-soc-wm8903-objs := wm8903.o
58snd-soc-wm8904-objs := wm8904.o 60snd-soc-wm8904-objs := wm8904.o
61snd-soc-wm8915-objs := wm8915.o
59snd-soc-wm8940-objs := wm8940.o 62snd-soc-wm8940-objs := wm8940.o
60snd-soc-wm8955-objs := wm8955.o 63snd-soc-wm8955-objs := wm8955.o
61snd-soc-wm8960-objs := wm8960.o 64snd-soc-wm8960-objs := wm8960.o
@@ -69,7 +72,7 @@ snd-soc-wm8988-objs := wm8988.o
69snd-soc-wm8990-objs := wm8990.o 72snd-soc-wm8990-objs := wm8990.o
70snd-soc-wm8991-objs := wm8991.o 73snd-soc-wm8991-objs := wm8991.o
71snd-soc-wm8993-objs := wm8993.o 74snd-soc-wm8993-objs := wm8993.o
72snd-soc-wm8994-objs := wm8994.o wm8994-tables.o 75snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o
73snd-soc-wm8995-objs := wm8995.o 76snd-soc-wm8995-objs := wm8995.o
74snd-soc-wm9081-objs := wm9081.o 77snd-soc-wm9081-objs := wm9081.o
75snd-soc-wm9705-objs := wm9705.o 78snd-soc-wm9705-objs := wm9705.o
@@ -108,6 +111,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
108obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 111obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
109obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 112obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
110obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 113obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
114obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
111obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 115obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
112obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 116obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
113obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 117obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
@@ -125,6 +129,7 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
125obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 129obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
126obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 130obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
127obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 131obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
132obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
128obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 133obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
129obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 134obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
130obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 135obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
@@ -144,6 +149,7 @@ obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
144obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 149obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
145obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 150obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
146obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o 151obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
152obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o
147obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 153obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
148obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o 154obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
149obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 155obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index da46479bfcfa..2374ca5ffe68 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,8 +23,7 @@
23 23
24/* codec private data */ 24/* codec private data */
25struct ad193x_priv { 25struct ad193x_priv {
26 enum snd_soc_control_type bus_type; 26 enum snd_soc_control_type control_type;
27 void *control_data;
28 int sysclk; 27 int sysclk;
29}; 28};
30 29
@@ -354,14 +353,12 @@ static int ad193x_probe(struct snd_soc_codec *codec)
354 struct snd_soc_dapm_context *dapm = &codec->dapm; 353 struct snd_soc_dapm_context *dapm = &codec->dapm;
355 int ret; 354 int ret;
356 355
357 codec->control_data = ad193x->control_data; 356 if (ad193x->control_type == SND_SOC_I2C)
358 if (ad193x->bus_type == SND_SOC_I2C) 357 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type);
359 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
360 else 358 else
361 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type); 359 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
362 if (ret < 0) { 360 if (ret < 0) {
363 dev_err(codec->dev, "failed to set cache I/O: %d\n", 361 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
364 ret);
365 return ret; 362 return ret;
366 } 363 }
367 364
@@ -408,8 +405,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi)
408 return -ENOMEM; 405 return -ENOMEM;
409 406
410 spi_set_drvdata(spi, ad193x); 407 spi_set_drvdata(spi, ad193x);
411 ad193x->control_data = spi; 408 ad193x->control_type = SND_SOC_SPI;
412 ad193x->bus_type = SND_SOC_SPI;
413 409
414 ret = snd_soc_register_codec(&spi->dev, 410 ret = snd_soc_register_codec(&spi->dev,
415 &soc_codec_dev_ad193x, &ad193x_dai, 1); 411 &soc_codec_dev_ad193x, &ad193x_dai, 1);
@@ -427,7 +423,7 @@ static int __devexit ad193x_spi_remove(struct spi_device *spi)
427 423
428static struct spi_driver ad193x_spi_driver = { 424static struct spi_driver ad193x_spi_driver = {
429 .driver = { 425 .driver = {
430 .name = "ad193x-codec", 426 .name = "ad193x",
431 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
432 }, 428 },
433 .probe = ad193x_spi_probe, 429 .probe = ad193x_spi_probe,
@@ -454,8 +450,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client,
454 return -ENOMEM; 450 return -ENOMEM;
455 451
456 i2c_set_clientdata(client, ad193x); 452 i2c_set_clientdata(client, ad193x);
457 ad193x->control_data = client; 453 ad193x->control_type = SND_SOC_I2C;
458 ad193x->bus_type = SND_SOC_I2C;
459 454
460 ret = snd_soc_register_codec(&client->dev, 455 ret = snd_soc_register_codec(&client->dev,
461 &soc_codec_dev_ad193x, &ad193x_dai, 1); 456 &soc_codec_dev_ad193x, &ad193x_dai, 1);
@@ -473,7 +468,7 @@ static int __devexit ad193x_i2c_remove(struct i2c_client *client)
473 468
474static struct i2c_driver ad193x_i2c_driver = { 469static struct i2c_driver ad193x_i2c_driver = {
475 .driver = { 470 .driver = {
476 .name = "ad193x-codec", 471 .name = "ad193x",
477 }, 472 },
478 .probe = ad193x_i2c_probe, 473 .probe = ad193x_i2c_probe,
479 .remove = __devexit_p(ad193x_i2c_remove), 474 .remove = __devexit_p(ad193x_i2c_remove),
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 34cb51ef2156..923b364a3e41 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -266,7 +266,7 @@ static int __devexit ad1980_remove(struct platform_device *pdev)
266 266
267static struct platform_driver ad1980_codec_driver = { 267static struct platform_driver ad1980_codec_driver = {
268 .driver = { 268 .driver = {
269 .name = "ad1980-codec", 269 .name = "ad1980",
270 .owner = THIS_MODULE, 270 .owner = THIS_MODULE,
271 }, 271 },
272 272
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index de799cd1ba72..8d793e993e9a 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -55,7 +55,7 @@ static int __devexit ad73311_remove(struct platform_device *pdev)
55 55
56static struct platform_driver ad73311_codec_driver = { 56static struct platform_driver ad73311_codec_driver = {
57 .driver = { 57 .driver = {
58 .name = "ad73311-codec", 58 .name = "ad73311",
59 .owner = THIS_MODULE, 59 .owner = THIS_MODULE,
60 }, 60 },
61 61
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 8b38739c88f8..e1a214ee757f 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -230,7 +230,7 @@ static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
230 SND_SOC_DAPM_INPUT("AIN"), 230 SND_SOC_DAPM_INPUT("AIN"),
231}; 231};
232 232
233static const struct snd_soc_dapm_route audio_map[] = { 233static const struct snd_soc_dapm_route ak4535_audio_map[] = {
234 /*stereo mixer */ 234 /*stereo mixer */
235 {"Stereo Mixer", "Playback Switch", "DAC"}, 235 {"Stereo Mixer", "Playback Switch", "DAC"},
236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, 236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
@@ -287,17 +287,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
287 {"Input Mixer", "Aux Capture Switch", "Aux In"}, 287 {"Input Mixer", "Aux Capture Switch", "Aux In"},
288}; 288};
289 289
290static int ak4535_add_widgets(struct snd_soc_codec *codec)
291{
292 struct snd_soc_dapm_context *dapm = &codec->dapm;
293
294 snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
295 ARRAY_SIZE(ak4535_dapm_widgets));
296 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
297
298 return 0;
299}
300
301static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, 290static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
302 int clk_id, unsigned int freq, int dir) 291 int clk_id, unsigned int freq, int dir)
303{ 292{
@@ -457,8 +446,6 @@ static int ak4535_probe(struct snd_soc_codec *codec)
457 446
458 snd_soc_add_controls(codec, ak4535_snd_controls, 447 snd_soc_add_controls(codec, ak4535_snd_controls,
459 ARRAY_SIZE(ak4535_snd_controls)); 448 ARRAY_SIZE(ak4535_snd_controls));
460 ak4535_add_widgets(codec);
461
462 return 0; 449 return 0;
463} 450}
464 451
@@ -480,6 +467,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
480 .reg_cache_size = ARRAY_SIZE(ak4535_reg), 467 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
481 .reg_word_size = sizeof(u8), 468 .reg_word_size = sizeof(u8),
482 .reg_cache_default = ak4535_reg, 469 .reg_cache_default = ak4535_reg,
470 .dapm_widgets = ak4535_dapm_widgets,
471 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
472 .dapm_routes = ak4535_audio_map,
473 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
483}; 474};
484 475
485#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 476#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 2ec75abfa3e9..88b29f8c748b 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -352,7 +352,7 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0), 352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
353}; 353};
354 354
355static const struct snd_soc_dapm_route intercon[] = { 355static const struct snd_soc_dapm_route ak4671_intercon[] = {
356 {"DAC Left", "NULL", "PMPLL"}, 356 {"DAC Left", "NULL", "PMPLL"},
357 {"DAC Right", "NULL", "PMPLL"}, 357 {"DAC Right", "NULL", "PMPLL"},
358 {"ADC Left", "NULL", "PMPLL"}, 358 {"ADC Left", "NULL", "PMPLL"},
@@ -433,17 +433,6 @@ static const struct snd_soc_dapm_route intercon[] = {
433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"}, 433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
434}; 434};
435 435
436static int ak4671_add_widgets(struct snd_soc_codec *codec)
437{
438 struct snd_soc_dapm_context *dapm = &codec->dapm;
439
440 snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
443
444 return 0;
445}
446
447static int ak4671_hw_params(struct snd_pcm_substream *substream, 436static int ak4671_hw_params(struct snd_pcm_substream *substream,
448 struct snd_pcm_hw_params *params, 437 struct snd_pcm_hw_params *params,
449 struct snd_soc_dai *dai) 438 struct snd_soc_dai *dai)
@@ -650,7 +639,6 @@ static int ak4671_probe(struct snd_soc_codec *codec)
650 639
651 snd_soc_add_controls(codec, ak4671_snd_controls, 640 snd_soc_add_controls(codec, ak4671_snd_controls,
652 ARRAY_SIZE(ak4671_snd_controls)); 641 ARRAY_SIZE(ak4671_snd_controls));
653 ak4671_add_widgets(codec);
654 642
655 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 643 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
656 644
@@ -670,6 +658,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
670 .reg_cache_size = AK4671_CACHEREGNUM, 658 .reg_cache_size = AK4671_CACHEREGNUM,
671 .reg_word_size = sizeof(u8), 659 .reg_word_size = sizeof(u8),
672 .reg_cache_default = ak4671_reg, 660 .reg_cache_default = ak4671_reg,
661 .dapm_widgets = ak4671_dapm_widgets,
662 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
663 .dapm_routes = ak4671_intercon,
664 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
673}; 665};
674 666
675static int __devinit ak4671_i2c_probe(struct i2c_client *client, 667static int __devinit ak4671_i2c_probe(struct i2c_client *client,
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 0bb424af956f..d68ea532cc7f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -86,18 +86,6 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
86 {"ADC", NULL, "Input Mixer"}, 86 {"ADC", NULL, "Input Mixer"},
87}; 87};
88 88
89static int cx20442_add_widgets(struct snd_soc_codec *codec)
90{
91 struct snd_soc_dapm_context *dapm = &codec->dapm;
92
93 snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets,
94 ARRAY_SIZE(cx20442_dapm_widgets));
95 snd_soc_dapm_add_routes(dapm, cx20442_audio_map,
96 ARRAY_SIZE(cx20442_audio_map));
97
98 return 0;
99}
100
101static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, 89static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
102 unsigned int reg) 90 unsigned int reg)
103{ 91{
@@ -344,8 +332,6 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
344 return -ENOMEM; 332 return -ENOMEM;
345 snd_soc_codec_set_drvdata(codec, cx20442); 333 snd_soc_codec_set_drvdata(codec, cx20442);
346 334
347 cx20442_add_widgets(codec);
348
349 cx20442->control_data = NULL; 335 cx20442->control_data = NULL;
350 codec->hw_write = NULL; 336 codec->hw_write = NULL;
351 codec->card->pop_time = 0; 337 codec->card->pop_time = 0;
@@ -377,6 +363,10 @@ static struct snd_soc_codec_driver cx20442_codec_dev = {
377 .reg_word_size = sizeof(u8), 363 .reg_word_size = sizeof(u8),
378 .read = cx20442_read_reg_cache, 364 .read = cx20442_read_reg_cache,
379 .write = cx20442_write, 365 .write = cx20442_write,
366 .dapm_widgets = cx20442_dapm_widgets,
367 .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
368 .dapm_routes = cx20442_audio_map,
369 .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
380}; 370};
381 371
382static int cx20442_platform_probe(struct platform_device *pdev) 372static int cx20442_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index f5ccdbf7ebc6..e373f8f06907 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -294,20 +294,9 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
294 294
295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) 295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
296{ 296{
297 struct snd_soc_dapm_context *dapm = &codec->dapm;
298
299 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, 297 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
300 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); 298 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
301 299
302 snd_soc_add_controls(codec, jz4740_codec_controls,
303 ARRAY_SIZE(jz4740_codec_controls));
304
305 snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets,
306 ARRAY_SIZE(jz4740_codec_dapm_widgets));
307
308 snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes,
309 ARRAY_SIZE(jz4740_codec_dapm_routes));
310
311 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 300 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
312 301
313 return 0; 302 return 0;
@@ -348,6 +337,13 @@ static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
348 .reg_cache_default = jz4740_codec_regs, 337 .reg_cache_default = jz4740_codec_regs,
349 .reg_word_size = sizeof(u32), 338 .reg_word_size = sizeof(u32),
350 .reg_cache_size = 2, 339 .reg_cache_size = 2,
340
341 .controls = jz4740_codec_controls,
342 .num_controls = ARRAY_SIZE(jz4740_codec_controls),
343 .dapm_widgets = jz4740_codec_dapm_widgets,
344 .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
345 .dapm_routes = jz4740_codec_dapm_routes,
346 .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
351}; 347};
352 348
353static int __devinit jz4740_codec_probe(struct platform_device *pdev) 349static int __devinit jz4740_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index bd0517cb7980..bb58bdb49853 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1112,7 +1112,7 @@ static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
1112 SND_SOC_DAPM_INPUT("INB2"), 1112 SND_SOC_DAPM_INPUT("INB2"),
1113}; 1113};
1114 1114
1115static const struct snd_soc_dapm_route audio_map[] = { 1115static const struct snd_soc_dapm_route max98088_audio_map[] = {
1116 /* Left headphone output mixer */ 1116 /* Left headphone output mixer */
1117 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"}, 1117 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"},
1118 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"}, 1118 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"},
@@ -1226,22 +1226,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
1226 {"MIC2 Input", NULL, "MIC2"}, 1226 {"MIC2 Input", NULL, "MIC2"},
1227}; 1227};
1228 1228
1229static int max98088_add_widgets(struct snd_soc_codec *codec)
1230{
1231 struct snd_soc_dapm_context *dapm = &codec->dapm;
1232
1233 snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets,
1234 ARRAY_SIZE(max98088_dapm_widgets));
1235
1236 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1237
1238 snd_soc_add_controls(codec, max98088_snd_controls,
1239 ARRAY_SIZE(max98088_snd_controls));
1240
1241 snd_soc_dapm_new_widgets(dapm);
1242 return 0;
1243}
1244
1245/* codec mclk clock divider coefficients */ 1229/* codec mclk clock divider coefficients */
1246static const struct { 1230static const struct {
1247 u32 rate; 1231 u32 rate;
@@ -2010,7 +1994,8 @@ static int max98088_probe(struct snd_soc_codec *codec)
2010 1994
2011 max98088_handle_pdata(codec); 1995 max98088_handle_pdata(codec);
2012 1996
2013 max98088_add_widgets(codec); 1997 snd_soc_add_controls(codec, max98088_snd_controls,
1998 ARRAY_SIZE(max98088_snd_controls));
2014 1999
2015err_access: 2000err_access:
2016 return ret; 2001 return ret;
@@ -2036,6 +2021,10 @@ static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
2036 .reg_word_size = sizeof(u8), 2021 .reg_word_size = sizeof(u8),
2037 .reg_cache_default = max98088_reg, 2022 .reg_cache_default = max98088_reg,
2038 .volatile_register = max98088_volatile_register, 2023 .volatile_register = max98088_volatile_register,
2024 .dapm_widgets = max98088_dapm_widgets,
2025 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
2026 .dapm_routes = max98088_audio_map,
2027 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
2039}; 2028};
2040 2029
2041static int max98088_i2c_probe(struct i2c_client *i2c, 2030static int max98088_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
new file mode 100644
index 000000000000..9c77f17a6afb
--- /dev/null
+++ b/sound/soc/codecs/max98095.c
@@ -0,0 +1,2009 @@
1/*
2 * max98095.c -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <linux/slab.h>
26#include <asm/div64.h>
27#include <sound/max98095.h>
28#include "max98095.h"
29
30enum max98095_type {
31 MAX98095,
32};
33
34struct max98095_cdata {
35 unsigned int rate;
36 unsigned int fmt;
37};
38
39struct max98095_priv {
40 enum max98095_type devtype;
41 void *control_data;
42 struct max98095_pdata *pdata;
43 unsigned int sysclk;
44 struct max98095_cdata dai[3];
45 u8 lin_state;
46 unsigned int mic1pre;
47 unsigned int mic2pre;
48};
49
50static const u8 max98095_reg_def[M98095_REG_CNT] = {
51 0x00, /* 00 */
52 0x00, /* 01 */
53 0x00, /* 02 */
54 0x00, /* 03 */
55 0x00, /* 04 */
56 0x00, /* 05 */
57 0x00, /* 06 */
58 0x00, /* 07 */
59 0x00, /* 08 */
60 0x00, /* 09 */
61 0x00, /* 0A */
62 0x00, /* 0B */
63 0x00, /* 0C */
64 0x00, /* 0D */
65 0x00, /* 0E */
66 0x00, /* 0F */
67 0x00, /* 10 */
68 0x00, /* 11 */
69 0x00, /* 12 */
70 0x00, /* 13 */
71 0x00, /* 14 */
72 0x00, /* 15 */
73 0x00, /* 16 */
74 0x00, /* 17 */
75 0x00, /* 18 */
76 0x00, /* 19 */
77 0x00, /* 1A */
78 0x00, /* 1B */
79 0x00, /* 1C */
80 0x00, /* 1D */
81 0x00, /* 1E */
82 0x00, /* 1F */
83 0x00, /* 20 */
84 0x00, /* 21 */
85 0x00, /* 22 */
86 0x00, /* 23 */
87 0x00, /* 24 */
88 0x00, /* 25 */
89 0x00, /* 26 */
90 0x00, /* 27 */
91 0x00, /* 28 */
92 0x00, /* 29 */
93 0x00, /* 2A */
94 0x00, /* 2B */
95 0x00, /* 2C */
96 0x00, /* 2D */
97 0x00, /* 2E */
98 0x00, /* 2F */
99 0x00, /* 30 */
100 0x00, /* 31 */
101 0x00, /* 32 */
102 0x00, /* 33 */
103 0x00, /* 34 */
104 0x00, /* 35 */
105 0x00, /* 36 */
106 0x00, /* 37 */
107 0x00, /* 38 */
108 0x00, /* 39 */
109 0x00, /* 3A */
110 0x00, /* 3B */
111 0x00, /* 3C */
112 0x00, /* 3D */
113 0x00, /* 3E */
114 0x00, /* 3F */
115 0x00, /* 40 */
116 0x00, /* 41 */
117 0x00, /* 42 */
118 0x00, /* 43 */
119 0x00, /* 44 */
120 0x00, /* 45 */
121 0x00, /* 46 */
122 0x00, /* 47 */
123 0x00, /* 48 */
124 0x00, /* 49 */
125 0x00, /* 4A */
126 0x00, /* 4B */
127 0x00, /* 4C */
128 0x00, /* 4D */
129 0x00, /* 4E */
130 0x00, /* 4F */
131 0x00, /* 50 */
132 0x00, /* 51 */
133 0x00, /* 52 */
134 0x00, /* 53 */
135 0x00, /* 54 */
136 0x00, /* 55 */
137 0x00, /* 56 */
138 0x00, /* 57 */
139 0x00, /* 58 */
140 0x00, /* 59 */
141 0x00, /* 5A */
142 0x00, /* 5B */
143 0x00, /* 5C */
144 0x00, /* 5D */
145 0x00, /* 5E */
146 0x00, /* 5F */
147 0x00, /* 60 */
148 0x00, /* 61 */
149 0x00, /* 62 */
150 0x00, /* 63 */
151 0x00, /* 64 */
152 0x00, /* 65 */
153 0x00, /* 66 */
154 0x00, /* 67 */
155 0x00, /* 68 */
156 0x00, /* 69 */
157 0x00, /* 6A */
158 0x00, /* 6B */
159 0x00, /* 6C */
160 0x00, /* 6D */
161 0x00, /* 6E */
162 0x00, /* 6F */
163 0x00, /* 70 */
164 0x00, /* 71 */
165 0x00, /* 72 */
166 0x00, /* 73 */
167 0x00, /* 74 */
168 0x00, /* 75 */
169 0x00, /* 76 */
170 0x00, /* 77 */
171 0x00, /* 78 */
172 0x00, /* 79 */
173 0x00, /* 7A */
174 0x00, /* 7B */
175 0x00, /* 7C */
176 0x00, /* 7D */
177 0x00, /* 7E */
178 0x00, /* 7F */
179 0x00, /* 80 */
180 0x00, /* 81 */
181 0x00, /* 82 */
182 0x00, /* 83 */
183 0x00, /* 84 */
184 0x00, /* 85 */
185 0x00, /* 86 */
186 0x00, /* 87 */
187 0x00, /* 88 */
188 0x00, /* 89 */
189 0x00, /* 8A */
190 0x00, /* 8B */
191 0x00, /* 8C */
192 0x00, /* 8D */
193 0x00, /* 8E */
194 0x00, /* 8F */
195 0x00, /* 90 */
196 0x00, /* 91 */
197 0x30, /* 92 */
198 0xF0, /* 93 */
199 0x00, /* 94 */
200 0x00, /* 95 */
201 0x3F, /* 96 */
202 0x00, /* 97 */
203 0x00, /* 98 */
204 0x00, /* 99 */
205 0x00, /* 9A */
206 0x00, /* 9B */
207 0x00, /* 9C */
208 0x00, /* 9D */
209 0x00, /* 9E */
210 0x00, /* 9F */
211 0x00, /* A0 */
212 0x00, /* A1 */
213 0x00, /* A2 */
214 0x00, /* A3 */
215 0x00, /* A4 */
216 0x00, /* A5 */
217 0x00, /* A6 */
218 0x00, /* A7 */
219 0x00, /* A8 */
220 0x00, /* A9 */
221 0x00, /* AA */
222 0x00, /* AB */
223 0x00, /* AC */
224 0x00, /* AD */
225 0x00, /* AE */
226 0x00, /* AF */
227 0x00, /* B0 */
228 0x00, /* B1 */
229 0x00, /* B2 */
230 0x00, /* B3 */
231 0x00, /* B4 */
232 0x00, /* B5 */
233 0x00, /* B6 */
234 0x00, /* B7 */
235 0x00, /* B8 */
236 0x00, /* B9 */
237 0x00, /* BA */
238 0x00, /* BB */
239 0x00, /* BC */
240 0x00, /* BD */
241 0x00, /* BE */
242 0x00, /* BF */
243 0x00, /* C0 */
244 0x00, /* C1 */
245 0x00, /* C2 */
246 0x00, /* C3 */
247 0x00, /* C4 */
248 0x00, /* C5 */
249 0x00, /* C6 */
250 0x00, /* C7 */
251 0x00, /* C8 */
252 0x00, /* C9 */
253 0x00, /* CA */
254 0x00, /* CB */
255 0x00, /* CC */
256 0x00, /* CD */
257 0x00, /* CE */
258 0x00, /* CF */
259 0x00, /* D0 */
260 0x00, /* D1 */
261 0x00, /* D2 */
262 0x00, /* D3 */
263 0x00, /* D4 */
264 0x00, /* D5 */
265 0x00, /* D6 */
266 0x00, /* D7 */
267 0x00, /* D8 */
268 0x00, /* D9 */
269 0x00, /* DA */
270 0x00, /* DB */
271 0x00, /* DC */
272 0x00, /* DD */
273 0x00, /* DE */
274 0x00, /* DF */
275 0x00, /* E0 */
276 0x00, /* E1 */
277 0x00, /* E2 */
278 0x00, /* E3 */
279 0x00, /* E4 */
280 0x00, /* E5 */
281 0x00, /* E6 */
282 0x00, /* E7 */
283 0x00, /* E8 */
284 0x00, /* E9 */
285 0x00, /* EA */
286 0x00, /* EB */
287 0x00, /* EC */
288 0x00, /* ED */
289 0x00, /* EE */
290 0x00, /* EF */
291 0x00, /* F0 */
292 0x00, /* F1 */
293 0x00, /* F2 */
294 0x00, /* F3 */
295 0x00, /* F4 */
296 0x00, /* F5 */
297 0x00, /* F6 */
298 0x00, /* F7 */
299 0x00, /* F8 */
300 0x00, /* F9 */
301 0x00, /* FA */
302 0x00, /* FB */
303 0x00, /* FC */
304 0x00, /* FD */
305 0x00, /* FE */
306 0x00, /* FF */
307};
308
309static struct {
310 int readable;
311 int writable;
312} max98095_access[M98095_REG_CNT] = {
313 { 0x00, 0x00 }, /* 00 */
314 { 0xFF, 0x00 }, /* 01 */
315 { 0xFF, 0x00 }, /* 02 */
316 { 0xFF, 0x00 }, /* 03 */
317 { 0xFF, 0x00 }, /* 04 */
318 { 0xFF, 0x00 }, /* 05 */
319 { 0xFF, 0x00 }, /* 06 */
320 { 0xFF, 0x00 }, /* 07 */
321 { 0xFF, 0x00 }, /* 08 */
322 { 0xFF, 0x00 }, /* 09 */
323 { 0xFF, 0x00 }, /* 0A */
324 { 0xFF, 0x00 }, /* 0B */
325 { 0xFF, 0x00 }, /* 0C */
326 { 0xFF, 0x00 }, /* 0D */
327 { 0xFF, 0x00 }, /* 0E */
328 { 0xFF, 0x9F }, /* 0F */
329 { 0xFF, 0xFF }, /* 10 */
330 { 0xFF, 0xFF }, /* 11 */
331 { 0xFF, 0xFF }, /* 12 */
332 { 0xFF, 0xFF }, /* 13 */
333 { 0xFF, 0xFF }, /* 14 */
334 { 0xFF, 0xFF }, /* 15 */
335 { 0xFF, 0xFF }, /* 16 */
336 { 0xFF, 0xFF }, /* 17 */
337 { 0xFF, 0xFF }, /* 18 */
338 { 0xFF, 0xFF }, /* 19 */
339 { 0xFF, 0xFF }, /* 1A */
340 { 0xFF, 0xFF }, /* 1B */
341 { 0xFF, 0xFF }, /* 1C */
342 { 0xFF, 0xFF }, /* 1D */
343 { 0xFF, 0x77 }, /* 1E */
344 { 0xFF, 0x77 }, /* 1F */
345 { 0xFF, 0x77 }, /* 20 */
346 { 0xFF, 0x77 }, /* 21 */
347 { 0xFF, 0x77 }, /* 22 */
348 { 0xFF, 0x77 }, /* 23 */
349 { 0xFF, 0xFF }, /* 24 */
350 { 0xFF, 0x7F }, /* 25 */
351 { 0xFF, 0x31 }, /* 26 */
352 { 0xFF, 0xFF }, /* 27 */
353 { 0xFF, 0xFF }, /* 28 */
354 { 0xFF, 0xFF }, /* 29 */
355 { 0xFF, 0xF7 }, /* 2A */
356 { 0xFF, 0x2F }, /* 2B */
357 { 0xFF, 0xEF }, /* 2C */
358 { 0xFF, 0xFF }, /* 2D */
359 { 0xFF, 0xFF }, /* 2E */
360 { 0xFF, 0xFF }, /* 2F */
361 { 0xFF, 0xFF }, /* 30 */
362 { 0xFF, 0xFF }, /* 31 */
363 { 0xFF, 0xFF }, /* 32 */
364 { 0xFF, 0xFF }, /* 33 */
365 { 0xFF, 0xF7 }, /* 34 */
366 { 0xFF, 0x2F }, /* 35 */
367 { 0xFF, 0xCF }, /* 36 */
368 { 0xFF, 0xFF }, /* 37 */
369 { 0xFF, 0xFF }, /* 38 */
370 { 0xFF, 0xFF }, /* 39 */
371 { 0xFF, 0xFF }, /* 3A */
372 { 0xFF, 0xFF }, /* 3B */
373 { 0xFF, 0xFF }, /* 3C */
374 { 0xFF, 0xFF }, /* 3D */
375 { 0xFF, 0xF7 }, /* 3E */
376 { 0xFF, 0x2F }, /* 3F */
377 { 0xFF, 0xCF }, /* 40 */
378 { 0xFF, 0xFF }, /* 41 */
379 { 0xFF, 0x77 }, /* 42 */
380 { 0xFF, 0xFF }, /* 43 */
381 { 0xFF, 0xFF }, /* 44 */
382 { 0xFF, 0xFF }, /* 45 */
383 { 0xFF, 0xFF }, /* 46 */
384 { 0xFF, 0xFF }, /* 47 */
385 { 0xFF, 0xFF }, /* 48 */
386 { 0xFF, 0x0F }, /* 49 */
387 { 0xFF, 0xFF }, /* 4A */
388 { 0xFF, 0xFF }, /* 4B */
389 { 0xFF, 0x3F }, /* 4C */
390 { 0xFF, 0x3F }, /* 4D */
391 { 0xFF, 0x3F }, /* 4E */
392 { 0xFF, 0xFF }, /* 4F */
393 { 0xFF, 0x7F }, /* 50 */
394 { 0xFF, 0x7F }, /* 51 */
395 { 0xFF, 0x0F }, /* 52 */
396 { 0xFF, 0x3F }, /* 53 */
397 { 0xFF, 0x3F }, /* 54 */
398 { 0xFF, 0x3F }, /* 55 */
399 { 0xFF, 0xFF }, /* 56 */
400 { 0xFF, 0xFF }, /* 57 */
401 { 0xFF, 0xBF }, /* 58 */
402 { 0xFF, 0x1F }, /* 59 */
403 { 0xFF, 0xBF }, /* 5A */
404 { 0xFF, 0x1F }, /* 5B */
405 { 0xFF, 0xBF }, /* 5C */
406 { 0xFF, 0x3F }, /* 5D */
407 { 0xFF, 0x3F }, /* 5E */
408 { 0xFF, 0x7F }, /* 5F */
409 { 0xFF, 0x7F }, /* 60 */
410 { 0xFF, 0x47 }, /* 61 */
411 { 0xFF, 0x9F }, /* 62 */
412 { 0xFF, 0x9F }, /* 63 */
413 { 0xFF, 0x9F }, /* 64 */
414 { 0xFF, 0x9F }, /* 65 */
415 { 0xFF, 0x9F }, /* 66 */
416 { 0xFF, 0xBF }, /* 67 */
417 { 0xFF, 0xBF }, /* 68 */
418 { 0xFF, 0xFF }, /* 69 */
419 { 0xFF, 0xFF }, /* 6A */
420 { 0xFF, 0x7F }, /* 6B */
421 { 0xFF, 0xF7 }, /* 6C */
422 { 0xFF, 0xFF }, /* 6D */
423 { 0xFF, 0xFF }, /* 6E */
424 { 0xFF, 0x1F }, /* 6F */
425 { 0xFF, 0xF7 }, /* 70 */
426 { 0xFF, 0xFF }, /* 71 */
427 { 0xFF, 0xFF }, /* 72 */
428 { 0xFF, 0x1F }, /* 73 */
429 { 0xFF, 0xF7 }, /* 74 */
430 { 0xFF, 0xFF }, /* 75 */
431 { 0xFF, 0xFF }, /* 76 */
432 { 0xFF, 0x1F }, /* 77 */
433 { 0xFF, 0xF7 }, /* 78 */
434 { 0xFF, 0xFF }, /* 79 */
435 { 0xFF, 0xFF }, /* 7A */
436 { 0xFF, 0x1F }, /* 7B */
437 { 0xFF, 0xF7 }, /* 7C */
438 { 0xFF, 0xFF }, /* 7D */
439 { 0xFF, 0xFF }, /* 7E */
440 { 0xFF, 0x1F }, /* 7F */
441 { 0xFF, 0xF7 }, /* 80 */
442 { 0xFF, 0xFF }, /* 81 */
443 { 0xFF, 0xFF }, /* 82 */
444 { 0xFF, 0x1F }, /* 83 */
445 { 0xFF, 0x7F }, /* 84 */
446 { 0xFF, 0x0F }, /* 85 */
447 { 0xFF, 0xD8 }, /* 86 */
448 { 0xFF, 0xFF }, /* 87 */
449 { 0xFF, 0xEF }, /* 88 */
450 { 0xFF, 0xFE }, /* 89 */
451 { 0xFF, 0xFE }, /* 8A */
452 { 0xFF, 0xFF }, /* 8B */
453 { 0xFF, 0xFF }, /* 8C */
454 { 0xFF, 0x3F }, /* 8D */
455 { 0xFF, 0xFF }, /* 8E */
456 { 0xFF, 0x3F }, /* 8F */
457 { 0xFF, 0x8F }, /* 90 */
458 { 0xFF, 0xFF }, /* 91 */
459 { 0xFF, 0x3F }, /* 92 */
460 { 0xFF, 0xFF }, /* 93 */
461 { 0xFF, 0xFF }, /* 94 */
462 { 0xFF, 0x0F }, /* 95 */
463 { 0xFF, 0x3F }, /* 96 */
464 { 0xFF, 0x8C }, /* 97 */
465 { 0x00, 0x00 }, /* 98 */
466 { 0x00, 0x00 }, /* 99 */
467 { 0x00, 0x00 }, /* 9A */
468 { 0x00, 0x00 }, /* 9B */
469 { 0x00, 0x00 }, /* 9C */
470 { 0x00, 0x00 }, /* 9D */
471 { 0x00, 0x00 }, /* 9E */
472 { 0x00, 0x00 }, /* 9F */
473 { 0x00, 0x00 }, /* A0 */
474 { 0x00, 0x00 }, /* A1 */
475 { 0x00, 0x00 }, /* A2 */
476 { 0x00, 0x00 }, /* A3 */
477 { 0x00, 0x00 }, /* A4 */
478 { 0x00, 0x00 }, /* A5 */
479 { 0x00, 0x00 }, /* A6 */
480 { 0x00, 0x00 }, /* A7 */
481 { 0x00, 0x00 }, /* A8 */
482 { 0x00, 0x00 }, /* A9 */
483 { 0x00, 0x00 }, /* AA */
484 { 0x00, 0x00 }, /* AB */
485 { 0x00, 0x00 }, /* AC */
486 { 0x00, 0x00 }, /* AD */
487 { 0x00, 0x00 }, /* AE */
488 { 0x00, 0x00 }, /* AF */
489 { 0x00, 0x00 }, /* B0 */
490 { 0x00, 0x00 }, /* B1 */
491 { 0x00, 0x00 }, /* B2 */
492 { 0x00, 0x00 }, /* B3 */
493 { 0x00, 0x00 }, /* B4 */
494 { 0x00, 0x00 }, /* B5 */
495 { 0x00, 0x00 }, /* B6 */
496 { 0x00, 0x00 }, /* B7 */
497 { 0x00, 0x00 }, /* B8 */
498 { 0x00, 0x00 }, /* B9 */
499 { 0x00, 0x00 }, /* BA */
500 { 0x00, 0x00 }, /* BB */
501 { 0x00, 0x00 }, /* BC */
502 { 0x00, 0x00 }, /* BD */
503 { 0x00, 0x00 }, /* BE */
504 { 0x00, 0x00 }, /* BF */
505 { 0x00, 0x00 }, /* C0 */
506 { 0x00, 0x00 }, /* C1 */
507 { 0x00, 0x00 }, /* C2 */
508 { 0x00, 0x00 }, /* C3 */
509 { 0x00, 0x00 }, /* C4 */
510 { 0x00, 0x00 }, /* C5 */
511 { 0x00, 0x00 }, /* C6 */
512 { 0x00, 0x00 }, /* C7 */
513 { 0x00, 0x00 }, /* C8 */
514 { 0x00, 0x00 }, /* C9 */
515 { 0x00, 0x00 }, /* CA */
516 { 0x00, 0x00 }, /* CB */
517 { 0x00, 0x00 }, /* CC */
518 { 0x00, 0x00 }, /* CD */
519 { 0x00, 0x00 }, /* CE */
520 { 0x00, 0x00 }, /* CF */
521 { 0x00, 0x00 }, /* D0 */
522 { 0x00, 0x00 }, /* D1 */
523 { 0x00, 0x00 }, /* D2 */
524 { 0x00, 0x00 }, /* D3 */
525 { 0x00, 0x00 }, /* D4 */
526 { 0x00, 0x00 }, /* D5 */
527 { 0x00, 0x00 }, /* D6 */
528 { 0x00, 0x00 }, /* D7 */
529 { 0x00, 0x00 }, /* D8 */
530 { 0x00, 0x00 }, /* D9 */
531 { 0x00, 0x00 }, /* DA */
532 { 0x00, 0x00 }, /* DB */
533 { 0x00, 0x00 }, /* DC */
534 { 0x00, 0x00 }, /* DD */
535 { 0x00, 0x00 }, /* DE */
536 { 0x00, 0x00 }, /* DF */
537 { 0x00, 0x00 }, /* E0 */
538 { 0x00, 0x00 }, /* E1 */
539 { 0x00, 0x00 }, /* E2 */
540 { 0x00, 0x00 }, /* E3 */
541 { 0x00, 0x00 }, /* E4 */
542 { 0x00, 0x00 }, /* E5 */
543 { 0x00, 0x00 }, /* E6 */
544 { 0x00, 0x00 }, /* E7 */
545 { 0x00, 0x00 }, /* E8 */
546 { 0x00, 0x00 }, /* E9 */
547 { 0x00, 0x00 }, /* EA */
548 { 0x00, 0x00 }, /* EB */
549 { 0x00, 0x00 }, /* EC */
550 { 0x00, 0x00 }, /* ED */
551 { 0x00, 0x00 }, /* EE */
552 { 0x00, 0x00 }, /* EF */
553 { 0x00, 0x00 }, /* F0 */
554 { 0x00, 0x00 }, /* F1 */
555 { 0x00, 0x00 }, /* F2 */
556 { 0x00, 0x00 }, /* F3 */
557 { 0x00, 0x00 }, /* F4 */
558 { 0x00, 0x00 }, /* F5 */
559 { 0x00, 0x00 }, /* F6 */
560 { 0x00, 0x00 }, /* F7 */
561 { 0x00, 0x00 }, /* F8 */
562 { 0x00, 0x00 }, /* F9 */
563 { 0x00, 0x00 }, /* FA */
564 { 0x00, 0x00 }, /* FB */
565 { 0x00, 0x00 }, /* FC */
566 { 0x00, 0x00 }, /* FD */
567 { 0x00, 0x00 }, /* FE */
568 { 0xFF, 0x00 }, /* FF */
569};
570
571static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg)
572{
573 if (reg >= M98095_REG_CNT)
574 return 0;
575 return max98095_access[reg].readable != 0;
576}
577
578static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
579{
580 if (reg > M98095_REG_MAX_CACHED)
581 return 1;
582
583 switch (reg) {
584 case M98095_000_HOST_DATA:
585 case M98095_001_HOST_INT_STS:
586 case M98095_002_HOST_RSP_STS:
587 case M98095_003_HOST_CMD_STS:
588 case M98095_004_CODEC_STS:
589 case M98095_005_DAI1_ALC_STS:
590 case M98095_006_DAI2_ALC_STS:
591 case M98095_007_JACK_AUTO_STS:
592 case M98095_008_JACK_MANUAL_STS:
593 case M98095_009_JACK_VBAT_STS:
594 case M98095_00A_ACC_ADC_STS:
595 case M98095_00B_MIC_NG_AGC_STS:
596 case M98095_00C_SPK_L_VOLT_STS:
597 case M98095_00D_SPK_R_VOLT_STS:
598 case M98095_00E_TEMP_SENSOR_STS:
599 return 1;
600 }
601
602 return 0;
603}
604
605static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
606static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
607 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
608};
609static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
610 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
611};
612
613static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
614
615static const struct soc_enum max98095_extmic_enum =
616 SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
617
618static const struct snd_kcontrol_new max98095_extmic_mux =
619 SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
620
621static const char * const max98095_linein_text[] = { "INA", "INB" };
622
623static const struct soc_enum max98095_linein_enum =
624 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
625
626static const struct snd_kcontrol_new max98095_linein_mux =
627 SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
628
629static const char * const max98095_line_mode_text[] = {
630 "Stereo", "Differential"};
631
632static const struct soc_enum max98095_linein_mode_enum =
633 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
634
635static const struct soc_enum max98095_lineout_mode_enum =
636 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
637
638static const char * const max98095_dai_fltr[] = {
639 "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
640 "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
641static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
642 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
643};
644static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
645 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
646};
647static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
648 SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
649};
650
651static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
652 struct snd_ctl_elem_value *ucontrol)
653{
654 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
655 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
656 unsigned int sel = ucontrol->value.integer.value[0];
657
658 max98095->mic1pre = sel;
659 snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
660 (1+sel)<<M98095_MICPRE_SHIFT);
661
662 return 0;
663}
664
665static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
666 struct snd_ctl_elem_value *ucontrol)
667{
668 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
669 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
670
671 ucontrol->value.integer.value[0] = max98095->mic1pre;
672 return 0;
673}
674
675static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
676 struct snd_ctl_elem_value *ucontrol)
677{
678 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
679 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
680 unsigned int sel = ucontrol->value.integer.value[0];
681
682 max98095->mic2pre = sel;
683 snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
684 (1+sel)<<M98095_MICPRE_SHIFT);
685
686 return 0;
687}
688
689static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
690 struct snd_ctl_elem_value *ucontrol)
691{
692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
693 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
694
695 ucontrol->value.integer.value[0] = max98095->mic2pre;
696 return 0;
697}
698
699static const unsigned int max98095_micboost_tlv[] = {
700 TLV_DB_RANGE_HEAD(2),
701 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
702 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
703};
704
705static const DECLARE_TLV_DB_SCALE(max98095_mic_tlv, 0, 100, 0);
706static const DECLARE_TLV_DB_SCALE(max98095_adc_tlv, -1200, 100, 0);
707static const DECLARE_TLV_DB_SCALE(max98095_adcboost_tlv, 0, 600, 0);
708
709static const unsigned int max98095_hp_tlv[] = {
710 TLV_DB_RANGE_HEAD(5),
711 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
712 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
713 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
714 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
715 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
716};
717
718static const unsigned int max98095_spk_tlv[] = {
719 TLV_DB_RANGE_HEAD(4),
720 0, 10, TLV_DB_SCALE_ITEM(-5900, 400, 0),
721 11, 18, TLV_DB_SCALE_ITEM(-1700, 200, 0),
722 19, 27, TLV_DB_SCALE_ITEM(-200, 100, 0),
723 28, 39, TLV_DB_SCALE_ITEM(650, 50, 0),
724};
725
726static const unsigned int max98095_rcv_lout_tlv[] = {
727 TLV_DB_RANGE_HEAD(5),
728 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
729 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
730 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
731 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
732 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
733};
734
735static const unsigned int max98095_lin_tlv[] = {
736 TLV_DB_RANGE_HEAD(3),
737 0, 2, TLV_DB_SCALE_ITEM(-600, 300, 0),
738 3, 3, TLV_DB_SCALE_ITEM(300, 1100, 0),
739 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0),
740};
741
742static const struct snd_kcontrol_new max98095_snd_controls[] = {
743
744 SOC_DOUBLE_R_TLV("Headphone Volume", M98095_064_LVL_HP_L,
745 M98095_065_LVL_HP_R, 0, 31, 0, max98095_hp_tlv),
746
747 SOC_DOUBLE_R_TLV("Speaker Volume", M98095_067_LVL_SPK_L,
748 M98095_068_LVL_SPK_R, 0, 39, 0, max98095_spk_tlv),
749
750 SOC_SINGLE_TLV("Receiver Volume", M98095_066_LVL_RCV,
751 0, 31, 0, max98095_rcv_lout_tlv),
752
753 SOC_DOUBLE_R_TLV("Lineout Volume", M98095_062_LVL_LINEOUT1,
754 M98095_063_LVL_LINEOUT2, 0, 31, 0, max98095_rcv_lout_tlv),
755
756 SOC_DOUBLE_R("Headphone Switch", M98095_064_LVL_HP_L,
757 M98095_065_LVL_HP_R, 7, 1, 1),
758
759 SOC_DOUBLE_R("Speaker Switch", M98095_067_LVL_SPK_L,
760 M98095_068_LVL_SPK_R, 7, 1, 1),
761
762 SOC_SINGLE("Receiver Switch", M98095_066_LVL_RCV, 7, 1, 1),
763
764 SOC_DOUBLE_R("Lineout Switch", M98095_062_LVL_LINEOUT1,
765 M98095_063_LVL_LINEOUT2, 7, 1, 1),
766
767 SOC_SINGLE_TLV("MIC1 Volume", M98095_05F_LVL_MIC1, 0, 20, 1,
768 max98095_mic_tlv),
769
770 SOC_SINGLE_TLV("MIC2 Volume", M98095_060_LVL_MIC2, 0, 20, 1,
771 max98095_mic_tlv),
772
773 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
774 M98095_05F_LVL_MIC1, 5, 2, 0,
775 max98095_mic1pre_get, max98095_mic1pre_set,
776 max98095_micboost_tlv),
777 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
778 M98095_060_LVL_MIC2, 5, 2, 0,
779 max98095_mic2pre_get, max98095_mic2pre_set,
780 max98095_micboost_tlv),
781
782 SOC_SINGLE_TLV("Linein Volume", M98095_061_LVL_LINEIN, 0, 5, 1,
783 max98095_lin_tlv),
784
785 SOC_SINGLE_TLV("ADCL Volume", M98095_05D_LVL_ADC_L, 0, 15, 1,
786 max98095_adc_tlv),
787 SOC_SINGLE_TLV("ADCR Volume", M98095_05E_LVL_ADC_R, 0, 15, 1,
788 max98095_adc_tlv),
789
790 SOC_SINGLE_TLV("ADCL Boost Volume", M98095_05D_LVL_ADC_L, 4, 3, 0,
791 max98095_adcboost_tlv),
792 SOC_SINGLE_TLV("ADCR Boost Volume", M98095_05E_LVL_ADC_R, 4, 3, 0,
793 max98095_adcboost_tlv),
794
795 SOC_ENUM("DAI1 Filter Mode", max98095_dai1_filter_mode_enum),
796 SOC_ENUM("DAI2 Filter Mode", max98095_dai2_filter_mode_enum),
797 SOC_ENUM("DAI1 DAC Filter", max98095_dai1_dac_filter_enum),
798 SOC_ENUM("DAI2 DAC Filter", max98095_dai2_dac_filter_enum),
799 SOC_ENUM("DAI3 DAC Filter", max98095_dai3_dac_filter_enum),
800
801 SOC_ENUM("Linein Mode", max98095_linein_mode_enum),
802 SOC_ENUM("Lineout Mode", max98095_lineout_mode_enum),
803};
804
805/* Left speaker mixer switch */
806static const struct snd_kcontrol_new max98095_left_speaker_mixer_controls[] = {
807 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_050_MIX_SPK_LEFT, 0, 1, 0),
808 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_050_MIX_SPK_LEFT, 6, 1, 0),
809 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
810 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
811 SOC_DAPM_SINGLE("MIC1 Switch", M98095_050_MIX_SPK_LEFT, 4, 1, 0),
812 SOC_DAPM_SINGLE("MIC2 Switch", M98095_050_MIX_SPK_LEFT, 5, 1, 0),
813 SOC_DAPM_SINGLE("IN1 Switch", M98095_050_MIX_SPK_LEFT, 1, 1, 0),
814 SOC_DAPM_SINGLE("IN2 Switch", M98095_050_MIX_SPK_LEFT, 2, 1, 0),
815};
816
817/* Right speaker mixer switch */
818static const struct snd_kcontrol_new max98095_right_speaker_mixer_controls[] = {
819 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 6, 1, 0),
820 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 0, 1, 0),
821 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
822 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
823 SOC_DAPM_SINGLE("MIC1 Switch", M98095_051_MIX_SPK_RIGHT, 5, 1, 0),
824 SOC_DAPM_SINGLE("MIC2 Switch", M98095_051_MIX_SPK_RIGHT, 4, 1, 0),
825 SOC_DAPM_SINGLE("IN1 Switch", M98095_051_MIX_SPK_RIGHT, 1, 1, 0),
826 SOC_DAPM_SINGLE("IN2 Switch", M98095_051_MIX_SPK_RIGHT, 2, 1, 0),
827};
828
829/* Left headphone mixer switch */
830static const struct snd_kcontrol_new max98095_left_hp_mixer_controls[] = {
831 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04C_MIX_HP_LEFT, 0, 1, 0),
832 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04C_MIX_HP_LEFT, 5, 1, 0),
833 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04C_MIX_HP_LEFT, 3, 1, 0),
834 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04C_MIX_HP_LEFT, 4, 1, 0),
835 SOC_DAPM_SINGLE("IN1 Switch", M98095_04C_MIX_HP_LEFT, 1, 1, 0),
836 SOC_DAPM_SINGLE("IN2 Switch", M98095_04C_MIX_HP_LEFT, 2, 1, 0),
837};
838
839/* Right headphone mixer switch */
840static const struct snd_kcontrol_new max98095_right_hp_mixer_controls[] = {
841 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 5, 1, 0),
842 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 0, 1, 0),
843 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04D_MIX_HP_RIGHT, 3, 1, 0),
844 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04D_MIX_HP_RIGHT, 4, 1, 0),
845 SOC_DAPM_SINGLE("IN1 Switch", M98095_04D_MIX_HP_RIGHT, 1, 1, 0),
846 SOC_DAPM_SINGLE("IN2 Switch", M98095_04D_MIX_HP_RIGHT, 2, 1, 0),
847};
848
849/* Receiver earpiece mixer switch */
850static const struct snd_kcontrol_new max98095_mono_rcv_mixer_controls[] = {
851 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04F_MIX_RCV, 0, 1, 0),
852 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04F_MIX_RCV, 5, 1, 0),
853 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04F_MIX_RCV, 3, 1, 0),
854 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04F_MIX_RCV, 4, 1, 0),
855 SOC_DAPM_SINGLE("IN1 Switch", M98095_04F_MIX_RCV, 1, 1, 0),
856 SOC_DAPM_SINGLE("IN2 Switch", M98095_04F_MIX_RCV, 2, 1, 0),
857};
858
859/* Left lineout mixer switch */
860static const struct snd_kcontrol_new max98095_left_lineout_mixer_controls[] = {
861 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_053_MIX_LINEOUT1, 5, 1, 0),
862 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_053_MIX_LINEOUT1, 0, 1, 0),
863 SOC_DAPM_SINGLE("MIC1 Switch", M98095_053_MIX_LINEOUT1, 3, 1, 0),
864 SOC_DAPM_SINGLE("MIC2 Switch", M98095_053_MIX_LINEOUT1, 4, 1, 0),
865 SOC_DAPM_SINGLE("IN1 Switch", M98095_053_MIX_LINEOUT1, 1, 1, 0),
866 SOC_DAPM_SINGLE("IN2 Switch", M98095_053_MIX_LINEOUT1, 2, 1, 0),
867};
868
869/* Right lineout mixer switch */
870static const struct snd_kcontrol_new max98095_right_lineout_mixer_controls[] = {
871 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_054_MIX_LINEOUT2, 0, 1, 0),
872 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_054_MIX_LINEOUT2, 5, 1, 0),
873 SOC_DAPM_SINGLE("MIC1 Switch", M98095_054_MIX_LINEOUT2, 3, 1, 0),
874 SOC_DAPM_SINGLE("MIC2 Switch", M98095_054_MIX_LINEOUT2, 4, 1, 0),
875 SOC_DAPM_SINGLE("IN1 Switch", M98095_054_MIX_LINEOUT2, 1, 1, 0),
876 SOC_DAPM_SINGLE("IN2 Switch", M98095_054_MIX_LINEOUT2, 2, 1, 0),
877};
878
879/* Left ADC mixer switch */
880static const struct snd_kcontrol_new max98095_left_ADC_mixer_controls[] = {
881 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04A_MIX_ADC_LEFT, 7, 1, 0),
882 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04A_MIX_ADC_LEFT, 6, 1, 0),
883 SOC_DAPM_SINGLE("IN1 Switch", M98095_04A_MIX_ADC_LEFT, 3, 1, 0),
884 SOC_DAPM_SINGLE("IN2 Switch", M98095_04A_MIX_ADC_LEFT, 2, 1, 0),
885};
886
887/* Right ADC mixer switch */
888static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
889 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04B_MIX_ADC_RIGHT, 7, 1, 0),
890 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04B_MIX_ADC_RIGHT, 6, 1, 0),
891 SOC_DAPM_SINGLE("IN1 Switch", M98095_04B_MIX_ADC_RIGHT, 3, 1, 0),
892 SOC_DAPM_SINGLE("IN2 Switch", M98095_04B_MIX_ADC_RIGHT, 2, 1, 0),
893};
894
895static int max98095_mic_event(struct snd_soc_dapm_widget *w,
896 struct snd_kcontrol *kcontrol, int event)
897{
898 struct snd_soc_codec *codec = w->codec;
899 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
900
901 switch (event) {
902 case SND_SOC_DAPM_POST_PMU:
903 if (w->reg == M98095_05F_LVL_MIC1) {
904 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
905 (1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
906 } else {
907 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
908 (1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
909 }
910 break;
911 case SND_SOC_DAPM_POST_PMD:
912 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
913 break;
914 default:
915 return -EINVAL;
916 }
917
918 return 0;
919}
920
921/*
922 * The line inputs are stereo inputs with the left and right
923 * channels sharing a common PGA power control signal.
924 */
925static int max98095_line_pga(struct snd_soc_dapm_widget *w,
926 int event, u8 channel)
927{
928 struct snd_soc_codec *codec = w->codec;
929 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
930 u8 *state;
931
932 BUG_ON(!((channel == 1) || (channel == 2)));
933
934 state = &max98095->lin_state;
935
936 switch (event) {
937 case SND_SOC_DAPM_POST_PMU:
938 *state |= channel;
939 snd_soc_update_bits(codec, w->reg,
940 (1 << w->shift), (1 << w->shift));
941 break;
942 case SND_SOC_DAPM_POST_PMD:
943 *state &= ~channel;
944 if (*state == 0) {
945 snd_soc_update_bits(codec, w->reg,
946 (1 << w->shift), 0);
947 }
948 break;
949 default:
950 return -EINVAL;
951 }
952
953 return 0;
954}
955
956static int max98095_pga_in1_event(struct snd_soc_dapm_widget *w,
957 struct snd_kcontrol *k, int event)
958{
959 return max98095_line_pga(w, event, 1);
960}
961
962static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
963 struct snd_kcontrol *k, int event)
964{
965 return max98095_line_pga(w, event, 2);
966}
967
968/*
969 * The stereo line out mixer outputs to two stereo line outs.
970 * The 2nd pair has a separate set of enables.
971 */
972static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
973 struct snd_kcontrol *kcontrol, int event)
974{
975 struct snd_soc_codec *codec = w->codec;
976
977 switch (event) {
978 case SND_SOC_DAPM_POST_PMU:
979 snd_soc_update_bits(codec, w->reg,
980 (1 << (w->shift+2)), (1 << (w->shift+2)));
981 break;
982 case SND_SOC_DAPM_POST_PMD:
983 snd_soc_update_bits(codec, w->reg,
984 (1 << (w->shift+2)), 0);
985 break;
986 default:
987 return -EINVAL;
988 }
989
990 return 0;
991}
992
993static const struct snd_soc_dapm_widget max98095_dapm_widgets[] = {
994
995 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98095_090_PWR_EN_IN, 0, 0),
996 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98095_090_PWR_EN_IN, 1, 0),
997
998 SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
999 M98095_091_PWR_EN_OUT, 0, 0),
1000 SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
1001 M98095_091_PWR_EN_OUT, 1, 0),
1002 SND_SOC_DAPM_DAC("DACM2", "Aux Playback",
1003 M98095_091_PWR_EN_OUT, 2, 0),
1004 SND_SOC_DAPM_DAC("DACM3", "Voice Playback",
1005 M98095_091_PWR_EN_OUT, 2, 0),
1006
1007 SND_SOC_DAPM_PGA("HP Left Out", M98095_091_PWR_EN_OUT,
1008 6, 0, NULL, 0),
1009 SND_SOC_DAPM_PGA("HP Right Out", M98095_091_PWR_EN_OUT,
1010 7, 0, NULL, 0),
1011
1012 SND_SOC_DAPM_PGA("SPK Left Out", M98095_091_PWR_EN_OUT,
1013 4, 0, NULL, 0),
1014 SND_SOC_DAPM_PGA("SPK Right Out", M98095_091_PWR_EN_OUT,
1015 5, 0, NULL, 0),
1016
1017 SND_SOC_DAPM_PGA("RCV Mono Out", M98095_091_PWR_EN_OUT,
1018 3, 0, NULL, 0),
1019
1020 SND_SOC_DAPM_PGA_E("LINE Left Out", M98095_092_PWR_EN_OUT,
1021 0, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1022 SND_SOC_DAPM_PGA_E("LINE Right Out", M98095_092_PWR_EN_OUT,
1023 1, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1024
1025 SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
1026 &max98095_extmic_mux),
1027
1028 SND_SOC_DAPM_MUX("Linein Mux", SND_SOC_NOPM, 0, 0,
1029 &max98095_linein_mux),
1030
1031 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
1032 &max98095_left_hp_mixer_controls[0],
1033 ARRAY_SIZE(max98095_left_hp_mixer_controls)),
1034
1035 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
1036 &max98095_right_hp_mixer_controls[0],
1037 ARRAY_SIZE(max98095_right_hp_mixer_controls)),
1038
1039 SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0,
1040 &max98095_left_speaker_mixer_controls[0],
1041 ARRAY_SIZE(max98095_left_speaker_mixer_controls)),
1042
1043 SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0,
1044 &max98095_right_speaker_mixer_controls[0],
1045 ARRAY_SIZE(max98095_right_speaker_mixer_controls)),
1046
1047 SND_SOC_DAPM_MIXER("Receiver Mixer", SND_SOC_NOPM, 0, 0,
1048 &max98095_mono_rcv_mixer_controls[0],
1049 ARRAY_SIZE(max98095_mono_rcv_mixer_controls)),
1050
1051 SND_SOC_DAPM_MIXER("Left Lineout Mixer", SND_SOC_NOPM, 0, 0,
1052 &max98095_left_lineout_mixer_controls[0],
1053 ARRAY_SIZE(max98095_left_lineout_mixer_controls)),
1054
1055 SND_SOC_DAPM_MIXER("Right Lineout Mixer", SND_SOC_NOPM, 0, 0,
1056 &max98095_right_lineout_mixer_controls[0],
1057 ARRAY_SIZE(max98095_right_lineout_mixer_controls)),
1058
1059 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1060 &max98095_left_ADC_mixer_controls[0],
1061 ARRAY_SIZE(max98095_left_ADC_mixer_controls)),
1062
1063 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1064 &max98095_right_ADC_mixer_controls[0],
1065 ARRAY_SIZE(max98095_right_ADC_mixer_controls)),
1066
1067 SND_SOC_DAPM_PGA_E("MIC1 Input", M98095_05F_LVL_MIC1,
1068 5, 0, NULL, 0, max98095_mic_event,
1069 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1070
1071 SND_SOC_DAPM_PGA_E("MIC2 Input", M98095_060_LVL_MIC2,
1072 5, 0, NULL, 0, max98095_mic_event,
1073 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1074
1075 SND_SOC_DAPM_PGA_E("IN1 Input", M98095_090_PWR_EN_IN,
1076 7, 0, NULL, 0, max98095_pga_in1_event,
1077 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1078
1079 SND_SOC_DAPM_PGA_E("IN2 Input", M98095_090_PWR_EN_IN,
1080 7, 0, NULL, 0, max98095_pga_in2_event,
1081 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1082
1083 SND_SOC_DAPM_MICBIAS("MICBIAS1", M98095_090_PWR_EN_IN, 2, 0),
1084 SND_SOC_DAPM_MICBIAS("MICBIAS2", M98095_090_PWR_EN_IN, 3, 0),
1085
1086 SND_SOC_DAPM_OUTPUT("HPL"),
1087 SND_SOC_DAPM_OUTPUT("HPR"),
1088 SND_SOC_DAPM_OUTPUT("SPKL"),
1089 SND_SOC_DAPM_OUTPUT("SPKR"),
1090 SND_SOC_DAPM_OUTPUT("RCV"),
1091 SND_SOC_DAPM_OUTPUT("OUT1"),
1092 SND_SOC_DAPM_OUTPUT("OUT2"),
1093 SND_SOC_DAPM_OUTPUT("OUT3"),
1094 SND_SOC_DAPM_OUTPUT("OUT4"),
1095
1096 SND_SOC_DAPM_INPUT("MIC1"),
1097 SND_SOC_DAPM_INPUT("MIC2"),
1098 SND_SOC_DAPM_INPUT("INA1"),
1099 SND_SOC_DAPM_INPUT("INA2"),
1100 SND_SOC_DAPM_INPUT("INB1"),
1101 SND_SOC_DAPM_INPUT("INB2"),
1102};
1103
1104static const struct snd_soc_dapm_route max98095_audio_map[] = {
1105 /* Left headphone output mixer */
1106 {"Left Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1107 {"Left Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1108 {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1109 {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1110 {"Left Headphone Mixer", "IN1 Switch", "IN1 Input"},
1111 {"Left Headphone Mixer", "IN2 Switch", "IN2 Input"},
1112
1113 /* Right headphone output mixer */
1114 {"Right Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1115 {"Right Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1116 {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1117 {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1118 {"Right Headphone Mixer", "IN1 Switch", "IN1 Input"},
1119 {"Right Headphone Mixer", "IN2 Switch", "IN2 Input"},
1120
1121 /* Left speaker output mixer */
1122 {"Left Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1123 {"Left Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1124 {"Left Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1125 {"Left Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1126 {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1127 {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1128 {"Left Speaker Mixer", "IN1 Switch", "IN1 Input"},
1129 {"Left Speaker Mixer", "IN2 Switch", "IN2 Input"},
1130
1131 /* Right speaker output mixer */
1132 {"Right Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1133 {"Right Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1134 {"Right Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1135 {"Right Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1136 {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1137 {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1138 {"Right Speaker Mixer", "IN1 Switch", "IN1 Input"},
1139 {"Right Speaker Mixer", "IN2 Switch", "IN2 Input"},
1140
1141 /* Earpiece/Receiver output mixer */
1142 {"Receiver Mixer", "Left DAC1 Switch", "DACL1"},
1143 {"Receiver Mixer", "Right DAC1 Switch", "DACR1"},
1144 {"Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
1145 {"Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
1146 {"Receiver Mixer", "IN1 Switch", "IN1 Input"},
1147 {"Receiver Mixer", "IN2 Switch", "IN2 Input"},
1148
1149 /* Left Lineout output mixer */
1150 {"Left Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1151 {"Left Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1152 {"Left Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1153 {"Left Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1154 {"Left Lineout Mixer", "IN1 Switch", "IN1 Input"},
1155 {"Left Lineout Mixer", "IN2 Switch", "IN2 Input"},
1156
1157 /* Right lineout output mixer */
1158 {"Right Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1159 {"Right Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1160 {"Right Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1161 {"Right Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1162 {"Right Lineout Mixer", "IN1 Switch", "IN1 Input"},
1163 {"Right Lineout Mixer", "IN2 Switch", "IN2 Input"},
1164
1165 {"HP Left Out", NULL, "Left Headphone Mixer"},
1166 {"HP Right Out", NULL, "Right Headphone Mixer"},
1167 {"SPK Left Out", NULL, "Left Speaker Mixer"},
1168 {"SPK Right Out", NULL, "Right Speaker Mixer"},
1169 {"RCV Mono Out", NULL, "Receiver Mixer"},
1170 {"LINE Left Out", NULL, "Left Lineout Mixer"},
1171 {"LINE Right Out", NULL, "Right Lineout Mixer"},
1172
1173 {"HPL", NULL, "HP Left Out"},
1174 {"HPR", NULL, "HP Right Out"},
1175 {"SPKL", NULL, "SPK Left Out"},
1176 {"SPKR", NULL, "SPK Right Out"},
1177 {"RCV", NULL, "RCV Mono Out"},
1178 {"OUT1", NULL, "LINE Left Out"},
1179 {"OUT2", NULL, "LINE Right Out"},
1180 {"OUT3", NULL, "LINE Left Out"},
1181 {"OUT4", NULL, "LINE Right Out"},
1182
1183 /* Left ADC input mixer */
1184 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1185 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1186 {"Left ADC Mixer", "IN1 Switch", "IN1 Input"},
1187 {"Left ADC Mixer", "IN2 Switch", "IN2 Input"},
1188
1189 /* Right ADC input mixer */
1190 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1191 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1192 {"Right ADC Mixer", "IN1 Switch", "IN1 Input"},
1193 {"Right ADC Mixer", "IN2 Switch", "IN2 Input"},
1194
1195 /* Inputs */
1196 {"ADCL", NULL, "Left ADC Mixer"},
1197 {"ADCR", NULL, "Right ADC Mixer"},
1198
1199 {"IN1 Input", NULL, "INA1"},
1200 {"IN2 Input", NULL, "INA2"},
1201
1202 {"MIC1 Input", NULL, "MIC1"},
1203 {"MIC2 Input", NULL, "MIC2"},
1204};
1205
1206static int max98095_add_widgets(struct snd_soc_codec *codec)
1207{
1208 snd_soc_add_controls(codec, max98095_snd_controls,
1209 ARRAY_SIZE(max98095_snd_controls));
1210
1211 return 0;
1212}
1213
1214/* codec mclk clock divider coefficients */
1215static const struct {
1216 u32 rate;
1217 u8 sr;
1218} rate_table[] = {
1219 {8000, 0x01},
1220 {11025, 0x02},
1221 {16000, 0x03},
1222 {22050, 0x04},
1223 {24000, 0x05},
1224 {32000, 0x06},
1225 {44100, 0x07},
1226 {48000, 0x08},
1227 {88200, 0x09},
1228 {96000, 0x0A},
1229};
1230
1231static int rate_value(int rate, u8 *value)
1232{
1233 int i;
1234
1235 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
1236 if (rate_table[i].rate >= rate) {
1237 *value = rate_table[i].sr;
1238 return 0;
1239 }
1240 }
1241 *value = rate_table[0].sr;
1242 return -EINVAL;
1243}
1244
1245static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
1246 struct snd_pcm_hw_params *params,
1247 struct snd_soc_dai *dai)
1248{
1249 struct snd_soc_codec *codec = dai->codec;
1250 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1251 struct max98095_cdata *cdata;
1252 unsigned long long ni;
1253 unsigned int rate;
1254 u8 regval;
1255
1256 cdata = &max98095->dai[0];
1257
1258 rate = params_rate(params);
1259
1260 switch (params_format(params)) {
1261 case SNDRV_PCM_FORMAT_S16_LE:
1262 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1263 M98095_DAI_WS, 0);
1264 break;
1265 case SNDRV_PCM_FORMAT_S24_LE:
1266 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1267 M98095_DAI_WS, M98095_DAI_WS);
1268 break;
1269 default:
1270 return -EINVAL;
1271 }
1272
1273 if (rate_value(rate, &regval))
1274 return -EINVAL;
1275
1276 snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
1277 M98095_CLKMODE_MASK, regval);
1278 cdata->rate = rate;
1279
1280 /* Configure NI when operating as master */
1281 if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
1282 if (max98095->sysclk == 0) {
1283 dev_err(codec->dev, "Invalid system clock frequency\n");
1284 return -EINVAL;
1285 }
1286 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1287 * (unsigned long long int)rate;
1288 do_div(ni, (unsigned long long int)max98095->sysclk);
1289 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1290 (ni >> 8) & 0x7F);
1291 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1292 ni & 0xFF);
1293 }
1294
1295 /* Update sample rate mode */
1296 if (rate < 50000)
1297 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1298 M98095_DAI_DHF, 0);
1299 else
1300 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1301 M98095_DAI_DHF, M98095_DAI_DHF);
1302
1303 return 0;
1304}
1305
1306static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
1307 struct snd_pcm_hw_params *params,
1308 struct snd_soc_dai *dai)
1309{
1310 struct snd_soc_codec *codec = dai->codec;
1311 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1312 struct max98095_cdata *cdata;
1313 unsigned long long ni;
1314 unsigned int rate;
1315 u8 regval;
1316
1317 cdata = &max98095->dai[1];
1318
1319 rate = params_rate(params);
1320
1321 switch (params_format(params)) {
1322 case SNDRV_PCM_FORMAT_S16_LE:
1323 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1324 M98095_DAI_WS, 0);
1325 break;
1326 case SNDRV_PCM_FORMAT_S24_LE:
1327 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1328 M98095_DAI_WS, M98095_DAI_WS);
1329 break;
1330 default:
1331 return -EINVAL;
1332 }
1333
1334 if (rate_value(rate, &regval))
1335 return -EINVAL;
1336
1337 snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
1338 M98095_CLKMODE_MASK, regval);
1339 cdata->rate = rate;
1340
1341 /* Configure NI when operating as master */
1342 if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
1343 if (max98095->sysclk == 0) {
1344 dev_err(codec->dev, "Invalid system clock frequency\n");
1345 return -EINVAL;
1346 }
1347 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1348 * (unsigned long long int)rate;
1349 do_div(ni, (unsigned long long int)max98095->sysclk);
1350 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1351 (ni >> 8) & 0x7F);
1352 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1353 ni & 0xFF);
1354 }
1355
1356 /* Update sample rate mode */
1357 if (rate < 50000)
1358 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1359 M98095_DAI_DHF, 0);
1360 else
1361 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1362 M98095_DAI_DHF, M98095_DAI_DHF);
1363
1364 return 0;
1365}
1366
1367static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
1368 struct snd_pcm_hw_params *params,
1369 struct snd_soc_dai *dai)
1370{
1371 struct snd_soc_codec *codec = dai->codec;
1372 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1373 struct max98095_cdata *cdata;
1374 unsigned long long ni;
1375 unsigned int rate;
1376 u8 regval;
1377
1378 cdata = &max98095->dai[2];
1379
1380 rate = params_rate(params);
1381
1382 switch (params_format(params)) {
1383 case SNDRV_PCM_FORMAT_S16_LE:
1384 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1385 M98095_DAI_WS, 0);
1386 break;
1387 case SNDRV_PCM_FORMAT_S24_LE:
1388 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1389 M98095_DAI_WS, M98095_DAI_WS);
1390 break;
1391 default:
1392 return -EINVAL;
1393 }
1394
1395 if (rate_value(rate, &regval))
1396 return -EINVAL;
1397
1398 snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
1399 M98095_CLKMODE_MASK, regval);
1400 cdata->rate = rate;
1401
1402 /* Configure NI when operating as master */
1403 if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
1404 if (max98095->sysclk == 0) {
1405 dev_err(codec->dev, "Invalid system clock frequency\n");
1406 return -EINVAL;
1407 }
1408 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1409 * (unsigned long long int)rate;
1410 do_div(ni, (unsigned long long int)max98095->sysclk);
1411 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1412 (ni >> 8) & 0x7F);
1413 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1414 ni & 0xFF);
1415 }
1416
1417 /* Update sample rate mode */
1418 if (rate < 50000)
1419 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1420 M98095_DAI_DHF, 0);
1421 else
1422 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1423 M98095_DAI_DHF, M98095_DAI_DHF);
1424
1425 return 0;
1426}
1427
1428static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
1429 int clk_id, unsigned int freq, int dir)
1430{
1431 struct snd_soc_codec *codec = dai->codec;
1432 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1433
1434 /* Requested clock frequency is already setup */
1435 if (freq == max98095->sysclk)
1436 return 0;
1437
1438 max98095->sysclk = freq; /* remember current sysclk */
1439
1440 /* Setup clocks for slave mode, and using the PLL
1441 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1442 * 0x02 (when master clk is 20MHz to 40MHz)..
1443 * 0x03 (when master clk is 40MHz to 60MHz)..
1444 */
1445 if ((freq >= 10000000) && (freq < 20000000)) {
1446 snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
1447 } else if ((freq >= 20000000) && (freq < 40000000)) {
1448 snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
1449 } else if ((freq >= 40000000) && (freq < 60000000)) {
1450 snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
1451 } else {
1452 dev_err(codec->dev, "Invalid master clock frequency\n");
1453 return -EINVAL;
1454 }
1455
1456 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1457
1458 max98095->sysclk = freq;
1459 return 0;
1460}
1461
1462static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
1463 unsigned int fmt)
1464{
1465 struct snd_soc_codec *codec = codec_dai->codec;
1466 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1467 struct max98095_cdata *cdata;
1468 u8 regval = 0;
1469
1470 cdata = &max98095->dai[0];
1471
1472 if (fmt != cdata->fmt) {
1473 cdata->fmt = fmt;
1474
1475 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1476 case SND_SOC_DAIFMT_CBS_CFS:
1477 /* Slave mode PLL */
1478 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1479 0x80);
1480 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1481 0x00);
1482 break;
1483 case SND_SOC_DAIFMT_CBM_CFM:
1484 /* Set to master mode */
1485 regval |= M98095_DAI_MAS;
1486 break;
1487 case SND_SOC_DAIFMT_CBS_CFM:
1488 case SND_SOC_DAIFMT_CBM_CFS:
1489 default:
1490 dev_err(codec->dev, "Clock mode unsupported");
1491 return -EINVAL;
1492 }
1493
1494 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1495 case SND_SOC_DAIFMT_I2S:
1496 regval |= M98095_DAI_DLY;
1497 break;
1498 case SND_SOC_DAIFMT_LEFT_J:
1499 break;
1500 default:
1501 return -EINVAL;
1502 }
1503
1504 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1505 case SND_SOC_DAIFMT_NB_NF:
1506 break;
1507 case SND_SOC_DAIFMT_NB_IF:
1508 regval |= M98095_DAI_WCI;
1509 break;
1510 case SND_SOC_DAIFMT_IB_NF:
1511 regval |= M98095_DAI_BCI;
1512 break;
1513 case SND_SOC_DAIFMT_IB_IF:
1514 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1515 break;
1516 default:
1517 return -EINVAL;
1518 }
1519
1520 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1521 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1522 M98095_DAI_WCI, regval);
1523
1524 snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
1525 }
1526
1527 return 0;
1528}
1529
1530static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1531 unsigned int fmt)
1532{
1533 struct snd_soc_codec *codec = codec_dai->codec;
1534 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1535 struct max98095_cdata *cdata;
1536 u8 regval = 0;
1537
1538 cdata = &max98095->dai[1];
1539
1540 if (fmt != cdata->fmt) {
1541 cdata->fmt = fmt;
1542
1543 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1544 case SND_SOC_DAIFMT_CBS_CFS:
1545 /* Slave mode PLL */
1546 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1547 0x80);
1548 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1549 0x00);
1550 break;
1551 case SND_SOC_DAIFMT_CBM_CFM:
1552 /* Set to master mode */
1553 regval |= M98095_DAI_MAS;
1554 break;
1555 case SND_SOC_DAIFMT_CBS_CFM:
1556 case SND_SOC_DAIFMT_CBM_CFS:
1557 default:
1558 dev_err(codec->dev, "Clock mode unsupported");
1559 return -EINVAL;
1560 }
1561
1562 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1563 case SND_SOC_DAIFMT_I2S:
1564 regval |= M98095_DAI_DLY;
1565 break;
1566 case SND_SOC_DAIFMT_LEFT_J:
1567 break;
1568 default:
1569 return -EINVAL;
1570 }
1571
1572 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1573 case SND_SOC_DAIFMT_NB_NF:
1574 break;
1575 case SND_SOC_DAIFMT_NB_IF:
1576 regval |= M98095_DAI_WCI;
1577 break;
1578 case SND_SOC_DAIFMT_IB_NF:
1579 regval |= M98095_DAI_BCI;
1580 break;
1581 case SND_SOC_DAIFMT_IB_IF:
1582 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1583 break;
1584 default:
1585 return -EINVAL;
1586 }
1587
1588 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1589 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1590 M98095_DAI_WCI, regval);
1591
1592 snd_soc_write(codec, M98095_035_DAI2_CLOCK,
1593 M98095_DAI_BSEL64);
1594 }
1595
1596 return 0;
1597}
1598
1599static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
1600 unsigned int fmt)
1601{
1602 struct snd_soc_codec *codec = codec_dai->codec;
1603 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1604 struct max98095_cdata *cdata;
1605 u8 regval = 0;
1606
1607 cdata = &max98095->dai[2];
1608
1609 if (fmt != cdata->fmt) {
1610 cdata->fmt = fmt;
1611
1612 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1613 case SND_SOC_DAIFMT_CBS_CFS:
1614 /* Slave mode PLL */
1615 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1616 0x80);
1617 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1618 0x00);
1619 break;
1620 case SND_SOC_DAIFMT_CBM_CFM:
1621 /* Set to master mode */
1622 regval |= M98095_DAI_MAS;
1623 break;
1624 case SND_SOC_DAIFMT_CBS_CFM:
1625 case SND_SOC_DAIFMT_CBM_CFS:
1626 default:
1627 dev_err(codec->dev, "Clock mode unsupported");
1628 return -EINVAL;
1629 }
1630
1631 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1632 case SND_SOC_DAIFMT_I2S:
1633 regval |= M98095_DAI_DLY;
1634 break;
1635 case SND_SOC_DAIFMT_LEFT_J:
1636 break;
1637 default:
1638 return -EINVAL;
1639 }
1640
1641 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1642 case SND_SOC_DAIFMT_NB_NF:
1643 break;
1644 case SND_SOC_DAIFMT_NB_IF:
1645 regval |= M98095_DAI_WCI;
1646 break;
1647 case SND_SOC_DAIFMT_IB_NF:
1648 regval |= M98095_DAI_BCI;
1649 break;
1650 case SND_SOC_DAIFMT_IB_IF:
1651 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1652 break;
1653 default:
1654 return -EINVAL;
1655 }
1656
1657 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1658 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1659 M98095_DAI_WCI, regval);
1660
1661 snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
1662 M98095_DAI_BSEL64);
1663 }
1664
1665 return 0;
1666}
1667
1668static int max98095_set_bias_level(struct snd_soc_codec *codec,
1669 enum snd_soc_bias_level level)
1670{
1671 int ret;
1672
1673 switch (level) {
1674 case SND_SOC_BIAS_ON:
1675 break;
1676
1677 case SND_SOC_BIAS_PREPARE:
1678 break;
1679
1680 case SND_SOC_BIAS_STANDBY:
1681 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1682 ret = snd_soc_cache_sync(codec);
1683
1684 if (ret != 0) {
1685 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
1686 return ret;
1687 }
1688 }
1689
1690 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1691 M98095_MBEN, M98095_MBEN);
1692 break;
1693
1694 case SND_SOC_BIAS_OFF:
1695 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1696 M98095_MBEN, 0);
1697 codec->cache_sync = 1;
1698 break;
1699 }
1700 codec->dapm.bias_level = level;
1701 return 0;
1702}
1703
1704#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
1705#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
1706
1707static struct snd_soc_dai_ops max98095_dai1_ops = {
1708 .set_sysclk = max98095_dai_set_sysclk,
1709 .set_fmt = max98095_dai1_set_fmt,
1710 .hw_params = max98095_dai1_hw_params,
1711};
1712
1713static struct snd_soc_dai_ops max98095_dai2_ops = {
1714 .set_sysclk = max98095_dai_set_sysclk,
1715 .set_fmt = max98095_dai2_set_fmt,
1716 .hw_params = max98095_dai2_hw_params,
1717};
1718
1719static struct snd_soc_dai_ops max98095_dai3_ops = {
1720 .set_sysclk = max98095_dai_set_sysclk,
1721 .set_fmt = max98095_dai3_set_fmt,
1722 .hw_params = max98095_dai3_hw_params,
1723};
1724
1725static struct snd_soc_dai_driver max98095_dai[] = {
1726{
1727 .name = "HiFi",
1728 .playback = {
1729 .stream_name = "HiFi Playback",
1730 .channels_min = 1,
1731 .channels_max = 2,
1732 .rates = MAX98095_RATES,
1733 .formats = MAX98095_FORMATS,
1734 },
1735 .capture = {
1736 .stream_name = "HiFi Capture",
1737 .channels_min = 1,
1738 .channels_max = 2,
1739 .rates = MAX98095_RATES,
1740 .formats = MAX98095_FORMATS,
1741 },
1742 .ops = &max98095_dai1_ops,
1743},
1744{
1745 .name = "Aux",
1746 .playback = {
1747 .stream_name = "Aux Playback",
1748 .channels_min = 1,
1749 .channels_max = 1,
1750 .rates = MAX98095_RATES,
1751 .formats = MAX98095_FORMATS,
1752 },
1753 .ops = &max98095_dai2_ops,
1754},
1755{
1756 .name = "Voice",
1757 .playback = {
1758 .stream_name = "Voice Playback",
1759 .channels_min = 1,
1760 .channels_max = 1,
1761 .rates = MAX98095_RATES,
1762 .formats = MAX98095_FORMATS,
1763 },
1764 .ops = &max98095_dai3_ops,
1765}
1766
1767};
1768
1769static void max98095_handle_pdata(struct snd_soc_codec *codec)
1770{
1771 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1772 struct max98095_pdata *pdata = max98095->pdata;
1773 u8 regval = 0;
1774
1775 if (!pdata) {
1776 dev_dbg(codec->dev, "No platform data\n");
1777 return;
1778 }
1779
1780 /* Configure mic for analog/digital mic mode */
1781 if (pdata->digmic_left_mode)
1782 regval |= M98095_DIGMIC_L;
1783
1784 if (pdata->digmic_right_mode)
1785 regval |= M98095_DIGMIC_R;
1786
1787 snd_soc_write(codec, M98095_087_CFG_MIC, regval);
1788}
1789
1790#ifdef CONFIG_PM
1791static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state)
1792{
1793 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
1794
1795 return 0;
1796}
1797
1798static int max98095_resume(struct snd_soc_codec *codec)
1799{
1800 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1801
1802 return 0;
1803}
1804#else
1805#define max98095_suspend NULL
1806#define max98095_resume NULL
1807#endif
1808
1809static int max98095_reset(struct snd_soc_codec *codec)
1810{
1811 int i, ret;
1812
1813 /* Gracefully reset the DSP core and the codec hardware
1814 * in a proper sequence */
1815 ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
1816 if (ret < 0) {
1817 dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
1818 return ret;
1819 }
1820
1821 ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
1822 if (ret < 0) {
1823 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
1824 return ret;
1825 }
1826
1827 /* Reset to hardware default for registers, as there is not
1828 * a soft reset hardware control register */
1829 for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
1830 ret = snd_soc_write(codec, i, max98095_reg_def[i]);
1831 if (ret < 0) {
1832 dev_err(codec->dev, "Failed to reset: %d\n", ret);
1833 return ret;
1834 }
1835 }
1836
1837 return ret;
1838}
1839
1840static int max98095_probe(struct snd_soc_codec *codec)
1841{
1842 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1843 struct max98095_cdata *cdata;
1844 int ret = 0;
1845
1846 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
1847 if (ret != 0) {
1848 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1849 return ret;
1850 }
1851
1852 /* reset the codec, the DSP core, and disable all interrupts */
1853 max98095_reset(codec);
1854
1855 /* initialize private data */
1856
1857 max98095->sysclk = (unsigned)-1;
1858
1859 cdata = &max98095->dai[0];
1860 cdata->rate = (unsigned)-1;
1861 cdata->fmt = (unsigned)-1;
1862
1863 cdata = &max98095->dai[1];
1864 cdata->rate = (unsigned)-1;
1865 cdata->fmt = (unsigned)-1;
1866
1867 cdata = &max98095->dai[2];
1868 cdata->rate = (unsigned)-1;
1869 cdata->fmt = (unsigned)-1;
1870
1871 max98095->lin_state = 0;
1872 max98095->mic1pre = 0;
1873 max98095->mic2pre = 0;
1874
1875 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
1876 if (ret < 0) {
1877 dev_err(codec->dev, "Failed to read device revision: %d\n",
1878 ret);
1879 goto err_access;
1880 }
1881 dev_info(codec->dev, "revision %c\n", ret + 'A');
1882
1883 snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
1884
1885 /* initialize registers cache to hardware default */
1886 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1887
1888 snd_soc_write(codec, M98095_048_MIX_DAC_LR,
1889 M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
1890
1891 snd_soc_write(codec, M98095_049_MIX_DAC_M,
1892 M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
1893
1894 snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
1895 snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
1896 snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
1897
1898 snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
1899 M98095_S1NORMAL|M98095_SDATA);
1900
1901 snd_soc_write(codec, M98095_036_DAI2_IOCFG,
1902 M98095_S2NORMAL|M98095_SDATA);
1903
1904 snd_soc_write(codec, M98095_040_DAI3_IOCFG,
1905 M98095_S3NORMAL|M98095_SDATA);
1906
1907 max98095_handle_pdata(codec);
1908
1909 /* take the codec out of the shut down */
1910 snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
1911 M98095_SHDNRUN);
1912
1913 max98095_add_widgets(codec);
1914
1915err_access:
1916 return ret;
1917}
1918
1919static int max98095_remove(struct snd_soc_codec *codec)
1920{
1921 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
1922
1923 return 0;
1924}
1925
1926static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
1927 .probe = max98095_probe,
1928 .remove = max98095_remove,
1929 .suspend = max98095_suspend,
1930 .resume = max98095_resume,
1931 .set_bias_level = max98095_set_bias_level,
1932 .reg_cache_size = ARRAY_SIZE(max98095_reg_def),
1933 .reg_word_size = sizeof(u8),
1934 .reg_cache_default = max98095_reg_def,
1935 .readable_register = max98095_readable,
1936 .volatile_register = max98095_volatile,
1937 .dapm_widgets = max98095_dapm_widgets,
1938 .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
1939 .dapm_routes = max98095_audio_map,
1940 .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
1941};
1942
1943static int max98095_i2c_probe(struct i2c_client *i2c,
1944 const struct i2c_device_id *id)
1945{
1946 struct max98095_priv *max98095;
1947 int ret;
1948
1949 max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL);
1950 if (max98095 == NULL)
1951 return -ENOMEM;
1952
1953 max98095->devtype = id->driver_data;
1954 i2c_set_clientdata(i2c, max98095);
1955 max98095->control_data = i2c;
1956 max98095->pdata = i2c->dev.platform_data;
1957
1958 ret = snd_soc_register_codec(&i2c->dev,
1959 &soc_codec_dev_max98095, &max98095_dai[0], 3);
1960 if (ret < 0)
1961 kfree(max98095);
1962 return ret;
1963}
1964
1965static int __devexit max98095_i2c_remove(struct i2c_client *client)
1966{
1967 snd_soc_unregister_codec(&client->dev);
1968 kfree(i2c_get_clientdata(client));
1969
1970 return 0;
1971}
1972
1973static const struct i2c_device_id max98095_i2c_id[] = {
1974 { "max98095", MAX98095 },
1975 { }
1976};
1977MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
1978
1979static struct i2c_driver max98095_i2c_driver = {
1980 .driver = {
1981 .name = "max98095",
1982 .owner = THIS_MODULE,
1983 },
1984 .probe = max98095_i2c_probe,
1985 .remove = __devexit_p(max98095_i2c_remove),
1986 .id_table = max98095_i2c_id,
1987};
1988
1989static int __init max98095_init(void)
1990{
1991 int ret;
1992
1993 ret = i2c_add_driver(&max98095_i2c_driver);
1994 if (ret)
1995 pr_err("Failed to register max98095 I2C driver: %d\n", ret);
1996
1997 return ret;
1998}
1999module_init(max98095_init);
2000
2001static void __exit max98095_exit(void)
2002{
2003 i2c_del_driver(&max98095_i2c_driver);
2004}
2005module_exit(max98095_exit);
2006
2007MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
2008MODULE_AUTHOR("Peter Hsiang");
2009MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
new file mode 100644
index 000000000000..5b22bc8dbede
--- /dev/null
+++ b/sound/soc/codecs/max98095.h
@@ -0,0 +1,284 @@
1/*
2 * max98095.h -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98095_H
12#define _MAX98095_H
13
14/*
15 * MAX98095 Registers Definition
16 */
17
18#define M98095_000_HOST_DATA 0x00
19#define M98095_001_HOST_INT_STS 0x01
20#define M98095_002_HOST_RSP_STS 0x02
21#define M98095_003_HOST_CMD_STS 0x03
22#define M98095_004_CODEC_STS 0x04
23#define M98095_005_DAI1_ALC_STS 0x05
24#define M98095_006_DAI2_ALC_STS 0x06
25#define M98095_007_JACK_AUTO_STS 0x07
26#define M98095_008_JACK_MANUAL_STS 0x08
27#define M98095_009_JACK_VBAT_STS 0x09
28#define M98095_00A_ACC_ADC_STS 0x0A
29#define M98095_00B_MIC_NG_AGC_STS 0x0B
30#define M98095_00C_SPK_L_VOLT_STS 0x0C
31#define M98095_00D_SPK_R_VOLT_STS 0x0D
32#define M98095_00E_TEMP_SENSOR_STS 0x0E
33#define M98095_00F_HOST_CFG 0x0F
34#define M98095_010_HOST_INT_CFG 0x10
35#define M98095_011_HOST_INT_EN 0x11
36#define M98095_012_CODEC_INT_EN 0x12
37#define M98095_013_JACK_INT_EN 0x13
38#define M98095_014_JACK_INT_EN 0x14
39#define M98095_015_DEC 0x15
40#define M98095_016_RESERVED 0x16
41#define M98095_017_RESERVED 0x17
42#define M98095_018_KEYCODE3 0x18
43#define M98095_019_KEYCODE2 0x19
44#define M98095_01A_KEYCODE1 0x1A
45#define M98095_01B_KEYCODE0 0x1B
46#define M98095_01C_OEMCODE1 0x1C
47#define M98095_01D_OEMCODE0 0x1D
48#define M98095_01E_XCFG1 0x1E
49#define M98095_01F_XCFG2 0x1F
50#define M98095_020_XCFG3 0x20
51#define M98095_021_XCFG4 0x21
52#define M98095_022_XCFG5 0x22
53#define M98095_023_XCFG6 0x23
54#define M98095_024_XGPIO 0x24
55#define M98095_025_XCLKCFG 0x25
56#define M98095_026_SYS_CLK 0x26
57#define M98095_027_DAI1_CLKMODE 0x27
58#define M98095_028_DAI1_CLKCFG_HI 0x28
59#define M98095_029_DAI1_CLKCFG_LO 0x29
60#define M98095_02A_DAI1_FORMAT 0x2A
61#define M98095_02B_DAI1_CLOCK 0x2B
62#define M98095_02C_DAI1_IOCFG 0x2C
63#define M98095_02D_DAI1_TDM 0x2D
64#define M98095_02E_DAI1_FILTERS 0x2E
65#define M98095_02F_DAI1_LVL1 0x2F
66#define M98095_030_DAI1_LVL2 0x30
67#define M98095_031_DAI2_CLKMODE 0x31
68#define M98095_032_DAI2_CLKCFG_HI 0x32
69#define M98095_033_DAI2_CLKCFG_LO 0x33
70#define M98095_034_DAI2_FORMAT 0x34
71#define M98095_035_DAI2_CLOCK 0x35
72#define M98095_036_DAI2_IOCFG 0x36
73#define M98095_037_DAI2_TDM 0x37
74#define M98095_038_DAI2_FILTERS 0x38
75#define M98095_039_DAI2_LVL1 0x39
76#define M98095_03A_DAI2_LVL2 0x3A
77#define M98095_03B_DAI3_CLKMODE 0x3B
78#define M98095_03C_DAI3_CLKCFG_HI 0x3C
79#define M98095_03D_DAI3_CLKCFG_LO 0x3D
80#define M98095_03E_DAI3_FORMAT 0x3E
81#define M98095_03F_DAI3_CLOCK 0x3F
82#define M98095_040_DAI3_IOCFG 0x40
83#define M98095_041_DAI3_TDM 0x41
84#define M98095_042_DAI3_FILTERS 0x42
85#define M98095_043_DAI3_LVL1 0x43
86#define M98095_044_DAI3_LVL2 0x44
87#define M98095_045_CFG_DSP 0x45
88#define M98095_046_DAC_CTRL1 0x46
89#define M98095_047_DAC_CTRL2 0x47
90#define M98095_048_MIX_DAC_LR 0x48
91#define M98095_049_MIX_DAC_M 0x49
92#define M98095_04A_MIX_ADC_LEFT 0x4A
93#define M98095_04B_MIX_ADC_RIGHT 0x4B
94#define M98095_04C_MIX_HP_LEFT 0x4C
95#define M98095_04D_MIX_HP_RIGHT 0x4D
96#define M98095_04E_CFG_HP 0x4E
97#define M98095_04F_MIX_RCV 0x4F
98#define M98095_050_MIX_SPK_LEFT 0x50
99#define M98095_051_MIX_SPK_RIGHT 0x51
100#define M98095_052_MIX_SPK_CFG 0x52
101#define M98095_053_MIX_LINEOUT1 0x53
102#define M98095_054_MIX_LINEOUT2 0x54
103#define M98095_055_MIX_LINEOUT_CFG 0x55
104#define M98095_056_LVL_SIDETONE_DAI12 0x56
105#define M98095_057_LVL_SIDETONE_DAI3 0x57
106#define M98095_058_LVL_DAI1_PLAY 0x58
107#define M98095_059_LVL_DAI1_EQ 0x59
108#define M98095_05A_LVL_DAI2_PLAY 0x5A
109#define M98095_05B_LVL_DAI2_EQ 0x5B
110#define M98095_05C_LVL_DAI3_PLAY 0x5C
111#define M98095_05D_LVL_ADC_L 0x5D
112#define M98095_05E_LVL_ADC_R 0x5E
113#define M98095_05F_LVL_MIC1 0x5F
114#define M98095_060_LVL_MIC2 0x60
115#define M98095_061_LVL_LINEIN 0x61
116#define M98095_062_LVL_LINEOUT1 0x62
117#define M98095_063_LVL_LINEOUT2 0x63
118#define M98095_064_LVL_HP_L 0x64
119#define M98095_065_LVL_HP_R 0x65
120#define M98095_066_LVL_RCV 0x66
121#define M98095_067_LVL_SPK_L 0x67
122#define M98095_068_LVL_SPK_R 0x68
123#define M98095_069_MICAGC_CFG 0x69
124#define M98095_06A_MICAGC_THRESH 0x6A
125#define M98095_06B_SPK_NOISEGATE 0x6B
126#define M98095_06C_DAI1_ALC1_TIME 0x6C
127#define M98095_06D_DAI1_ALC1_COMP 0x6D
128#define M98095_06E_DAI1_ALC1_EXPN 0x6E
129#define M98095_06F_DAI1_ALC1_GAIN 0x6F
130#define M98095_070_DAI1_ALC2_TIME 0x70
131#define M98095_071_DAI1_ALC2_COMP 0x71
132#define M98095_072_DAI1_ALC2_EXPN 0x72
133#define M98095_073_DAI1_ALC2_GAIN 0x73
134#define M98095_074_DAI1_ALC3_TIME 0x74
135#define M98095_075_DAI1_ALC3_COMP 0x75
136#define M98095_076_DAI1_ALC3_EXPN 0x76
137#define M98095_077_DAI1_ALC3_GAIN 0x77
138#define M98095_078_DAI2_ALC1_TIME 0x78
139#define M98095_079_DAI2_ALC1_COMP 0x79
140#define M98095_07A_DAI2_ALC1_EXPN 0x7A
141#define M98095_07B_DAI2_ALC1_GAIN 0x7B
142#define M98095_07C_DAI2_ALC2_TIME 0x7C
143#define M98095_07D_DAI2_ALC2_COMP 0x7D
144#define M98095_07E_DAI2_ALC2_EXPN 0x7E
145#define M98095_07F_DAI2_ALC2_GAIN 0x7F
146#define M98095_080_DAI2_ALC3_TIME 0x80
147#define M98095_081_DAI2_ALC3_COMP 0x81
148#define M98095_082_DAI2_ALC3_EXPN 0x82
149#define M98095_083_DAI2_ALC3_GAIN 0x83
150#define M98095_084_HP_NOISE_GATE 0x84
151#define M98095_085_AUX_ADC 0x85
152#define M98095_086_CFG_LINE 0x86
153#define M98095_087_CFG_MIC 0x87
154#define M98095_088_CFG_LEVEL 0x88
155#define M98095_089_JACK_DET_AUTO 0x89
156#define M98095_08A_JACK_DET_MANUAL 0x8A
157#define M98095_08B_JACK_KEYSCAN_DBC 0x8B
158#define M98095_08C_JACK_KEYSCAN_DLY 0x8C
159#define M98095_08D_JACK_KEY_THRESH 0x8D
160#define M98095_08E_JACK_DC_SLEW 0x8E
161#define M98095_08F_JACK_TEST_CFG 0x8F
162#define M98095_090_PWR_EN_IN 0x90
163#define M98095_091_PWR_EN_OUT 0x91
164#define M98095_092_PWR_EN_OUT 0x92
165#define M98095_093_BIAS_CTRL 0x93
166#define M98095_094_PWR_DAC_21 0x94
167#define M98095_095_PWR_DAC_03 0x95
168#define M98095_096_PWR_DAC_CK 0x96
169#define M98095_097_PWR_SYS 0x97
170
171#define M98095_0FF_REV_ID 0xFF
172
173#define M98095_REG_CNT (0xFF+1)
174#define M98095_REG_MAX_CACHED 0X97
175
176/* MAX98095 Registers Bit Fields */
177
178/* M98095_00F_HOST_CFG */
179 #define M98095_SEG (1<<0)
180 #define M98095_XTEN (1<<1)
181 #define M98095_MDLLEN (1<<2)
182
183/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 #define M98095_CLKMODE_MASK 0xFF
185
186/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
187 #define M98095_DAI_MAS (1<<7)
188 #define M98095_DAI_WCI (1<<6)
189 #define M98095_DAI_BCI (1<<5)
190 #define M98095_DAI_DLY (1<<4)
191 #define M98095_DAI_TDM (1<<2)
192 #define M98095_DAI_FSW (1<<1)
193 #define M98095_DAI_WS (1<<0)
194
195/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
196 #define M98095_DAI_BSEL64 (1<<0)
197 #define M98095_DAI_DOSR_DIV2 (0<<5)
198 #define M98095_DAI_DOSR_DIV4 (1<<5)
199
200/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
201 #define M98095_S1NORMAL (1<<6)
202 #define M98095_S2NORMAL (2<<6)
203 #define M98095_S3NORMAL (3<<6)
204 #define M98095_SDATA (3<<0)
205
206/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
207 #define M98095_DAI_DHF (1<<3)
208
209/* M98095_045_DSP_CFG */
210 #define M98095_DSPNORMAL (5<<4)
211
212/* M98095_048_MIX_DAC_LR */
213 #define M98095_DAI1L_TO_DACR (1<<7)
214 #define M98095_DAI1R_TO_DACR (1<<6)
215 #define M98095_DAI2M_TO_DACR (1<<5)
216 #define M98095_DAI1L_TO_DACL (1<<3)
217 #define M98095_DAI1R_TO_DACL (1<<2)
218 #define M98095_DAI2M_TO_DACL (1<<1)
219 #define M98095_DAI3M_TO_DACL (1<<0)
220
221/* M98095_049_MIX_DAC_M */
222 #define M98095_DAI1L_TO_DACM (1<<3)
223 #define M98095_DAI1R_TO_DACM (1<<2)
224 #define M98095_DAI2M_TO_DACM (1<<1)
225 #define M98095_DAI3M_TO_DACM (1<<0)
226
227/* M98095_04E_MIX_HP_CFG */
228 #define M98095_HPNORMAL (3<<4)
229
230/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
231 #define M98095_MICPRE_MASK (3<<5)
232 #define M98095_MICPRE_SHIFT 5
233
234/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
235 #define M98095_HP_MUTE (1<<7)
236
237/* M98095_066_LVL_RCV */
238 #define M98095_REC_MUTE (1<<7)
239
240/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
241 #define M98095_SP_MUTE (1<<7)
242
243/* M98095_087_CFG_MIC */
244 #define M98095_MICSEL_MASK (3<<0)
245 #define M98095_DIGMIC_L (1<<2)
246 #define M98095_DIGMIC_R (1<<3)
247 #define M98095_DIGMIC2L (1<<4)
248 #define M98095_DIGMIC2R (1<<5)
249
250/* M98095_088_CFG_LEVEL */
251 #define M98095_VSEN (1<<6)
252 #define M98095_ZDEN (1<<5)
253 #define M98095_EQ2EN (1<<1)
254 #define M98095_EQ1EN (1<<0)
255
256/* M98095_090_PWR_EN_IN */
257 #define M98095_INEN (1<<7)
258 #define M98095_MB2EN (1<<3)
259 #define M98095_MB1EN (1<<2)
260 #define M98095_MBEN (3<<2)
261 #define M98095_ADREN (1<<1)
262 #define M98095_ADLEN (1<<0)
263
264/* M98095_091_PWR_EN_OUT */
265 #define M98095_HPLEN (1<<7)
266 #define M98095_HPREN (1<<6)
267 #define M98095_SPLEN (1<<5)
268 #define M98095_SPREN (1<<4)
269 #define M98095_RECEN (1<<3)
270 #define M98095_DALEN (1<<1)
271 #define M98095_DAREN (1<<0)
272
273/* M98095_092_PWR_EN_OUT */
274 #define M98095_SPK_FIXEDSPECTRUM (0<<4)
275 #define M98095_SPK_SPREADSPECTRUM (1<<4)
276
277/* M98095_097_PWR_SYS */
278 #define M98095_SHDNRUN (1<<7)
279 #define M98095_PERFMODE (1<<3)
280 #define M98095_HPPLYBACK (1<<2)
281 #define M98095_PWRSV8K (1<<1)
282 #define M98095_PWRSV (1<<0)
283
284#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 4d9fb279e146..84ffdebb8a8b 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -827,8 +827,6 @@ EXPORT_SYMBOL_GPL(sn95031_jack_detection);
827/* codec registration */ 827/* codec registration */
828static int sn95031_codec_probe(struct snd_soc_codec *codec) 828static int sn95031_codec_probe(struct snd_soc_codec *codec)
829{ 829{
830 int ret;
831
832 pr_debug("codec_probe called\n"); 830 pr_debug("codec_probe called\n");
833 831
834 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
@@ -879,16 +877,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
879 snd_soc_add_controls(codec, sn95031_snd_controls, 877 snd_soc_add_controls(codec, sn95031_snd_controls,
880 ARRAY_SIZE(sn95031_snd_controls)); 878 ARRAY_SIZE(sn95031_snd_controls));
881 879
882 ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, 880 return 0;
883 ARRAY_SIZE(sn95031_dapm_widgets));
884 if (ret)
885 pr_err("soc_dapm_new_control failed %d", ret);
886 ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map,
887 ARRAY_SIZE(sn95031_audio_map));
888 if (ret)
889 pr_err("soc_dapm_add_routes failed %d", ret);
890
891 return ret;
892} 881}
893 882
894static int sn95031_codec_remove(struct snd_soc_codec *codec) 883static int sn95031_codec_remove(struct snd_soc_codec *codec)
@@ -905,6 +894,10 @@ struct snd_soc_codec_driver sn95031_codec = {
905 .read = sn95031_read, 894 .read = sn95031_read,
906 .write = sn95031_write, 895 .write = sn95031_write,
907 .set_bias_level = sn95031_set_vaud_bias, 896 .set_bias_level = sn95031_set_vaud_bias,
897 .dapm_widgets = sn95031_dapm_widgets,
898 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
899 .dapm_routes = sn95031_audio_map,
900 .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
908}; 901};
909 902
910static int __devinit sn95031_device_probe(struct platform_device *pdev) 903static int __devinit sn95031_device_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 2727befd158e..7e2194975360 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/spi/spi.h>
35#include <linux/platform_device.h> 36#include <linux/platform_device.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <sound/core.h> 38#include <sound/core.h>
@@ -48,7 +49,6 @@
48struct ssm2602_priv { 49struct ssm2602_priv {
49 unsigned int sysclk; 50 unsigned int sysclk;
50 enum snd_soc_control_type control_type; 51 enum snd_soc_control_type control_type;
51 void *control_data;
52 struct snd_pcm_substream *master_substream; 52 struct snd_pcm_substream *master_substream;
53 struct snd_pcm_substream *slave_substream; 53 struct snd_pcm_substream *slave_substream;
54}; 54};
@@ -65,55 +65,7 @@ static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
65 0x0000, 0x0000 65 0x0000, 0x0000
66}; 66};
67 67
68/* 68#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0)
69 * read ssm2602 register cache
70 */
71static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
72 unsigned int reg)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg == SSM2602_RESET)
76 return 0;
77 if (reg >= SSM2602_CACHEREGNUM)
78 return -1;
79 return cache[reg];
80}
81
82/*
83 * write ssm2602 register cache
84 */
85static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
86 u16 reg, unsigned int value)
87{
88 u16 *cache = codec->reg_cache;
89 if (reg >= SSM2602_CACHEREGNUM)
90 return;
91 cache[reg] = value;
92}
93
94/*
95 * write to the ssm2602 register space
96 */
97static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
98 unsigned int value)
99{
100 u8 data[2];
101
102 /* data is
103 * D15..D9 ssm2602 register offset
104 * D8...D0 register data
105 */
106 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107 data[1] = value & 0x00ff;
108
109 ssm2602_write_reg_cache(codec, reg, value);
110 if (codec->hw_write(codec->control_data, data, 2) == 2)
111 return 0;
112 else
113 return -EIO;
114}
115
116#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
117 69
118/*Appending several "None"s just for OSS mixer use*/ 70/*Appending several "None"s just for OSS mixer use*/
119static const char *ssm2602_input_select[] = { 71static const char *ssm2602_input_select[] = {
@@ -278,12 +230,11 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
278 struct snd_soc_pcm_runtime *rtd = substream->private_data; 230 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_codec *codec = rtd->codec; 231 struct snd_soc_codec *codec = rtd->codec;
280 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 232 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
281 struct i2c_client *i2c = codec->control_data; 233 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
283 int i = get_coeff(ssm2602->sysclk, params_rate(params)); 234 int i = get_coeff(ssm2602->sysclk, params_rate(params));
284 235
285 if (substream == ssm2602->slave_substream) { 236 if (substream == ssm2602->slave_substream) {
286 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 237 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
287 return 0; 238 return 0;
288 } 239 }
289 240
@@ -294,8 +245,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
294 srate = (coeff_div[i].sr << 2) | 245 srate = (coeff_div[i].sr << 2) |
295 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 246 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
296 247
297 ssm2602_write(codec, SSM2602_ACTIVE, 0); 248 snd_soc_write(codec, SSM2602_ACTIVE, 0);
298 ssm2602_write(codec, SSM2602_SRATE, srate); 249 snd_soc_write(codec, SSM2602_SRATE, srate);
299 250
300 /* bit size */ 251 /* bit size */
301 switch (params_format(params)) { 252 switch (params_format(params)) {
@@ -311,8 +262,8 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
311 iface |= 0x000c; 262 iface |= 0x000c;
312 break; 263 break;
313 } 264 }
314 ssm2602_write(codec, SSM2602_IFACE, iface); 265 snd_soc_write(codec, SSM2602_IFACE, iface);
315 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); 266 snd_soc_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
316 return 0; 267 return 0;
317} 268}
318 269
@@ -360,7 +311,7 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
360 struct snd_soc_pcm_runtime *rtd = substream->private_data; 311 struct snd_soc_pcm_runtime *rtd = substream->private_data;
361 struct snd_soc_codec *codec = rtd->codec; 312 struct snd_soc_codec *codec = rtd->codec;
362 /* set active */ 313 /* set active */
363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); 314 snd_soc_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
364 315
365 return 0; 316 return 0;
366} 317}
@@ -374,7 +325,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
374 325
375 /* deactivate */ 326 /* deactivate */
376 if (!codec->active) 327 if (!codec->active)
377 ssm2602_write(codec, SSM2602_ACTIVE, 0); 328 snd_soc_write(codec, SSM2602_ACTIVE, 0);
378 329
379 if (ssm2602->master_substream == substream) 330 if (ssm2602->master_substream == substream)
380 ssm2602->master_substream = ssm2602->slave_substream; 331 ssm2602->master_substream = ssm2602->slave_substream;
@@ -385,12 +336,12 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
385static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 336static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
386{ 337{
387 struct snd_soc_codec *codec = dai->codec; 338 struct snd_soc_codec *codec = dai->codec;
388 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; 339 u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
389 if (mute) 340 if (mute)
390 ssm2602_write(codec, SSM2602_APDIGI, 341 snd_soc_write(codec, SSM2602_APDIGI,
391 mute_reg | APDIGI_ENABLE_DAC_MUTE); 342 mute_reg | APDIGI_ENABLE_DAC_MUTE);
392 else 343 else
393 ssm2602_write(codec, SSM2602_APDIGI, mute_reg); 344 snd_soc_write(codec, SSM2602_APDIGI, mute_reg);
394 return 0; 345 return 0;
395} 346}
396 347
@@ -466,30 +417,30 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
466 } 417 }
467 418
468 /* set iface */ 419 /* set iface */
469 ssm2602_write(codec, SSM2602_IFACE, iface); 420 snd_soc_write(codec, SSM2602_IFACE, iface);
470 return 0; 421 return 0;
471} 422}
472 423
473static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 424static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
474 enum snd_soc_bias_level level) 425 enum snd_soc_bias_level level)
475{ 426{
476 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f; 427 u16 reg = snd_soc_read(codec, SSM2602_PWR) & 0xff7f;
477 428
478 switch (level) { 429 switch (level) {
479 case SND_SOC_BIAS_ON: 430 case SND_SOC_BIAS_ON:
480 /* vref/mid, osc on, dac unmute */ 431 /* vref/mid, osc on, dac unmute */
481 ssm2602_write(codec, SSM2602_PWR, reg); 432 snd_soc_write(codec, SSM2602_PWR, reg);
482 break; 433 break;
483 case SND_SOC_BIAS_PREPARE: 434 case SND_SOC_BIAS_PREPARE:
484 break; 435 break;
485 case SND_SOC_BIAS_STANDBY: 436 case SND_SOC_BIAS_STANDBY:
486 /* everything off except vref/vmid, */ 437 /* everything off except vref/vmid, */
487 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); 438 snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
488 break; 439 break;
489 case SND_SOC_BIAS_OFF: 440 case SND_SOC_BIAS_OFF:
490 /* everything off, dac mute, inactive */ 441 /* everything off, dac mute, inactive */
491 ssm2602_write(codec, SSM2602_ACTIVE, 0); 442 snd_soc_write(codec, SSM2602_ACTIVE, 0);
492 ssm2602_write(codec, SSM2602_PWR, 0xffff); 443 snd_soc_write(codec, SSM2602_PWR, 0xffff);
493 break; 444 break;
494 445
495 } 446 }
@@ -539,17 +490,10 @@ static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
539 490
540static int ssm2602_resume(struct snd_soc_codec *codec) 491static int ssm2602_resume(struct snd_soc_codec *codec)
541{ 492{
542 int i; 493 snd_soc_cache_sync(codec);
543 u8 data[2]; 494
544 u16 *cache = codec->reg_cache;
545
546 /* Sync reg_cache with the hardware */
547 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
548 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
549 data[1] = cache[i] & 0x00ff;
550 codec->hw_write(codec->control_data, data, 2);
551 }
552 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 495 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
496
553 return 0; 497 return 0;
554} 498}
555 499
@@ -560,31 +504,39 @@ static int ssm2602_probe(struct snd_soc_codec *codec)
560 504
561 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 505 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
562 506
563 codec->control_data = ssm2602->control_data; 507 ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type);
508 if (ret < 0) {
509 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
510 return ret;
511 }
564 512
565 ssm2602_reset(codec); 513 ret = ssm2602_reset(codec);
514 if (ret < 0) {
515 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
516 return ret;
517 }
566 518
567 /*power on device*/ 519 /*power on device*/
568 ssm2602_write(codec, SSM2602_ACTIVE, 0); 520 snd_soc_write(codec, SSM2602_ACTIVE, 0);
569 /* set the update bits */ 521 /* set the update bits */
570 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL); 522 reg = snd_soc_read(codec, SSM2602_LINVOL);
571 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); 523 snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
572 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL); 524 reg = snd_soc_read(codec, SSM2602_RINVOL);
573 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); 525 snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
574 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V); 526 reg = snd_soc_read(codec, SSM2602_LOUT1V);
575 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH); 527 snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
576 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V); 528 reg = snd_soc_read(codec, SSM2602_ROUT1V);
577 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); 529 snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
578 /*select Line in as default input*/ 530 /*select Line in as default input*/
579 ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 531 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
580 APANA_ENABLE_MIC_BOOST); 532 APANA_ENABLE_MIC_BOOST);
581 ssm2602_write(codec, SSM2602_PWR, 0); 533 snd_soc_write(codec, SSM2602_PWR, 0);
582 534
583 snd_soc_add_controls(codec, ssm2602_snd_controls, 535 snd_soc_add_controls(codec, ssm2602_snd_controls,
584 ARRAY_SIZE(ssm2602_snd_controls)); 536 ARRAY_SIZE(ssm2602_snd_controls));
585 ssm2602_add_widgets(codec); 537 ssm2602_add_widgets(codec);
586 538
587 return ret; 539 return 0;
588} 540}
589 541
590/* remove everything here */ 542/* remove everything here */
@@ -599,14 +551,49 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
599 .remove = ssm2602_remove, 551 .remove = ssm2602_remove,
600 .suspend = ssm2602_suspend, 552 .suspend = ssm2602_suspend,
601 .resume = ssm2602_resume, 553 .resume = ssm2602_resume,
602 .read = ssm2602_read_reg_cache,
603 .write = ssm2602_write,
604 .set_bias_level = ssm2602_set_bias_level, 554 .set_bias_level = ssm2602_set_bias_level,
605 .reg_cache_size = sizeof(ssm2602_reg), 555 .reg_cache_size = sizeof(ssm2602_reg),
606 .reg_word_size = sizeof(u16), 556 .reg_word_size = sizeof(u16),
607 .reg_cache_default = ssm2602_reg, 557 .reg_cache_default = ssm2602_reg,
608}; 558};
609 559
560#if defined(CONFIG_SPI_MASTER)
561static int __devinit ssm2602_spi_probe(struct spi_device *spi)
562{
563 struct ssm2602_priv *ssm2602;
564 int ret;
565
566 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
567 if (ssm2602 == NULL)
568 return -ENOMEM;
569
570 spi_set_drvdata(spi, ssm2602);
571 ssm2602->control_type = SND_SOC_SPI;
572
573 ret = snd_soc_register_codec(&spi->dev,
574 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
575 if (ret < 0)
576 kfree(ssm2602);
577 return ret;
578}
579
580static int __devexit ssm2602_spi_remove(struct spi_device *spi)
581{
582 snd_soc_unregister_codec(&spi->dev);
583 kfree(spi_get_drvdata(spi));
584 return 0;
585}
586
587static struct spi_driver ssm2602_spi_driver = {
588 .driver = {
589 .name = "ssm2602",
590 .owner = THIS_MODULE,
591 },
592 .probe = ssm2602_spi_probe,
593 .remove = __devexit_p(ssm2602_spi_remove),
594};
595#endif
596
610#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 597#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
611/* 598/*
612 * ssm2602 2 wire address is determined by GPIO5 599 * ssm2602 2 wire address is determined by GPIO5
@@ -625,7 +612,6 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c,
625 return -ENOMEM; 612 return -ENOMEM;
626 613
627 i2c_set_clientdata(i2c, ssm2602); 614 i2c_set_clientdata(i2c, ssm2602);
628 ssm2602->control_data = i2c;
629 ssm2602->control_type = SND_SOC_I2C; 615 ssm2602->control_type = SND_SOC_I2C;
630 616
631 ret = snd_soc_register_codec(&i2c->dev, 617 ret = snd_soc_register_codec(&i2c->dev,
@@ -651,7 +637,7 @@ MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
651/* corgi i2c codec control layer */ 637/* corgi i2c codec control layer */
652static struct i2c_driver ssm2602_i2c_driver = { 638static struct i2c_driver ssm2602_i2c_driver = {
653 .driver = { 639 .driver = {
654 .name = "ssm2602-codec", 640 .name = "ssm2602",
655 .owner = THIS_MODULE, 641 .owner = THIS_MODULE,
656 }, 642 },
657 .probe = ssm2602_i2c_probe, 643 .probe = ssm2602_i2c_probe,
@@ -664,19 +650,29 @@ static struct i2c_driver ssm2602_i2c_driver = {
664static int __init ssm2602_modinit(void) 650static int __init ssm2602_modinit(void)
665{ 651{
666 int ret = 0; 652 int ret = 0;
653
654#if defined(CONFIG_SPI_MASTER)
655 ret = spi_register_driver(&ssm2602_spi_driver);
656 if (ret)
657 return ret;
658#endif
659
667#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 660#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
668 ret = i2c_add_driver(&ssm2602_i2c_driver); 661 ret = i2c_add_driver(&ssm2602_i2c_driver);
669 if (ret != 0) { 662 if (ret)
670 printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n", 663 return ret;
671 ret);
672 }
673#endif 664#endif
665
674 return ret; 666 return ret;
675} 667}
676module_init(ssm2602_modinit); 668module_init(ssm2602_modinit);
677 669
678static void __exit ssm2602_exit(void) 670static void __exit ssm2602_exit(void)
679{ 671{
672#if defined(CONFIG_SPI_MASTER)
673 spi_unregister_driver(&ssm2602_spi_driver);
674#endif
675
680#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 676#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
681 i2c_del_driver(&ssm2602_i2c_driver); 677 i2c_del_driver(&ssm2602_i2c_driver);
682#endif 678#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 54a30ef0ec8b..33bb52f3f683 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -212,7 +212,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
212 SND_SOC_DAPM_INPUT("MICIN"), 212 SND_SOC_DAPM_INPUT("MICIN"),
213}; 213};
214 214
215static const struct snd_soc_dapm_route intercon[] = { 215static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
216 /* Output Mixer */ 216 /* Output Mixer */
217 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 217 {"Output Mixer", "Line Bypass Switch", "Line Input"},
218 {"Output Mixer", "Playback Switch", "DAC"}, 218 {"Output Mixer", "Playback Switch", "DAC"},
@@ -388,18 +388,6 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
388 return 0; 388 return 0;
389} 389}
390 390
391static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
392{
393 struct snd_soc_dapm_context *dapm = &codec->dapm;
394
395 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
396 ARRAY_SIZE(tlv320aic23_dapm_widgets));
397 /* set up audio path interconnects */
398 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
399
400 return 0;
401}
402
403static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 391static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
404 struct snd_pcm_hw_params *params, 392 struct snd_pcm_hw_params *params,
405 struct snd_soc_dai *dai) 393 struct snd_soc_dai *dai)
@@ -676,7 +664,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
676 664
677 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 665 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
678 ARRAY_SIZE(tlv320aic23_snd_controls)); 666 ARRAY_SIZE(tlv320aic23_snd_controls));
679 tlv320aic23_add_widgets(codec);
680 667
681 return 0; 668 return 0;
682} 669}
@@ -698,6 +685,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
698 .read = tlv320aic23_read_reg_cache, 685 .read = tlv320aic23_read_reg_cache,
699 .write = tlv320aic23_write, 686 .write = tlv320aic23_write,
700 .set_bias_level = tlv320aic23_set_bias_level, 687 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
690 .dapm_routes = tlv320aic23_intercon,
691 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
701}; 692};
702 693
703#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
new file mode 100644
index 000000000000..14d0716bf009
--- /dev/null
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -0,0 +1,108 @@
1/*
2 * Driver for the 1250-EV1 audio I/O module
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16
17#include <sound/soc.h>
18#include <sound/soc-dapm.h>
19
20static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
21SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
22SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0),
23
24SND_SOC_DAPM_INPUT("WM1250 Input"),
25SND_SOC_DAPM_INPUT("WM1250 Output"),
26};
27
28static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = {
29 { "ADC", NULL, "WM1250 Input" },
30 { "WM1250 Output", NULL, "DAC" },
31};
32
33static struct snd_soc_dai_driver wm1250_ev1_dai = {
34 .name = "wm1250-ev1",
35 .playback = {
36 .stream_name = "Playback",
37 .channels_min = 1,
38 .channels_max = 1,
39 .rates = SNDRV_PCM_RATE_8000,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE,
41 },
42 .capture = {
43 .stream_name = "Capture",
44 .channels_min = 1,
45 .channels_max = 1,
46 .rates = SNDRV_PCM_RATE_8000,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 },
49};
50
51static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
52 .dapm_widgets = wm1250_ev1_dapm_widgets,
53 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
54 .dapm_routes = wm1250_ev1_dapm_routes,
55 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
56};
57
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id)
60{
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
62 &wm1250_ev1_dai, 1);
63}
64
65static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
66{
67 snd_soc_unregister_codec(&i2c->dev);
68
69 return 0;
70}
71
72static const struct i2c_device_id wm1250_ev1_i2c_id[] = {
73 { "wm1250-ev1", 0 },
74 { }
75};
76MODULE_DEVICE_TABLE(i2c, wm1250_ev1_i2c_id);
77
78static struct i2c_driver wm1250_ev1_i2c_driver = {
79 .driver = {
80 .name = "wm1250-ev1",
81 .owner = THIS_MODULE,
82 },
83 .probe = wm1250_ev1_probe,
84 .remove = __devexit_p(wm1250_ev1_remove),
85 .id_table = wm1250_ev1_i2c_id,
86};
87
88static int __init wm1250_ev1_modinit(void)
89{
90 int ret = 0;
91
92 ret = i2c_add_driver(&wm1250_ev1_i2c_driver);
93 if (ret != 0)
94 pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret);
95
96 return ret;
97}
98module_init(wm1250_ev1_modinit);
99
100static void __exit wm1250_ev1_exit(void)
101{
102 i2c_del_driver(&wm1250_ev1_i2c_driver);
103}
104module_exit(wm1250_ev1_exit);
105
106MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
107MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver");
108MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 97c30382d3ff..a537e4af6ae7 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -77,7 +77,7 @@ SND_SOC_DAPM_OUTPUT("ROUT"),
77SND_SOC_DAPM_OUTPUT("RHPOUT"), 77SND_SOC_DAPM_OUTPUT("RHPOUT"),
78}; 78};
79 79
80static const struct snd_soc_dapm_route intercon[] = { 80static const struct snd_soc_dapm_route wm8711_intercon[] = {
81 /* output mixer */ 81 /* output mixer */
82 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 82 {"Output Mixer", "Line Bypass Switch", "Line Input"},
83 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 83 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -89,17 +89,6 @@ static const struct snd_soc_dapm_route intercon[] = {
89 {"LOUT", NULL, "Output Mixer"}, 89 {"LOUT", NULL, "Output Mixer"},
90}; 90};
91 91
92static int wm8711_add_widgets(struct snd_soc_codec *codec)
93{
94 struct snd_soc_dapm_context *dapm = &codec->dapm;
95
96 snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets,
97 ARRAY_SIZE(wm8711_dapm_widgets));
98 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
99
100 return 0;
101}
102
103struct _coeff_div { 92struct _coeff_div {
104 u32 mclk; 93 u32 mclk;
105 u32 rate; 94 u32 rate;
@@ -398,7 +387,6 @@ static int wm8711_probe(struct snd_soc_codec *codec)
398 387
399 snd_soc_add_controls(codec, wm8711_snd_controls, 388 snd_soc_add_controls(codec, wm8711_snd_controls,
400 ARRAY_SIZE(wm8711_snd_controls)); 389 ARRAY_SIZE(wm8711_snd_controls));
401 wm8711_add_widgets(codec);
402 390
403 return ret; 391 return ret;
404 392
@@ -420,6 +408,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
420 .reg_cache_size = ARRAY_SIZE(wm8711_reg), 408 .reg_cache_size = ARRAY_SIZE(wm8711_reg),
421 .reg_word_size = sizeof(u16), 409 .reg_word_size = sizeof(u16),
422 .reg_cache_default = wm8711_reg, 410 .reg_cache_default = wm8711_reg,
411 .dapm_widgets = wm8711_dapm_widgets,
412 .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
413 .dapm_routes = wm8711_intercon,
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
423}; 415};
424 416
425#if defined(CONFIG_SPI_MASTER) 417#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 736b0352d0a7..86d4718d3a76 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -65,22 +65,11 @@ SND_SOC_DAPM_OUTPUT("VOUTL"),
65SND_SOC_DAPM_OUTPUT("VOUTR"), 65SND_SOC_DAPM_OUTPUT("VOUTR"),
66}; 66};
67 67
68static const struct snd_soc_dapm_route intercon[] = { 68static const struct snd_soc_dapm_route wm8728_intercon[] = {
69 {"VOUTL", NULL, "DAC"}, 69 {"VOUTL", NULL, "DAC"},
70 {"VOUTR", NULL, "DAC"}, 70 {"VOUTR", NULL, "DAC"},
71}; 71};
72 72
73static int wm8728_add_widgets(struct snd_soc_codec *codec)
74{
75 struct snd_soc_dapm_context *dapm = &codec->dapm;
76
77 snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets,
78 ARRAY_SIZE(wm8728_dapm_widgets));
79 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
80
81 return 0;
82}
83
84static int wm8728_mute(struct snd_soc_dai *dai, int mute) 73static int wm8728_mute(struct snd_soc_dai *dai, int mute)
85{ 74{
86 struct snd_soc_codec *codec = dai->codec; 75 struct snd_soc_codec *codec = dai->codec;
@@ -255,7 +244,6 @@ static int wm8728_probe(struct snd_soc_codec *codec)
255 244
256 snd_soc_add_controls(codec, wm8728_snd_controls, 245 snd_soc_add_controls(codec, wm8728_snd_controls,
257 ARRAY_SIZE(wm8728_snd_controls)); 246 ARRAY_SIZE(wm8728_snd_controls));
258 wm8728_add_widgets(codec);
259 247
260 return ret; 248 return ret;
261} 249}
@@ -275,6 +263,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
275 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), 263 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
276 .reg_word_size = sizeof(u16), 264 .reg_word_size = sizeof(u16),
277 .reg_cache_default = wm8728_reg_defaults, 265 .reg_cache_default = wm8728_reg_defaults,
266 .dapm_widgets = wm8728_dapm_widgets,
267 .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
268 .dapm_routes = wm8728_intercon,
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
278}; 270};
279 271
280#if defined(CONFIG_SPI_MASTER) 272#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0a67c31b2663..6dec7cee2cb4 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -201,7 +201,7 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
201 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; 201 return wm8731->sysclk_type == WM8731_SYSCLK_MCLK;
202} 202}
203 203
204static const struct snd_soc_dapm_route intercon[] = { 204static const struct snd_soc_dapm_route wm8731_intercon[] = {
205 {"DAC", NULL, "OSC", wm8731_check_osc}, 205 {"DAC", NULL, "OSC", wm8731_check_osc},
206 {"ADC", NULL, "OSC", wm8731_check_osc}, 206 {"ADC", NULL, "OSC", wm8731_check_osc},
207 207
@@ -227,17 +227,6 @@ static const struct snd_soc_dapm_route intercon[] = {
227 {"Mic Bias", NULL, "MICIN"}, 227 {"Mic Bias", NULL, "MICIN"},
228}; 228};
229 229
230static int wm8731_add_widgets(struct snd_soc_codec *codec)
231{
232 struct snd_soc_dapm_context *dapm = &codec->dapm;
233
234 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
235 ARRAY_SIZE(wm8731_dapm_widgets));
236 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
237
238 return 0;
239}
240
241struct _coeff_div { 230struct _coeff_div {
242 u32 mclk; 231 u32 mclk;
243 u32 rate; 232 u32 rate;
@@ -599,7 +588,6 @@ static int wm8731_probe(struct snd_soc_codec *codec)
599 588
600 snd_soc_add_controls(codec, wm8731_snd_controls, 589 snd_soc_add_controls(codec, wm8731_snd_controls,
601 ARRAY_SIZE(wm8731_snd_controls)); 590 ARRAY_SIZE(wm8731_snd_controls));
602 wm8731_add_widgets(codec);
603 591
604 /* Regulators will have been enabled by bias management */ 592 /* Regulators will have been enabled by bias management */
605 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 593 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
@@ -636,6 +624,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
636 .reg_cache_size = ARRAY_SIZE(wm8731_reg), 624 .reg_cache_size = ARRAY_SIZE(wm8731_reg),
637 .reg_word_size = sizeof(u16), 625 .reg_word_size = sizeof(u16),
638 .reg_cache_default = wm8731_reg, 626 .reg_cache_default = wm8731_reg,
627 .dapm_widgets = wm8731_dapm_widgets,
628 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
629 .dapm_routes = wm8731_intercon,
630 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
639}; 631};
640 632
641#if defined(CONFIG_SPI_MASTER) 633#if defined(CONFIG_SPI_MASTER)
@@ -667,7 +659,7 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
667 659
668static struct spi_driver wm8731_spi_driver = { 660static struct spi_driver wm8731_spi_driver = {
669 .driver = { 661 .driver = {
670 .name = "wm8731-codec", 662 .name = "wm8731",
671 .owner = THIS_MODULE, 663 .owner = THIS_MODULE,
672 }, 664 },
673 .probe = wm8731_spi_probe, 665 .probe = wm8731_spi_probe,
@@ -711,7 +703,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
711 703
712static struct i2c_driver wm8731_i2c_driver = { 704static struct i2c_driver wm8731_i2c_driver = {
713 .driver = { 705 .driver = {
714 .name = "wm8731-codec", 706 .name = "wm8731",
715 .owner = THIS_MODULE, 707 .owner = THIS_MODULE,
716 }, 708 },
717 .probe = wm8731_i2c_probe, 709 .probe = wm8731_i2c_probe,
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index f52b623bb692..d53f206d6410 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -930,7 +930,7 @@ SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
930SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), 930SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
931}; 931};
932 932
933static const struct snd_soc_dapm_route intercon[] = { 933static const struct snd_soc_dapm_route wm8903_intercon[] = {
934 934
935 { "CLK_DSP", NULL, "CLK_SYS" }, 935 { "CLK_DSP", NULL, "CLK_SYS" },
936 { "Mic Bias", NULL, "CLK_SYS" }, 936 { "Mic Bias", NULL, "CLK_SYS" },
@@ -1087,17 +1087,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1087 { "Right Line Output PGA", NULL, "Charge Pump" }, 1087 { "Right Line Output PGA", NULL, "Charge Pump" },
1088}; 1088};
1089 1089
1090static int wm8903_add_widgets(struct snd_soc_codec *codec)
1091{
1092 struct snd_soc_dapm_context *dapm = &codec->dapm;
1093
1094 snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
1095 ARRAY_SIZE(wm8903_dapm_widgets));
1096 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1097
1098 return 0;
1099}
1100
1101static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1090static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1102 enum snd_soc_bias_level level) 1091 enum snd_soc_bias_level level)
1103{ 1092{
@@ -2028,7 +2017,6 @@ static int wm8903_probe(struct snd_soc_codec *codec)
2028 2017
2029 snd_soc_add_controls(codec, wm8903_snd_controls, 2018 snd_soc_add_controls(codec, wm8903_snd_controls,
2030 ARRAY_SIZE(wm8903_snd_controls)); 2019 ARRAY_SIZE(wm8903_snd_controls));
2031 wm8903_add_widgets(codec);
2032 2020
2033 wm8903_init_gpio(codec); 2021 wm8903_init_gpio(codec);
2034 2022
@@ -2054,6 +2042,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
2054 .reg_cache_default = wm8903_reg_defaults, 2042 .reg_cache_default = wm8903_reg_defaults,
2055 .volatile_register = wm8903_volatile_register, 2043 .volatile_register = wm8903_volatile_register,
2056 .seq_notifier = wm8903_seq_notifier, 2044 .seq_notifier = wm8903_seq_notifier,
2045 .dapm_widgets = wm8903_dapm_widgets,
2046 .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
2047 .dapm_routes = wm8903_intercon,
2048 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
2057}; 2049};
2058 2050
2059#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2051#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c
new file mode 100644
index 000000000000..083609418bf4
--- /dev/null
+++ b/sound/soc/codecs/wm8915.c
@@ -0,0 +1,2924 @@
1/*
2 * wm8915.c - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/completion.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/gcd.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22#include <linux/delay.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32#include <sound/tlv.h>
33#include <trace/events/asoc.h>
34
35#include <sound/wm8915.h>
36#include "wm8915.h"
37
38#define WM8915_AIFS 2
39
40#define HPOUT1L 1
41#define HPOUT1R 2
42#define HPOUT2L 4
43#define HPOUT2R 8
44
45#define WM8915_NUM_SUPPLIES 6
46static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
47 "DCVDD",
48 "DBVDD",
49 "AVDD1",
50 "AVDD2",
51 "CPVDD",
52 "MICVDD",
53};
54
55struct wm8915_priv {
56 struct snd_soc_codec *codec;
57
58 int ldo1ena;
59
60 int sysclk;
61
62 int fll_src;
63 int fll_fref;
64 int fll_fout;
65
66 struct completion fll_lock;
67
68 u16 dcs_pending;
69 struct completion dcs_done;
70
71 u16 hpout_ena;
72 u16 hpout_pending;
73
74 struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES];
75 struct notifier_block disable_nb[WM8915_NUM_SUPPLIES];
76
77 struct wm8915_pdata pdata;
78
79 int rx_rate[WM8915_AIFS];
80
81 /* Platform dependant ReTune mobile configuration */
82 int num_retune_mobile_texts;
83 const char **retune_mobile_texts;
84 int retune_mobile_cfg[2];
85 struct soc_enum retune_mobile_enum;
86
87 struct snd_soc_jack *jack;
88 bool detecting;
89 bool jack_mic;
90 wm8915_polarity_fn polarity_cb;
91
92#ifdef CONFIG_GPIOLIB
93 struct gpio_chip gpio_chip;
94#endif
95};
96
97/* We can't use the same notifier block for more than one supply and
98 * there's no way I can see to get from a callback to the caller
99 * except container_of().
100 */
101#define WM8915_REGULATOR_EVENT(n) \
102static int wm8915_regulator_event_##n(struct notifier_block *nb, \
103 unsigned long event, void *data) \
104{ \
105 struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \
106 disable_nb[n]); \
107 if (event & REGULATOR_EVENT_DISABLE) { \
108 wm8915->codec->cache_sync = 1; \
109 } \
110 return 0; \
111}
112
113WM8915_REGULATOR_EVENT(0)
114WM8915_REGULATOR_EVENT(1)
115WM8915_REGULATOR_EVENT(2)
116WM8915_REGULATOR_EVENT(3)
117WM8915_REGULATOR_EVENT(4)
118WM8915_REGULATOR_EVENT(5)
119
120static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
121 [WM8915_SOFTWARE_RESET] = 0x8915,
122 [WM8915_POWER_MANAGEMENT_7] = 0x10,
123 [WM8915_DAC1_HPOUT1_VOLUME] = 0x88,
124 [WM8915_DAC2_HPOUT2_VOLUME] = 0x88,
125 [WM8915_DAC1_LEFT_VOLUME] = 0x2c0,
126 [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0,
127 [WM8915_DAC2_LEFT_VOLUME] = 0x2c0,
128 [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0,
129 [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80,
130 [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80,
131 [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80,
132 [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80,
133 [WM8915_MICBIAS_1] = 0x39,
134 [WM8915_MICBIAS_2] = 0x39,
135 [WM8915_LDO_1] = 0x3,
136 [WM8915_LDO_2] = 0x13,
137 [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4,
138 [WM8915_HEADPHONE_DETECT_1] = 0x20,
139 [WM8915_MIC_DETECT_1] = 0x7600,
140 [WM8915_MIC_DETECT_2] = 0xbf,
141 [WM8915_CHARGE_PUMP_1] = 0x1f25,
142 [WM8915_CHARGE_PUMP_2] = 0xab19,
143 [WM8915_DC_SERVO_5] = 0x2a2a,
144 [WM8915_CONTROL_INTERFACE_1] = 0x8004,
145 [WM8915_CLOCKING_1] = 0x10,
146 [WM8915_AIF_RATE] = 0x83,
147 [WM8915_FLL_CONTROL_4] = 0x5dc0,
148 [WM8915_FLL_CONTROL_5] = 0xc84,
149 [WM8915_FLL_EFS_2] = 0x2,
150 [WM8915_AIF1_TX_LRCLK_1] = 0x80,
151 [WM8915_AIF1_TX_LRCLK_2] = 0x8,
152 [WM8915_AIF1_RX_LRCLK_1] = 0x80,
153 [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
154 [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818,
155 [WM8915_AIF1TX_TEST] = 0x7,
156 [WM8915_AIF2_TX_LRCLK_1] = 0x80,
157 [WM8915_AIF2_TX_LRCLK_2] = 0x8,
158 [WM8915_AIF2_RX_LRCLK_1] = 0x80,
159 [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
160 [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818,
161 [WM8915_AIF2TX_TEST] = 0x1,
162 [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0,
163 [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0,
164 [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0,
165 [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0,
166 [WM8915_DSP1_TX_FILTERS] = 0x2000,
167 [WM8915_DSP1_RX_FILTERS_1] = 0x200,
168 [WM8915_DSP1_RX_FILTERS_2] = 0x10,
169 [WM8915_DSP1_DRC_1] = 0x98,
170 [WM8915_DSP1_DRC_2] = 0x845,
171 [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318,
172 [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300,
173 [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca,
174 [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400,
175 [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
176 [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
177 [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145,
178 [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75,
179 [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
180 [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
181 [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373,
182 [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54,
183 [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558,
184 [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e,
185 [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829,
186 [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
187 [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
188 [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564,
189 [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559,
190 [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
191 [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0,
192 [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0,
193 [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0,
194 [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0,
195 [WM8915_DSP2_TX_FILTERS] = 0x2000,
196 [WM8915_DSP2_RX_FILTERS_1] = 0x200,
197 [WM8915_DSP2_RX_FILTERS_2] = 0x10,
198 [WM8915_DSP2_DRC_1] = 0x98,
199 [WM8915_DSP2_DRC_2] = 0x845,
200 [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318,
201 [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300,
202 [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca,
203 [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400,
204 [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
205 [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
206 [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145,
207 [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75,
208 [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
209 [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
210 [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373,
211 [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54,
212 [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558,
213 [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e,
214 [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829,
215 [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
216 [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
217 [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564,
218 [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559,
219 [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
220 [WM8915_OVERSAMPLING] = 0xd,
221 [WM8915_SIDETONE] = 0x1040,
222 [WM8915_GPIO_1] = 0xa101,
223 [WM8915_GPIO_2] = 0xa101,
224 [WM8915_GPIO_3] = 0xa101,
225 [WM8915_GPIO_4] = 0xa101,
226 [WM8915_GPIO_5] = 0xa101,
227 [WM8915_PULL_CONTROL_2] = 0x140,
228 [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f,
229 [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
230 [WM8915_RIGHT_PDM_SPEAKER] = 0x1,
231 [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
232 [WM8915_PDM_SPEAKER_VOLUME] = 0x66,
233 [WM8915_WRITE_SEQUENCER_0] = 0x1,
234 [WM8915_WRITE_SEQUENCER_1] = 0x1,
235 [WM8915_WRITE_SEQUENCER_3] = 0x6,
236 [WM8915_WRITE_SEQUENCER_4] = 0x40,
237 [WM8915_WRITE_SEQUENCER_5] = 0x1,
238 [WM8915_WRITE_SEQUENCER_6] = 0xf,
239 [WM8915_WRITE_SEQUENCER_7] = 0x6,
240 [WM8915_WRITE_SEQUENCER_8] = 0x1,
241 [WM8915_WRITE_SEQUENCER_9] = 0x3,
242 [WM8915_WRITE_SEQUENCER_10] = 0x104,
243 [WM8915_WRITE_SEQUENCER_12] = 0x60,
244 [WM8915_WRITE_SEQUENCER_13] = 0x11,
245 [WM8915_WRITE_SEQUENCER_14] = 0x401,
246 [WM8915_WRITE_SEQUENCER_16] = 0x50,
247 [WM8915_WRITE_SEQUENCER_17] = 0x3,
248 [WM8915_WRITE_SEQUENCER_18] = 0x100,
249 [WM8915_WRITE_SEQUENCER_20] = 0x51,
250 [WM8915_WRITE_SEQUENCER_21] = 0x3,
251 [WM8915_WRITE_SEQUENCER_22] = 0x104,
252 [WM8915_WRITE_SEQUENCER_23] = 0xa,
253 [WM8915_WRITE_SEQUENCER_24] = 0x60,
254 [WM8915_WRITE_SEQUENCER_25] = 0x3b,
255 [WM8915_WRITE_SEQUENCER_26] = 0x502,
256 [WM8915_WRITE_SEQUENCER_27] = 0x100,
257 [WM8915_WRITE_SEQUENCER_28] = 0x2fff,
258 [WM8915_WRITE_SEQUENCER_32] = 0x2fff,
259 [WM8915_WRITE_SEQUENCER_36] = 0x2fff,
260 [WM8915_WRITE_SEQUENCER_40] = 0x2fff,
261 [WM8915_WRITE_SEQUENCER_44] = 0x2fff,
262 [WM8915_WRITE_SEQUENCER_48] = 0x2fff,
263 [WM8915_WRITE_SEQUENCER_52] = 0x2fff,
264 [WM8915_WRITE_SEQUENCER_56] = 0x2fff,
265 [WM8915_WRITE_SEQUENCER_60] = 0x2fff,
266 [WM8915_WRITE_SEQUENCER_64] = 0x1,
267 [WM8915_WRITE_SEQUENCER_65] = 0x1,
268 [WM8915_WRITE_SEQUENCER_67] = 0x6,
269 [WM8915_WRITE_SEQUENCER_68] = 0x40,
270 [WM8915_WRITE_SEQUENCER_69] = 0x1,
271 [WM8915_WRITE_SEQUENCER_70] = 0xf,
272 [WM8915_WRITE_SEQUENCER_71] = 0x6,
273 [WM8915_WRITE_SEQUENCER_72] = 0x1,
274 [WM8915_WRITE_SEQUENCER_73] = 0x3,
275 [WM8915_WRITE_SEQUENCER_74] = 0x104,
276 [WM8915_WRITE_SEQUENCER_76] = 0x60,
277 [WM8915_WRITE_SEQUENCER_77] = 0x11,
278 [WM8915_WRITE_SEQUENCER_78] = 0x401,
279 [WM8915_WRITE_SEQUENCER_80] = 0x50,
280 [WM8915_WRITE_SEQUENCER_81] = 0x3,
281 [WM8915_WRITE_SEQUENCER_82] = 0x100,
282 [WM8915_WRITE_SEQUENCER_84] = 0x60,
283 [WM8915_WRITE_SEQUENCER_85] = 0x3b,
284 [WM8915_WRITE_SEQUENCER_86] = 0x502,
285 [WM8915_WRITE_SEQUENCER_87] = 0x100,
286 [WM8915_WRITE_SEQUENCER_88] = 0x2fff,
287 [WM8915_WRITE_SEQUENCER_92] = 0x2fff,
288 [WM8915_WRITE_SEQUENCER_96] = 0x2fff,
289 [WM8915_WRITE_SEQUENCER_100] = 0x2fff,
290 [WM8915_WRITE_SEQUENCER_104] = 0x2fff,
291 [WM8915_WRITE_SEQUENCER_108] = 0x2fff,
292 [WM8915_WRITE_SEQUENCER_112] = 0x2fff,
293 [WM8915_WRITE_SEQUENCER_116] = 0x2fff,
294 [WM8915_WRITE_SEQUENCER_120] = 0x2fff,
295 [WM8915_WRITE_SEQUENCER_124] = 0x2fff,
296 [WM8915_WRITE_SEQUENCER_128] = 0x1,
297 [WM8915_WRITE_SEQUENCER_129] = 0x1,
298 [WM8915_WRITE_SEQUENCER_131] = 0x6,
299 [WM8915_WRITE_SEQUENCER_132] = 0x40,
300 [WM8915_WRITE_SEQUENCER_133] = 0x1,
301 [WM8915_WRITE_SEQUENCER_134] = 0xf,
302 [WM8915_WRITE_SEQUENCER_135] = 0x6,
303 [WM8915_WRITE_SEQUENCER_136] = 0x1,
304 [WM8915_WRITE_SEQUENCER_137] = 0x3,
305 [WM8915_WRITE_SEQUENCER_138] = 0x106,
306 [WM8915_WRITE_SEQUENCER_140] = 0x61,
307 [WM8915_WRITE_SEQUENCER_141] = 0x11,
308 [WM8915_WRITE_SEQUENCER_142] = 0x401,
309 [WM8915_WRITE_SEQUENCER_144] = 0x50,
310 [WM8915_WRITE_SEQUENCER_145] = 0x3,
311 [WM8915_WRITE_SEQUENCER_146] = 0x102,
312 [WM8915_WRITE_SEQUENCER_148] = 0x51,
313 [WM8915_WRITE_SEQUENCER_149] = 0x3,
314 [WM8915_WRITE_SEQUENCER_150] = 0x106,
315 [WM8915_WRITE_SEQUENCER_151] = 0xa,
316 [WM8915_WRITE_SEQUENCER_152] = 0x61,
317 [WM8915_WRITE_SEQUENCER_153] = 0x3b,
318 [WM8915_WRITE_SEQUENCER_154] = 0x502,
319 [WM8915_WRITE_SEQUENCER_155] = 0x100,
320 [WM8915_WRITE_SEQUENCER_156] = 0x2fff,
321 [WM8915_WRITE_SEQUENCER_160] = 0x2fff,
322 [WM8915_WRITE_SEQUENCER_164] = 0x2fff,
323 [WM8915_WRITE_SEQUENCER_168] = 0x2fff,
324 [WM8915_WRITE_SEQUENCER_172] = 0x2fff,
325 [WM8915_WRITE_SEQUENCER_176] = 0x2fff,
326 [WM8915_WRITE_SEQUENCER_180] = 0x2fff,
327 [WM8915_WRITE_SEQUENCER_184] = 0x2fff,
328 [WM8915_WRITE_SEQUENCER_188] = 0x2fff,
329 [WM8915_WRITE_SEQUENCER_192] = 0x1,
330 [WM8915_WRITE_SEQUENCER_193] = 0x1,
331 [WM8915_WRITE_SEQUENCER_195] = 0x6,
332 [WM8915_WRITE_SEQUENCER_196] = 0x40,
333 [WM8915_WRITE_SEQUENCER_197] = 0x1,
334 [WM8915_WRITE_SEQUENCER_198] = 0xf,
335 [WM8915_WRITE_SEQUENCER_199] = 0x6,
336 [WM8915_WRITE_SEQUENCER_200] = 0x1,
337 [WM8915_WRITE_SEQUENCER_201] = 0x3,
338 [WM8915_WRITE_SEQUENCER_202] = 0x106,
339 [WM8915_WRITE_SEQUENCER_204] = 0x61,
340 [WM8915_WRITE_SEQUENCER_205] = 0x11,
341 [WM8915_WRITE_SEQUENCER_206] = 0x401,
342 [WM8915_WRITE_SEQUENCER_208] = 0x50,
343 [WM8915_WRITE_SEQUENCER_209] = 0x3,
344 [WM8915_WRITE_SEQUENCER_210] = 0x102,
345 [WM8915_WRITE_SEQUENCER_212] = 0x61,
346 [WM8915_WRITE_SEQUENCER_213] = 0x3b,
347 [WM8915_WRITE_SEQUENCER_214] = 0x502,
348 [WM8915_WRITE_SEQUENCER_215] = 0x100,
349 [WM8915_WRITE_SEQUENCER_216] = 0x2fff,
350 [WM8915_WRITE_SEQUENCER_220] = 0x2fff,
351 [WM8915_WRITE_SEQUENCER_224] = 0x2fff,
352 [WM8915_WRITE_SEQUENCER_228] = 0x2fff,
353 [WM8915_WRITE_SEQUENCER_232] = 0x2fff,
354 [WM8915_WRITE_SEQUENCER_236] = 0x2fff,
355 [WM8915_WRITE_SEQUENCER_240] = 0x2fff,
356 [WM8915_WRITE_SEQUENCER_244] = 0x2fff,
357 [WM8915_WRITE_SEQUENCER_248] = 0x2fff,
358 [WM8915_WRITE_SEQUENCER_252] = 0x2fff,
359 [WM8915_WRITE_SEQUENCER_256] = 0x60,
360 [WM8915_WRITE_SEQUENCER_258] = 0x601,
361 [WM8915_WRITE_SEQUENCER_260] = 0x50,
362 [WM8915_WRITE_SEQUENCER_262] = 0x100,
363 [WM8915_WRITE_SEQUENCER_264] = 0x1,
364 [WM8915_WRITE_SEQUENCER_266] = 0x104,
365 [WM8915_WRITE_SEQUENCER_267] = 0x100,
366 [WM8915_WRITE_SEQUENCER_268] = 0x2fff,
367 [WM8915_WRITE_SEQUENCER_272] = 0x2fff,
368 [WM8915_WRITE_SEQUENCER_276] = 0x2fff,
369 [WM8915_WRITE_SEQUENCER_280] = 0x2fff,
370 [WM8915_WRITE_SEQUENCER_284] = 0x2fff,
371 [WM8915_WRITE_SEQUENCER_288] = 0x2fff,
372 [WM8915_WRITE_SEQUENCER_292] = 0x2fff,
373 [WM8915_WRITE_SEQUENCER_296] = 0x2fff,
374 [WM8915_WRITE_SEQUENCER_300] = 0x2fff,
375 [WM8915_WRITE_SEQUENCER_304] = 0x2fff,
376 [WM8915_WRITE_SEQUENCER_308] = 0x2fff,
377 [WM8915_WRITE_SEQUENCER_312] = 0x2fff,
378 [WM8915_WRITE_SEQUENCER_316] = 0x2fff,
379 [WM8915_WRITE_SEQUENCER_320] = 0x61,
380 [WM8915_WRITE_SEQUENCER_322] = 0x601,
381 [WM8915_WRITE_SEQUENCER_324] = 0x50,
382 [WM8915_WRITE_SEQUENCER_326] = 0x102,
383 [WM8915_WRITE_SEQUENCER_328] = 0x1,
384 [WM8915_WRITE_SEQUENCER_330] = 0x106,
385 [WM8915_WRITE_SEQUENCER_331] = 0x100,
386 [WM8915_WRITE_SEQUENCER_332] = 0x2fff,
387 [WM8915_WRITE_SEQUENCER_336] = 0x2fff,
388 [WM8915_WRITE_SEQUENCER_340] = 0x2fff,
389 [WM8915_WRITE_SEQUENCER_344] = 0x2fff,
390 [WM8915_WRITE_SEQUENCER_348] = 0x2fff,
391 [WM8915_WRITE_SEQUENCER_352] = 0x2fff,
392 [WM8915_WRITE_SEQUENCER_356] = 0x2fff,
393 [WM8915_WRITE_SEQUENCER_360] = 0x2fff,
394 [WM8915_WRITE_SEQUENCER_364] = 0x2fff,
395 [WM8915_WRITE_SEQUENCER_368] = 0x2fff,
396 [WM8915_WRITE_SEQUENCER_372] = 0x2fff,
397 [WM8915_WRITE_SEQUENCER_376] = 0x2fff,
398 [WM8915_WRITE_SEQUENCER_380] = 0x2fff,
399 [WM8915_WRITE_SEQUENCER_384] = 0x60,
400 [WM8915_WRITE_SEQUENCER_386] = 0x601,
401 [WM8915_WRITE_SEQUENCER_388] = 0x61,
402 [WM8915_WRITE_SEQUENCER_390] = 0x601,
403 [WM8915_WRITE_SEQUENCER_392] = 0x50,
404 [WM8915_WRITE_SEQUENCER_394] = 0x300,
405 [WM8915_WRITE_SEQUENCER_396] = 0x1,
406 [WM8915_WRITE_SEQUENCER_398] = 0x304,
407 [WM8915_WRITE_SEQUENCER_400] = 0x40,
408 [WM8915_WRITE_SEQUENCER_402] = 0xf,
409 [WM8915_WRITE_SEQUENCER_404] = 0x1,
410 [WM8915_WRITE_SEQUENCER_407] = 0x100,
411};
412
413static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
414static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
415static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
416static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
417static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
418static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
419static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
420
421static const char *sidetone_hpf_text[] = {
422 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
423};
424
425static const struct soc_enum sidetone_hpf =
426 SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text);
427
428static const char *hpf_mode_text[] = {
429 "HiFi", "Custom", "Voice"
430};
431
432static const struct soc_enum dsp1tx_hpf_mode =
433 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
434
435static const struct soc_enum dsp2tx_hpf_mode =
436 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
437
438static const char *hpf_cutoff_text[] = {
439 "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
440};
441
442static const struct soc_enum dsp1tx_hpf_cutoff =
443 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
444
445static const struct soc_enum dsp2tx_hpf_cutoff =
446 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
447
448static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block)
449{
450 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
451 struct wm8915_pdata *pdata = &wm8915->pdata;
452 int base, best, best_val, save, i, cfg, iface;
453
454 if (!wm8915->num_retune_mobile_texts)
455 return;
456
457 switch (block) {
458 case 0:
459 base = WM8915_DSP1_RX_EQ_GAINS_1;
460 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
461 WM8915_DSP1RX_SRC)
462 iface = 1;
463 else
464 iface = 0;
465 break;
466 case 1:
467 base = WM8915_DSP1_RX_EQ_GAINS_2;
468 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
469 WM8915_DSP2RX_SRC)
470 iface = 1;
471 else
472 iface = 0;
473 break;
474 default:
475 return;
476 }
477
478 /* Find the version of the currently selected configuration
479 * with the nearest sample rate. */
480 cfg = wm8915->retune_mobile_cfg[block];
481 best = 0;
482 best_val = INT_MAX;
483 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
484 if (strcmp(pdata->retune_mobile_cfgs[i].name,
485 wm8915->retune_mobile_texts[cfg]) == 0 &&
486 abs(pdata->retune_mobile_cfgs[i].rate
487 - wm8915->rx_rate[iface]) < best_val) {
488 best = i;
489 best_val = abs(pdata->retune_mobile_cfgs[i].rate
490 - wm8915->rx_rate[iface]);
491 }
492 }
493
494 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
495 block,
496 pdata->retune_mobile_cfgs[best].name,
497 pdata->retune_mobile_cfgs[best].rate,
498 wm8915->rx_rate[iface]);
499
500 /* The EQ will be disabled while reconfiguring it, remember the
501 * current configuration.
502 */
503 save = snd_soc_read(codec, base);
504 save &= WM8915_DSP1RX_EQ_ENA;
505
506 for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
507 snd_soc_update_bits(codec, base + i, 0xffff,
508 pdata->retune_mobile_cfgs[best].regs[i]);
509
510 snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save);
511}
512
513/* Icky as hell but saves code duplication */
514static int wm8915_get_retune_mobile_block(const char *name)
515{
516 if (strcmp(name, "DSP1 EQ Mode") == 0)
517 return 0;
518 if (strcmp(name, "DSP2 EQ Mode") == 0)
519 return 1;
520 return -EINVAL;
521}
522
523static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
528 struct wm8915_pdata *pdata = &wm8915->pdata;
529 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
530 int value = ucontrol->value.integer.value[0];
531
532 if (block < 0)
533 return block;
534
535 if (value >= pdata->num_retune_mobile_cfgs)
536 return -EINVAL;
537
538 wm8915->retune_mobile_cfg[block] = value;
539
540 wm8915_set_retune_mobile(codec, block);
541
542 return 0;
543}
544
545static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
546 struct snd_ctl_elem_value *ucontrol)
547{
548 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
549 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
550 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
551
552 ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block];
553
554 return 0;
555}
556
557static const struct snd_kcontrol_new wm8915_snd_controls[] = {
558SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME,
559 WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
560SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME,
561 WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
562
563SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES,
564 0, 5, 24, 0, sidetone_tlv),
565SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES,
566 0, 5, 24, 0, sidetone_tlv),
567SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0),
568SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
569SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0),
570
571SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME,
572 WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
573SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME,
574 WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
575
576SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS,
577 13, 1, 0),
578SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0),
579SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
580SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
581
582SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS,
583 13, 1, 0),
584SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0),
585SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
586SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
587
588SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME,
589 WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
590SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1),
591
592SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME,
593 WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
594SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1),
595
596SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME,
597 WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
598SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME,
599 WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1),
600
601SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME,
602 WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
603SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME,
604 WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1),
605
606SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0),
607SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0),
608SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0),
609SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0),
610
611SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0),
612SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0),
613
614SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4,
615 8, 0, out_digital_tlv),
616SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4,
617 8, 0, out_digital_tlv),
618
619SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME,
620 WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
621SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME,
622 WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
623
624SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME,
625 WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
626SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME,
627 WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
628
629SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
630 spk_tlv),
631SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER,
632 WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1),
633SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER,
634 WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0),
635
636SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
637SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
638};
639
640static const struct snd_kcontrol_new wm8915_eq_controls[] = {
641SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
642 eq_tlv),
643SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
644 eq_tlv),
645SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
646 eq_tlv),
647SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
648 eq_tlv),
649SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
650 eq_tlv),
651
652SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
653 eq_tlv),
654SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
655 eq_tlv),
656SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
657 eq_tlv),
658SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
659 eq_tlv),
660SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
661 eq_tlv),
662};
663
664static int cp_event(struct snd_soc_dapm_widget *w,
665 struct snd_kcontrol *kcontrol, int event)
666{
667 switch (event) {
668 case SND_SOC_DAPM_POST_PMU:
669 msleep(5);
670 break;
671 default:
672 BUG();
673 return -EINVAL;
674 }
675
676 return 0;
677}
678
679static int rmv_short_event(struct snd_soc_dapm_widget *w,
680 struct snd_kcontrol *kcontrol, int event)
681{
682 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
683
684 /* Record which outputs we enabled */
685 switch (event) {
686 case SND_SOC_DAPM_PRE_PMD:
687 wm8915->hpout_pending &= ~w->shift;
688 break;
689 case SND_SOC_DAPM_PRE_PMU:
690 wm8915->hpout_pending |= w->shift;
691 break;
692 default:
693 BUG();
694 return -EINVAL;
695 }
696
697 return 0;
698}
699
700static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
701{
702 struct i2c_client *i2c = to_i2c_client(codec->dev);
703 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
704 int i, ret;
705 unsigned long timeout = 200;
706
707 snd_soc_write(codec, WM8915_DC_SERVO_2, mask);
708
709 /* Use the interrupt if possible */
710 do {
711 if (i2c->irq) {
712 timeout = wait_for_completion_timeout(&wm8915->dcs_done,
713 msecs_to_jiffies(200));
714 if (timeout == 0)
715 dev_err(codec->dev, "DC servo timed out\n");
716
717 } else {
718 msleep(1);
719 if (--i) {
720 timeout = 0;
721 break;
722 }
723 }
724
725 ret = snd_soc_read(codec, WM8915_DC_SERVO_2);
726 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
727 } while (ret & mask);
728
729 if (timeout == 0)
730 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
731 else
732 dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
733}
734
735static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm,
736 enum snd_soc_dapm_type event, int subseq)
737{
738 struct snd_soc_codec *codec = container_of(dapm,
739 struct snd_soc_codec, dapm);
740 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
741 u16 val, mask;
742
743 /* Complete any pending DC servo starts */
744 if (wm8915->dcs_pending) {
745 dev_dbg(codec->dev, "Starting DC servo for %x\n",
746 wm8915->dcs_pending);
747
748 /* Trigger a startup sequence */
749 wait_for_dc_servo(codec, wm8915->dcs_pending
750 << WM8915_DCS_TRIG_STARTUP_0_SHIFT);
751
752 wm8915->dcs_pending = 0;
753 }
754
755 if (wm8915->hpout_pending != wm8915->hpout_ena) {
756 dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
757 wm8915->hpout_ena, wm8915->hpout_pending);
758
759 val = 0;
760 mask = 0;
761 if (wm8915->hpout_pending & HPOUT1L) {
762 val |= WM8915_HPOUT1L_RMV_SHORT;
763 mask |= WM8915_HPOUT1L_RMV_SHORT;
764 } else {
765 mask |= WM8915_HPOUT1L_RMV_SHORT |
766 WM8915_HPOUT1L_OUTP |
767 WM8915_HPOUT1L_DLY;
768 }
769
770 if (wm8915->hpout_pending & HPOUT1R) {
771 val |= WM8915_HPOUT1R_RMV_SHORT;
772 mask |= WM8915_HPOUT1R_RMV_SHORT;
773 } else {
774 mask |= WM8915_HPOUT1R_RMV_SHORT |
775 WM8915_HPOUT1R_OUTP |
776 WM8915_HPOUT1R_DLY;
777 }
778
779 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val);
780
781 val = 0;
782 mask = 0;
783 if (wm8915->hpout_pending & HPOUT2L) {
784 val |= WM8915_HPOUT2L_RMV_SHORT;
785 mask |= WM8915_HPOUT2L_RMV_SHORT;
786 } else {
787 mask |= WM8915_HPOUT2L_RMV_SHORT |
788 WM8915_HPOUT2L_OUTP |
789 WM8915_HPOUT2L_DLY;
790 }
791
792 if (wm8915->hpout_pending & HPOUT2R) {
793 val |= WM8915_HPOUT2R_RMV_SHORT;
794 mask |= WM8915_HPOUT2R_RMV_SHORT;
795 } else {
796 mask |= WM8915_HPOUT2R_RMV_SHORT |
797 WM8915_HPOUT2R_OUTP |
798 WM8915_HPOUT2R_DLY;
799 }
800
801 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val);
802
803 wm8915->hpout_ena = wm8915->hpout_pending;
804 }
805}
806
807static int dcs_start(struct snd_soc_dapm_widget *w,
808 struct snd_kcontrol *kcontrol, int event)
809{
810 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
811
812 switch (event) {
813 case SND_SOC_DAPM_POST_PMU:
814 wm8915->dcs_pending |= 1 << w->shift;
815 break;
816 default:
817 BUG();
818 return -EINVAL;
819 }
820
821 return 0;
822}
823
824static const char *sidetone_text[] = {
825 "IN1", "IN2",
826};
827
828static const struct soc_enum left_sidetone_enum =
829 SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text);
830
831static const struct snd_kcontrol_new left_sidetone =
832 SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
833
834static const struct soc_enum right_sidetone_enum =
835 SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text);
836
837static const struct snd_kcontrol_new right_sidetone =
838 SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
839
840static const char *spk_text[] = {
841 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
842};
843
844static const struct soc_enum spkl_enum =
845 SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text);
846
847static const struct snd_kcontrol_new spkl_mux =
848 SOC_DAPM_ENUM("SPKL", spkl_enum);
849
850static const struct soc_enum spkr_enum =
851 SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
852
853static const struct snd_kcontrol_new spkr_mux =
854 SOC_DAPM_ENUM("SPKR", spkr_enum);
855
856static const char *dsp1rx_text[] = {
857 "AIF1", "AIF2"
858};
859
860static const struct soc_enum dsp1rx_enum =
861 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
862
863static const struct snd_kcontrol_new dsp1rx =
864 SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
865
866static const char *dsp2rx_text[] = {
867 "AIF2", "AIF1"
868};
869
870static const struct soc_enum dsp2rx_enum =
871 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
872
873static const struct snd_kcontrol_new dsp2rx =
874 SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
875
876static const char *aif2tx_text[] = {
877 "DSP2", "DSP1", "AIF1"
878};
879
880static const struct soc_enum aif2tx_enum =
881 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
882
883static const struct snd_kcontrol_new aif2tx =
884 SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
885
886static const char *inmux_text[] = {
887 "ADC", "DMIC1", "DMIC2"
888};
889
890static const struct soc_enum in1_enum =
891 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text);
892
893static const struct snd_kcontrol_new in1_mux =
894 SOC_DAPM_ENUM("IN1 Mux", in1_enum);
895
896static const struct soc_enum in2_enum =
897 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text);
898
899static const struct snd_kcontrol_new in2_mux =
900 SOC_DAPM_ENUM("IN2 Mux", in2_enum);
901
902static const struct snd_kcontrol_new dac2r_mix[] = {
903SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
904 5, 1, 0),
905SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
906 4, 1, 0),
907SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
908SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
909};
910
911static const struct snd_kcontrol_new dac2l_mix[] = {
912SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
913 5, 1, 0),
914SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
915 4, 1, 0),
916SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
917SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
918};
919
920static const struct snd_kcontrol_new dac1r_mix[] = {
921SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
922 5, 1, 0),
923SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
924 4, 1, 0),
925SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
926SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
927};
928
929static const struct snd_kcontrol_new dac1l_mix[] = {
930SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
931 5, 1, 0),
932SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
933 4, 1, 0),
934SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
935SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
936};
937
938static const struct snd_kcontrol_new dsp1txl[] = {
939SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
940 1, 1, 0),
941SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
942 0, 1, 0),
943};
944
945static const struct snd_kcontrol_new dsp1txr[] = {
946SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
947 1, 1, 0),
948SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
949 0, 1, 0),
950};
951
952static const struct snd_kcontrol_new dsp2txl[] = {
953SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
954 1, 1, 0),
955SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
956 0, 1, 0),
957};
958
959static const struct snd_kcontrol_new dsp2txr[] = {
960SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
961 1, 1, 0),
962SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
963 0, 1, 0),
964};
965
966
967static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = {
968SND_SOC_DAPM_INPUT("IN1LN"),
969SND_SOC_DAPM_INPUT("IN1LP"),
970SND_SOC_DAPM_INPUT("IN1RN"),
971SND_SOC_DAPM_INPUT("IN1RP"),
972
973SND_SOC_DAPM_INPUT("IN2LN"),
974SND_SOC_DAPM_INPUT("IN2LP"),
975SND_SOC_DAPM_INPUT("IN2RN"),
976SND_SOC_DAPM_INPUT("IN2RP"),
977
978SND_SOC_DAPM_INPUT("DMIC1DAT"),
979SND_SOC_DAPM_INPUT("DMIC2DAT"),
980
981SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0),
982SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0),
983SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0),
984SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event,
985 SND_SOC_DAPM_POST_PMU),
986
987SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
988SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0),
989SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0),
990
991SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
992SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
993
994SND_SOC_DAPM_PGA("ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
995
996SND_SOC_DAPM_MUX("IN1 Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
997SND_SOC_DAPM_MUX("IN2 Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
998
999SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
1000SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
1001SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
1002SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
1003
1004/* FIXME - these need to be concentrator widgets */
1005SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
1006SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
1007
1008SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0),
1009SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0),
1010SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0),
1011SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0),
1012
1013SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0),
1014SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0),
1015
1016SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
1017SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
1018
1019SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0),
1020SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0),
1021SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0),
1022SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0),
1023
1024SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0,
1025 dsp2txl, ARRAY_SIZE(dsp2txl)),
1026SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0,
1027 dsp2txr, ARRAY_SIZE(dsp2txr)),
1028SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0,
1029 dsp1txl, ARRAY_SIZE(dsp1txl)),
1030SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0,
1031 dsp1txr, ARRAY_SIZE(dsp1txr)),
1032
1033SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
1034 dac2l_mix, ARRAY_SIZE(dac2l_mix)),
1035SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
1036 dac2r_mix, ARRAY_SIZE(dac2r_mix)),
1037SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
1038 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
1039SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
1040 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
1041
1042SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0),
1043SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0),
1044SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0),
1045SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0),
1046
1047SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1,
1048 WM8915_POWER_MANAGEMENT_4, 9, 0),
1049SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2,
1050 WM8915_POWER_MANAGEMENT_4, 8, 0),
1051
1052SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1,
1053 WM8915_POWER_MANAGEMENT_6, 9, 0),
1054SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2,
1055 WM8915_POWER_MANAGEMENT_6, 8, 0),
1056
1057SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
1058 WM8915_POWER_MANAGEMENT_4, 5, 0),
1059SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4,
1060 WM8915_POWER_MANAGEMENT_4, 4, 0),
1061SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3,
1062 WM8915_POWER_MANAGEMENT_4, 3, 0),
1063SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2,
1064 WM8915_POWER_MANAGEMENT_4, 2, 0),
1065SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1,
1066 WM8915_POWER_MANAGEMENT_4, 1, 0),
1067SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
1068 WM8915_POWER_MANAGEMENT_4, 0, 0),
1069
1070SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
1071 WM8915_POWER_MANAGEMENT_6, 5, 0),
1072SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
1073 WM8915_POWER_MANAGEMENT_6, 4, 0),
1074SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
1075 WM8915_POWER_MANAGEMENT_6, 3, 0),
1076SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
1077 WM8915_POWER_MANAGEMENT_6, 2, 0),
1078SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
1079 WM8915_POWER_MANAGEMENT_6, 1, 0),
1080SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
1081 WM8915_POWER_MANAGEMENT_6, 0, 0),
1082
1083/* We route as stereo pairs so define some dummy widgets to squash
1084 * things down for now. RXA = 0,1, RXB = 2,3 and so on */
1085SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
1086SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
1087SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
1088SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
1089SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
1090
1091SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
1092SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
1093SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
1094
1095SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
1096SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
1097SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
1098SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
1099
1100SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
1101SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0),
1102SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start,
1103 SND_SOC_DAPM_POST_PMU),
1104SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0),
1105SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
1106 rmv_short_event,
1107 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1108
1109SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
1110SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0),
1111SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start,
1112 SND_SOC_DAPM_POST_PMU),
1113SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0),
1114SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
1115 rmv_short_event,
1116 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1117
1118SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
1119SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0),
1120SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start,
1121 SND_SOC_DAPM_POST_PMU),
1122SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0),
1123SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
1124 rmv_short_event,
1125 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1126
1127SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
1128SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0),
1129SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start,
1130 SND_SOC_DAPM_POST_PMU),
1131SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0),
1132SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
1133 rmv_short_event,
1134 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1135
1136SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1137SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1138SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1139SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1140SND_SOC_DAPM_OUTPUT("SPKDAT"),
1141};
1142
1143static const struct snd_soc_dapm_route wm8915_dapm_routes[] = {
1144 { "AIFCLK", NULL, "SYSCLK" },
1145 { "SYSDSPCLK", NULL, "SYSCLK" },
1146 { "Charge Pump", NULL, "SYSCLK" },
1147
1148 { "MICB1", NULL, "LDO2" },
1149 { "MICB2", NULL, "LDO2" },
1150
1151 { "IN1L PGA", NULL, "IN2LN" },
1152 { "IN1L PGA", NULL, "IN2LP" },
1153 { "IN1L PGA", NULL, "IN1LN" },
1154 { "IN1L PGA", NULL, "IN1LP" },
1155
1156 { "IN1R PGA", NULL, "IN2RN" },
1157 { "IN1R PGA", NULL, "IN2RP" },
1158 { "IN1R PGA", NULL, "IN1RN" },
1159 { "IN1R PGA", NULL, "IN1RP" },
1160
1161 { "ADCL", NULL, "IN1L PGA" },
1162
1163 { "ADCR", NULL, "IN1R PGA" },
1164
1165 { "DMIC1L", NULL, "DMIC1DAT" },
1166 { "DMIC1R", NULL, "DMIC1DAT" },
1167 { "DMIC2L", NULL, "DMIC2DAT" },
1168 { "DMIC2R", NULL, "DMIC2DAT" },
1169
1170 { "DMIC2L", NULL, "DMIC2" },
1171 { "DMIC2R", NULL, "DMIC2" },
1172 { "DMIC1L", NULL, "DMIC1" },
1173 { "DMIC1R", NULL, "DMIC1" },
1174
1175 { "ADC", NULL, "ADCL" },
1176 { "ADC", NULL, "ADCR" },
1177
1178 { "IN1 Mux", "ADC", "ADC" },
1179 { "IN1 Mux", "DMIC1", "DMIC1" },
1180 { "IN1 Mux", "DMIC2", "DMIC2" },
1181
1182 { "IN2 Mux", "ADC", "ADC" },
1183 { "IN2 Mux", "DMIC1", "DMIC1" },
1184 { "IN2 Mux", "DMIC2", "DMIC2" },
1185
1186 { "Left Sidetone", "IN1", "IN1 Mux" },
1187 { "Left Sidetone", "IN2", "IN2 Mux" },
1188
1189 { "Right Sidetone", "IN1", "IN1 Mux" },
1190 { "Right Sidetone", "IN2", "IN2 Mux" },
1191
1192 { "DSP1TXL", "IN1 Switch", "IN1 Mux" },
1193 { "DSP1TXR", "IN1 Switch", "IN1 Mux" },
1194
1195 { "DSP2TXL", "IN1 Switch", "IN2 Mux" },
1196 { "DSP2TXR", "IN1 Switch", "IN2 Mux" },
1197
1198 { "AIF1TX0", NULL, "DSP1TXL" },
1199 { "AIF1TX1", NULL, "DSP1TXR" },
1200 { "AIF1TX2", NULL, "DSP2TXL" },
1201 { "AIF1TX3", NULL, "DSP2TXR" },
1202 { "AIF1TX4", NULL, "AIF2RX0" },
1203 { "AIF1TX5", NULL, "AIF2RX1" },
1204
1205 { "AIF1RX0", NULL, "AIFCLK" },
1206 { "AIF1RX1", NULL, "AIFCLK" },
1207 { "AIF1RX2", NULL, "AIFCLK" },
1208 { "AIF1RX3", NULL, "AIFCLK" },
1209 { "AIF1RX4", NULL, "AIFCLK" },
1210 { "AIF1RX5", NULL, "AIFCLK" },
1211
1212 { "AIF2RX0", NULL, "AIFCLK" },
1213 { "AIF2RX1", NULL, "AIFCLK" },
1214
1215 { "DSP1RXL", NULL, "SYSDSPCLK" },
1216 { "DSP1RXR", NULL, "SYSDSPCLK" },
1217 { "DSP2RXL", NULL, "SYSDSPCLK" },
1218 { "DSP2RXR", NULL, "SYSDSPCLK" },
1219 { "DSP1TXL", NULL, "SYSDSPCLK" },
1220 { "DSP1TXR", NULL, "SYSDSPCLK" },
1221 { "DSP2TXL", NULL, "SYSDSPCLK" },
1222 { "DSP2TXR", NULL, "SYSDSPCLK" },
1223
1224 { "AIF1RXA", NULL, "AIF1RX0" },
1225 { "AIF1RXA", NULL, "AIF1RX1" },
1226 { "AIF1RXB", NULL, "AIF1RX2" },
1227 { "AIF1RXB", NULL, "AIF1RX3" },
1228 { "AIF1RXC", NULL, "AIF1RX4" },
1229 { "AIF1RXC", NULL, "AIF1RX5" },
1230
1231 { "AIF2RX", NULL, "AIF2RX0" },
1232 { "AIF2RX", NULL, "AIF2RX1" },
1233
1234 { "AIF2TX", "DSP2", "DSP2TX" },
1235 { "AIF2TX", "DSP1", "DSP1RX" },
1236 { "AIF2TX", "AIF1", "AIF1RXC" },
1237
1238 { "DSP1RXL", NULL, "DSP1RX" },
1239 { "DSP1RXR", NULL, "DSP1RX" },
1240 { "DSP2RXL", NULL, "DSP2RX" },
1241 { "DSP2RXR", NULL, "DSP2RX" },
1242
1243 { "DSP2TX", NULL, "DSP2TXL" },
1244 { "DSP2TX", NULL, "DSP2TXR" },
1245
1246 { "DSP1RX", "AIF1", "AIF1RXA" },
1247 { "DSP1RX", "AIF2", "AIF2RX" },
1248
1249 { "DSP2RX", "AIF1", "AIF1RXB" },
1250 { "DSP2RX", "AIF2", "AIF2RX" },
1251
1252 { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
1253 { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
1254 { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1255 { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1256
1257 { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
1258 { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
1259 { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1260 { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1261
1262 { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
1263 { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
1264 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1265 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1266
1267 { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
1268 { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
1269 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1270 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1271
1272 { "DAC1L", NULL, "DAC1L Mixer" },
1273 { "DAC1R", NULL, "DAC1R Mixer" },
1274 { "DAC2L", NULL, "DAC2L Mixer" },
1275 { "DAC2R", NULL, "DAC2R Mixer" },
1276
1277 { "HPOUT2L PGA", NULL, "Charge Pump" },
1278 { "HPOUT2L PGA", NULL, "DAC2L" },
1279 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1280 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
1281 { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" },
1282 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1283
1284 { "HPOUT2R PGA", NULL, "Charge Pump" },
1285 { "HPOUT2R PGA", NULL, "DAC2R" },
1286 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1287 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
1288 { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" },
1289 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1290
1291 { "HPOUT1L PGA", NULL, "Charge Pump" },
1292 { "HPOUT1L PGA", NULL, "DAC1L" },
1293 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1294 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
1295 { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" },
1296 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1297
1298 { "HPOUT1R PGA", NULL, "Charge Pump" },
1299 { "HPOUT1R PGA", NULL, "DAC1R" },
1300 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1301 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
1302 { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" },
1303 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
1304
1305 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
1306 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
1307 { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
1308 { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
1309
1310 { "SPKL", "DAC1L", "DAC1L" },
1311 { "SPKL", "DAC1R", "DAC1R" },
1312 { "SPKL", "DAC2L", "DAC2L" },
1313 { "SPKL", "DAC2R", "DAC2R" },
1314
1315 { "SPKR", "DAC1L", "DAC1L" },
1316 { "SPKR", "DAC1R", "DAC1R" },
1317 { "SPKR", "DAC2L", "DAC2L" },
1318 { "SPKR", "DAC2R", "DAC2R" },
1319
1320 { "SPKL PGA", NULL, "SPKL" },
1321 { "SPKR PGA", NULL, "SPKR" },
1322
1323 { "SPKDAT", NULL, "SPKL PGA" },
1324 { "SPKDAT", NULL, "SPKR PGA" },
1325};
1326
1327static int wm8915_readable_register(struct snd_soc_codec *codec,
1328 unsigned int reg)
1329{
1330 /* Due to the sparseness of the register map the compiler
1331 * output from an explicit switch statement ends up being much
1332 * more efficient than a table.
1333 */
1334 switch (reg) {
1335 case WM8915_SOFTWARE_RESET:
1336 case WM8915_POWER_MANAGEMENT_1:
1337 case WM8915_POWER_MANAGEMENT_2:
1338 case WM8915_POWER_MANAGEMENT_3:
1339 case WM8915_POWER_MANAGEMENT_4:
1340 case WM8915_POWER_MANAGEMENT_5:
1341 case WM8915_POWER_MANAGEMENT_6:
1342 case WM8915_POWER_MANAGEMENT_7:
1343 case WM8915_POWER_MANAGEMENT_8:
1344 case WM8915_LEFT_LINE_INPUT_VOLUME:
1345 case WM8915_RIGHT_LINE_INPUT_VOLUME:
1346 case WM8915_LINE_INPUT_CONTROL:
1347 case WM8915_DAC1_HPOUT1_VOLUME:
1348 case WM8915_DAC2_HPOUT2_VOLUME:
1349 case WM8915_DAC1_LEFT_VOLUME:
1350 case WM8915_DAC1_RIGHT_VOLUME:
1351 case WM8915_DAC2_LEFT_VOLUME:
1352 case WM8915_DAC2_RIGHT_VOLUME:
1353 case WM8915_OUTPUT1_LEFT_VOLUME:
1354 case WM8915_OUTPUT1_RIGHT_VOLUME:
1355 case WM8915_OUTPUT2_LEFT_VOLUME:
1356 case WM8915_OUTPUT2_RIGHT_VOLUME:
1357 case WM8915_MICBIAS_1:
1358 case WM8915_MICBIAS_2:
1359 case WM8915_LDO_1:
1360 case WM8915_LDO_2:
1361 case WM8915_ACCESSORY_DETECT_MODE_1:
1362 case WM8915_ACCESSORY_DETECT_MODE_2:
1363 case WM8915_HEADPHONE_DETECT_1:
1364 case WM8915_HEADPHONE_DETECT_2:
1365 case WM8915_MIC_DETECT_1:
1366 case WM8915_MIC_DETECT_2:
1367 case WM8915_MIC_DETECT_3:
1368 case WM8915_CHARGE_PUMP_1:
1369 case WM8915_CHARGE_PUMP_2:
1370 case WM8915_DC_SERVO_1:
1371 case WM8915_DC_SERVO_2:
1372 case WM8915_DC_SERVO_3:
1373 case WM8915_DC_SERVO_5:
1374 case WM8915_DC_SERVO_6:
1375 case WM8915_DC_SERVO_7:
1376 case WM8915_DC_SERVO_READBACK_0:
1377 case WM8915_ANALOGUE_HP_1:
1378 case WM8915_ANALOGUE_HP_2:
1379 case WM8915_CHIP_REVISION:
1380 case WM8915_CONTROL_INTERFACE_1:
1381 case WM8915_WRITE_SEQUENCER_CTRL_1:
1382 case WM8915_WRITE_SEQUENCER_CTRL_2:
1383 case WM8915_AIF_CLOCKING_1:
1384 case WM8915_AIF_CLOCKING_2:
1385 case WM8915_CLOCKING_1:
1386 case WM8915_CLOCKING_2:
1387 case WM8915_AIF_RATE:
1388 case WM8915_FLL_CONTROL_1:
1389 case WM8915_FLL_CONTROL_2:
1390 case WM8915_FLL_CONTROL_3:
1391 case WM8915_FLL_CONTROL_4:
1392 case WM8915_FLL_CONTROL_5:
1393 case WM8915_FLL_CONTROL_6:
1394 case WM8915_FLL_EFS_1:
1395 case WM8915_FLL_EFS_2:
1396 case WM8915_AIF1_CONTROL:
1397 case WM8915_AIF1_BCLK:
1398 case WM8915_AIF1_TX_LRCLK_1:
1399 case WM8915_AIF1_TX_LRCLK_2:
1400 case WM8915_AIF1_RX_LRCLK_1:
1401 case WM8915_AIF1_RX_LRCLK_2:
1402 case WM8915_AIF1TX_DATA_CONFIGURATION_1:
1403 case WM8915_AIF1TX_DATA_CONFIGURATION_2:
1404 case WM8915_AIF1RX_DATA_CONFIGURATION:
1405 case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION:
1406 case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION:
1407 case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION:
1408 case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION:
1409 case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION:
1410 case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION:
1411 case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION:
1412 case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION:
1413 case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION:
1414 case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION:
1415 case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION:
1416 case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION:
1417 case WM8915_AIF1RX_MONO_CONFIGURATION:
1418 case WM8915_AIF1TX_TEST:
1419 case WM8915_AIF2_CONTROL:
1420 case WM8915_AIF2_BCLK:
1421 case WM8915_AIF2_TX_LRCLK_1:
1422 case WM8915_AIF2_TX_LRCLK_2:
1423 case WM8915_AIF2_RX_LRCLK_1:
1424 case WM8915_AIF2_RX_LRCLK_2:
1425 case WM8915_AIF2TX_DATA_CONFIGURATION_1:
1426 case WM8915_AIF2TX_DATA_CONFIGURATION_2:
1427 case WM8915_AIF2RX_DATA_CONFIGURATION:
1428 case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION:
1429 case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION:
1430 case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION:
1431 case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION:
1432 case WM8915_AIF2RX_MONO_CONFIGURATION:
1433 case WM8915_AIF2TX_TEST:
1434 case WM8915_DSP1_TX_LEFT_VOLUME:
1435 case WM8915_DSP1_TX_RIGHT_VOLUME:
1436 case WM8915_DSP1_RX_LEFT_VOLUME:
1437 case WM8915_DSP1_RX_RIGHT_VOLUME:
1438 case WM8915_DSP1_TX_FILTERS:
1439 case WM8915_DSP1_RX_FILTERS_1:
1440 case WM8915_DSP1_RX_FILTERS_2:
1441 case WM8915_DSP1_DRC_1:
1442 case WM8915_DSP1_DRC_2:
1443 case WM8915_DSP1_DRC_3:
1444 case WM8915_DSP1_DRC_4:
1445 case WM8915_DSP1_DRC_5:
1446 case WM8915_DSP1_RX_EQ_GAINS_1:
1447 case WM8915_DSP1_RX_EQ_GAINS_2:
1448 case WM8915_DSP1_RX_EQ_BAND_1_A:
1449 case WM8915_DSP1_RX_EQ_BAND_1_B:
1450 case WM8915_DSP1_RX_EQ_BAND_1_PG:
1451 case WM8915_DSP1_RX_EQ_BAND_2_A:
1452 case WM8915_DSP1_RX_EQ_BAND_2_B:
1453 case WM8915_DSP1_RX_EQ_BAND_2_C:
1454 case WM8915_DSP1_RX_EQ_BAND_2_PG:
1455 case WM8915_DSP1_RX_EQ_BAND_3_A:
1456 case WM8915_DSP1_RX_EQ_BAND_3_B:
1457 case WM8915_DSP1_RX_EQ_BAND_3_C:
1458 case WM8915_DSP1_RX_EQ_BAND_3_PG:
1459 case WM8915_DSP1_RX_EQ_BAND_4_A:
1460 case WM8915_DSP1_RX_EQ_BAND_4_B:
1461 case WM8915_DSP1_RX_EQ_BAND_4_C:
1462 case WM8915_DSP1_RX_EQ_BAND_4_PG:
1463 case WM8915_DSP1_RX_EQ_BAND_5_A:
1464 case WM8915_DSP1_RX_EQ_BAND_5_B:
1465 case WM8915_DSP1_RX_EQ_BAND_5_PG:
1466 case WM8915_DSP2_TX_LEFT_VOLUME:
1467 case WM8915_DSP2_TX_RIGHT_VOLUME:
1468 case WM8915_DSP2_RX_LEFT_VOLUME:
1469 case WM8915_DSP2_RX_RIGHT_VOLUME:
1470 case WM8915_DSP2_TX_FILTERS:
1471 case WM8915_DSP2_RX_FILTERS_1:
1472 case WM8915_DSP2_RX_FILTERS_2:
1473 case WM8915_DSP2_DRC_1:
1474 case WM8915_DSP2_DRC_2:
1475 case WM8915_DSP2_DRC_3:
1476 case WM8915_DSP2_DRC_4:
1477 case WM8915_DSP2_DRC_5:
1478 case WM8915_DSP2_RX_EQ_GAINS_1:
1479 case WM8915_DSP2_RX_EQ_GAINS_2:
1480 case WM8915_DSP2_RX_EQ_BAND_1_A:
1481 case WM8915_DSP2_RX_EQ_BAND_1_B:
1482 case WM8915_DSP2_RX_EQ_BAND_1_PG:
1483 case WM8915_DSP2_RX_EQ_BAND_2_A:
1484 case WM8915_DSP2_RX_EQ_BAND_2_B:
1485 case WM8915_DSP2_RX_EQ_BAND_2_C:
1486 case WM8915_DSP2_RX_EQ_BAND_2_PG:
1487 case WM8915_DSP2_RX_EQ_BAND_3_A:
1488 case WM8915_DSP2_RX_EQ_BAND_3_B:
1489 case WM8915_DSP2_RX_EQ_BAND_3_C:
1490 case WM8915_DSP2_RX_EQ_BAND_3_PG:
1491 case WM8915_DSP2_RX_EQ_BAND_4_A:
1492 case WM8915_DSP2_RX_EQ_BAND_4_B:
1493 case WM8915_DSP2_RX_EQ_BAND_4_C:
1494 case WM8915_DSP2_RX_EQ_BAND_4_PG:
1495 case WM8915_DSP2_RX_EQ_BAND_5_A:
1496 case WM8915_DSP2_RX_EQ_BAND_5_B:
1497 case WM8915_DSP2_RX_EQ_BAND_5_PG:
1498 case WM8915_DAC1_MIXER_VOLUMES:
1499 case WM8915_DAC1_LEFT_MIXER_ROUTING:
1500 case WM8915_DAC1_RIGHT_MIXER_ROUTING:
1501 case WM8915_DAC2_MIXER_VOLUMES:
1502 case WM8915_DAC2_LEFT_MIXER_ROUTING:
1503 case WM8915_DAC2_RIGHT_MIXER_ROUTING:
1504 case WM8915_DSP1_TX_LEFT_MIXER_ROUTING:
1505 case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING:
1506 case WM8915_DSP2_TX_LEFT_MIXER_ROUTING:
1507 case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING:
1508 case WM8915_DSP_TX_MIXER_SELECT:
1509 case WM8915_DAC_SOFTMUTE:
1510 case WM8915_OVERSAMPLING:
1511 case WM8915_SIDETONE:
1512 case WM8915_GPIO_1:
1513 case WM8915_GPIO_2:
1514 case WM8915_GPIO_3:
1515 case WM8915_GPIO_4:
1516 case WM8915_GPIO_5:
1517 case WM8915_PULL_CONTROL_1:
1518 case WM8915_PULL_CONTROL_2:
1519 case WM8915_INTERRUPT_STATUS_1:
1520 case WM8915_INTERRUPT_STATUS_2:
1521 case WM8915_INTERRUPT_RAW_STATUS_2:
1522 case WM8915_INTERRUPT_STATUS_1_MASK:
1523 case WM8915_INTERRUPT_STATUS_2_MASK:
1524 case WM8915_INTERRUPT_CONTROL:
1525 case WM8915_LEFT_PDM_SPEAKER:
1526 case WM8915_RIGHT_PDM_SPEAKER:
1527 case WM8915_PDM_SPEAKER_MUTE_SEQUENCE:
1528 case WM8915_PDM_SPEAKER_VOLUME:
1529 return 1;
1530 default:
1531 return 0;
1532 }
1533}
1534
1535static int wm8915_volatile_register(struct snd_soc_codec *codec,
1536 unsigned int reg)
1537{
1538 switch (reg) {
1539 case WM8915_SOFTWARE_RESET:
1540 case WM8915_CHIP_REVISION:
1541 case WM8915_LDO_1:
1542 case WM8915_LDO_2:
1543 case WM8915_INTERRUPT_STATUS_1:
1544 case WM8915_INTERRUPT_STATUS_2:
1545 case WM8915_INTERRUPT_RAW_STATUS_2:
1546 case WM8915_DC_SERVO_READBACK_0:
1547 case WM8915_DC_SERVO_2:
1548 case WM8915_DC_SERVO_6:
1549 case WM8915_DC_SERVO_7:
1550 case WM8915_FLL_CONTROL_6:
1551 case WM8915_MIC_DETECT_3:
1552 case WM8915_HEADPHONE_DETECT_1:
1553 case WM8915_HEADPHONE_DETECT_2:
1554 return 1;
1555 default:
1556 return 0;
1557 }
1558}
1559
1560static int wm8915_reset(struct snd_soc_codec *codec)
1561{
1562 return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
1563}
1564
1565static int wm8915_set_bias_level(struct snd_soc_codec *codec,
1566 enum snd_soc_bias_level level)
1567{
1568 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1569 int ret;
1570
1571 switch (level) {
1572 case SND_SOC_BIAS_ON:
1573 break;
1574
1575 case SND_SOC_BIAS_PREPARE:
1576 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1577 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1578 WM8915_BG_ENA, WM8915_BG_ENA);
1579 msleep(2);
1580 }
1581 break;
1582
1583 case SND_SOC_BIAS_STANDBY:
1584 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1585 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
1586 wm8915->supplies);
1587 if (ret != 0) {
1588 dev_err(codec->dev,
1589 "Failed to enable supplies: %d\n",
1590 ret);
1591 return ret;
1592 }
1593
1594 if (wm8915->pdata.ldo_ena >= 0) {
1595 gpio_set_value_cansleep(wm8915->pdata.ldo_ena,
1596 1);
1597 msleep(5);
1598 }
1599
1600 codec->cache_only = false;
1601 snd_soc_cache_sync(codec);
1602 }
1603
1604 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1605 WM8915_BG_ENA, 0);
1606 break;
1607
1608 case SND_SOC_BIAS_OFF:
1609 codec->cache_only = true;
1610 if (wm8915->pdata.ldo_ena >= 0)
1611 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
1612 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies),
1613 wm8915->supplies);
1614 break;
1615 }
1616
1617 codec->dapm.bias_level = level;
1618
1619 return 0;
1620}
1621
1622static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1623{
1624 struct snd_soc_codec *codec = dai->codec;
1625 int aifctrl = 0;
1626 int bclk = 0;
1627 int lrclk_tx = 0;
1628 int lrclk_rx = 0;
1629 int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
1630
1631 switch (dai->id) {
1632 case 0:
1633 aifctrl_reg = WM8915_AIF1_CONTROL;
1634 bclk_reg = WM8915_AIF1_BCLK;
1635 lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2;
1636 lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2;
1637 break;
1638 case 1:
1639 aifctrl_reg = WM8915_AIF2_CONTROL;
1640 bclk_reg = WM8915_AIF2_BCLK;
1641 lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2;
1642 lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2;
1643 break;
1644 default:
1645 BUG();
1646 return -EINVAL;
1647 }
1648
1649 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1650 case SND_SOC_DAIFMT_NB_NF:
1651 break;
1652 case SND_SOC_DAIFMT_IB_NF:
1653 bclk |= WM8915_AIF1_BCLK_INV;
1654 break;
1655 case SND_SOC_DAIFMT_NB_IF:
1656 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1657 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1658 break;
1659 case SND_SOC_DAIFMT_IB_IF:
1660 bclk |= WM8915_AIF1_BCLK_INV;
1661 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1662 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1663 break;
1664 }
1665
1666 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1667 case SND_SOC_DAIFMT_CBS_CFS:
1668 break;
1669 case SND_SOC_DAIFMT_CBS_CFM:
1670 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1671 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1672 break;
1673 case SND_SOC_DAIFMT_CBM_CFS:
1674 bclk |= WM8915_AIF1_BCLK_MSTR;
1675 break;
1676 case SND_SOC_DAIFMT_CBM_CFM:
1677 bclk |= WM8915_AIF1_BCLK_MSTR;
1678 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1679 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1680 break;
1681 default:
1682 return -EINVAL;
1683 }
1684
1685 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1686 case SND_SOC_DAIFMT_DSP_A:
1687 break;
1688 case SND_SOC_DAIFMT_DSP_B:
1689 aifctrl |= 1;
1690 break;
1691 case SND_SOC_DAIFMT_I2S:
1692 aifctrl |= 2;
1693 break;
1694 case SND_SOC_DAIFMT_LEFT_J:
1695 aifctrl |= 3;
1696 break;
1697 default:
1698 return -EINVAL;
1699 }
1700
1701 snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl);
1702 snd_soc_update_bits(codec, bclk_reg,
1703 WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR,
1704 bclk);
1705 snd_soc_update_bits(codec, lrclk_tx_reg,
1706 WM8915_AIF1TX_LRCLK_INV |
1707 WM8915_AIF1TX_LRCLK_MSTR,
1708 lrclk_tx);
1709 snd_soc_update_bits(codec, lrclk_rx_reg,
1710 WM8915_AIF1RX_LRCLK_INV |
1711 WM8915_AIF1RX_LRCLK_MSTR,
1712 lrclk_rx);
1713
1714 return 0;
1715}
1716
1717static const int bclk_divs[] = {
1718 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1719};
1720
1721static const int dsp_divs[] = {
1722 48000, 32000, 16000, 8000
1723};
1724
1725static int wm8915_hw_params(struct snd_pcm_substream *substream,
1726 struct snd_pcm_hw_params *params,
1727 struct snd_soc_dai *dai)
1728{
1729 struct snd_soc_codec *codec = dai->codec;
1730 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1731 int bits, i, bclk_rate, best, cur_val;
1732 int aifdata = 0;
1733 int bclk = 0;
1734 int lrclk = 0;
1735 int dsp = 0;
1736 int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift;
1737
1738 if (!wm8915->sysclk) {
1739 dev_err(codec->dev, "SYSCLK not configured\n");
1740 return -EINVAL;
1741 }
1742
1743 switch (dai->id) {
1744 case 0:
1745 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1746 (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) {
1747 aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION;
1748 lrclk_reg = WM8915_AIF1_RX_LRCLK_1;
1749 } else {
1750 aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
1751 lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
1752 }
1753 bclk_reg = WM8915_AIF1_BCLK;
1754 dsp_shift = 0;
1755 break;
1756 case 1:
1757 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1758 (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) {
1759 aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION;
1760 lrclk_reg = WM8915_AIF2_RX_LRCLK_1;
1761 } else {
1762 aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
1763 lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
1764 }
1765 bclk_reg = WM8915_AIF2_BCLK;
1766 dsp_shift = WM8915_DSP2_DIV_SHIFT;
1767 break;
1768 default:
1769 BUG();
1770 return -EINVAL;
1771 }
1772
1773 bclk_rate = snd_soc_params_to_bclk(params);
1774 if (bclk_rate < 0) {
1775 dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
1776 return bclk_rate;
1777 }
1778
1779 /* Needs looking at for TDM */
1780 bits = snd_pcm_format_width(params_format(params));
1781 if (bits < 0)
1782 return bits;
1783 aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits;
1784
1785 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
1786 if (dsp_divs[i] == params_rate(params))
1787 break;
1788 }
1789 if (i == ARRAY_SIZE(dsp_divs)) {
1790 dev_err(codec->dev, "Unsupported sample rate %dHz\n",
1791 params_rate(params));
1792 return -EINVAL;
1793 }
1794 dsp |= i << dsp_shift;
1795
1796 /* Pick a divisor for BCLK as close as we can get to ideal */
1797 best = 0;
1798 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1799 cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
1800 if (cur_val < 0) /* BCLK table is sorted */
1801 break;
1802 best = i;
1803 }
1804 bclk_rate = wm8915->sysclk / bclk_divs[best];
1805 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1806 bclk_divs[best], bclk_rate);
1807 bclk |= best;
1808
1809 lrclk = bclk_rate / params_rate(params);
1810 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
1811 lrclk, bclk_rate / lrclk);
1812
1813 snd_soc_update_bits(codec, aifdata_reg,
1814 WM8915_AIF1TX_WL_MASK |
1815 WM8915_AIF1TX_SLOT_LEN_MASK,
1816 aifdata);
1817 snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
1818 snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
1819 lrclk);
1820 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
1821 WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
1822
1823 wm8915->rx_rate[dai->id] = params_rate(params);
1824
1825 return 0;
1826}
1827
1828static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1829 int clk_id, unsigned int freq, int dir)
1830{
1831 struct snd_soc_codec *codec = dai->codec;
1832 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1833 int lfclk = 0;
1834 int src;
1835 int old;
1836
1837 /* Disable SYSCLK while we reconfigure */
1838 old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1);
1839 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1840 WM8915_SYSCLK_ENA, 0);
1841
1842 switch (clk_id) {
1843 case WM8915_SYSCLK_MCLK1:
1844 wm8915->sysclk = freq;
1845 src = 0;
1846 break;
1847 case WM8915_SYSCLK_MCLK2:
1848 wm8915->sysclk = freq;
1849 src = 1;
1850 break;
1851 case WM8915_SYSCLK_FLL:
1852 wm8915->sysclk = freq;
1853 src = 2;
1854 break;
1855 default:
1856 dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
1857 return -EINVAL;
1858 }
1859
1860 switch (wm8915->sysclk) {
1861 case 6144000:
1862 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1863 WM8915_SYSCLK_RATE, 0);
1864 break;
1865 case 12288000:
1866 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1867 WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE);
1868 break;
1869 case 32000:
1870 case 32768:
1871 lfclk = WM8915_LFCLK_ENA;
1872 break;
1873 default:
1874 dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
1875 wm8915->sysclk);
1876 return -EINVAL;
1877 }
1878
1879 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1880 WM8915_SYSCLK_SRC_MASK,
1881 src << WM8915_SYSCLK_SRC_SHIFT);
1882 snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk);
1883 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1884 WM8915_SYSCLK_ENA, old);
1885
1886 return 0;
1887}
1888
1889struct _fll_div {
1890 u16 fll_fratio;
1891 u16 fll_outdiv;
1892 u16 fll_refclk_div;
1893 u16 fll_loop_gain;
1894 u16 fll_ref_freq;
1895 u16 n;
1896 u16 theta;
1897 u16 lambda;
1898};
1899
1900static struct {
1901 unsigned int min;
1902 unsigned int max;
1903 u16 fll_fratio;
1904 int ratio;
1905} fll_fratios[] = {
1906 { 0, 64000, 4, 16 },
1907 { 64000, 128000, 3, 8 },
1908 { 128000, 256000, 2, 4 },
1909 { 256000, 1000000, 1, 2 },
1910 { 1000000, 13500000, 0, 1 },
1911};
1912
1913static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1914 unsigned int Fout)
1915{
1916 unsigned int target;
1917 unsigned int div;
1918 unsigned int fratio, gcd_fll;
1919 int i;
1920
1921 /* Fref must be <=13.5MHz */
1922 div = 1;
1923 fll_div->fll_refclk_div = 0;
1924 while ((Fref / div) > 13500000) {
1925 div *= 2;
1926 fll_div->fll_refclk_div++;
1927
1928 if (div > 8) {
1929 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1930 Fref);
1931 return -EINVAL;
1932 }
1933 }
1934
1935 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1936
1937 /* Apply the division for our remaining calculations */
1938 Fref /= div;
1939
1940 if (Fref >= 3000000)
1941 fll_div->fll_loop_gain = 5;
1942 else
1943 fll_div->fll_loop_gain = 0;
1944
1945 if (Fref >= 48000)
1946 fll_div->fll_ref_freq = 0;
1947 else
1948 fll_div->fll_ref_freq = 1;
1949
1950 /* Fvco should be 90-100MHz; don't check the upper bound */
1951 div = 2;
1952 while (Fout * div < 90000000) {
1953 div++;
1954 if (div > 64) {
1955 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1956 Fout);
1957 return -EINVAL;
1958 }
1959 }
1960 target = Fout * div;
1961 fll_div->fll_outdiv = div - 1;
1962
1963 pr_debug("FLL Fvco=%dHz\n", target);
1964
1965 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1966 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1967 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1968 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1969 fratio = fll_fratios[i].ratio;
1970 break;
1971 }
1972 }
1973 if (i == ARRAY_SIZE(fll_fratios)) {
1974 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1975 return -EINVAL;
1976 }
1977
1978 fll_div->n = target / (fratio * Fref);
1979
1980 if (target % Fref == 0) {
1981 fll_div->theta = 0;
1982 fll_div->lambda = 0;
1983 } else {
1984 gcd_fll = gcd(target, fratio * Fref);
1985
1986 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1987 / gcd_fll;
1988 fll_div->lambda = (fratio * Fref) / gcd_fll;
1989 }
1990
1991 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1992 fll_div->n, fll_div->theta, fll_div->lambda);
1993 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1994 fll_div->fll_fratio, fll_div->fll_outdiv,
1995 fll_div->fll_refclk_div);
1996
1997 return 0;
1998}
1999
2000static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2001 unsigned int Fref, unsigned int Fout)
2002{
2003 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2004 struct _fll_div fll_div;
2005 unsigned long timeout;
2006 int ret, reg;
2007
2008 /* Any change? */
2009 if (source == wm8915->fll_src && Fref == wm8915->fll_fref &&
2010 Fout == wm8915->fll_fout)
2011 return 0;
2012
2013 if (Fout == 0) {
2014 dev_dbg(codec->dev, "FLL disabled\n");
2015
2016 wm8915->fll_fref = 0;
2017 wm8915->fll_fout = 0;
2018
2019 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2020 WM8915_FLL_ENA, 0);
2021
2022 return 0;
2023 }
2024
2025 ret = fll_factors(&fll_div, Fref, Fout);
2026 if (ret != 0)
2027 return ret;
2028
2029 switch (source) {
2030 case WM8915_FLL_MCLK1:
2031 reg = 0;
2032 break;
2033 case WM8915_FLL_MCLK2:
2034 reg = 1;
2035 case WM8915_FLL_DACLRCLK1:
2036 reg = 2;
2037 break;
2038 case WM8915_FLL_BCLK1:
2039 reg = 3;
2040 break;
2041 default:
2042 dev_err(codec->dev, "Unknown FLL source %d\n", ret);
2043 return -EINVAL;
2044 }
2045
2046 reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT;
2047 reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT;
2048
2049 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5,
2050 WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ |
2051 WM8915_FLL_REFCLK_SRC_MASK, reg);
2052
2053 reg = 0;
2054 if (fll_div.theta || fll_div.lambda)
2055 reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT);
2056 else
2057 reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT;
2058 snd_soc_write(codec, WM8915_FLL_EFS_2, reg);
2059
2060 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2,
2061 WM8915_FLL_OUTDIV_MASK |
2062 WM8915_FLL_FRATIO_MASK,
2063 (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) |
2064 (fll_div.fll_fratio));
2065
2066 snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta);
2067
2068 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4,
2069 WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK,
2070 (fll_div.n << WM8915_FLL_N_SHIFT) |
2071 fll_div.fll_loop_gain);
2072
2073 snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda);
2074
2075 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2076 WM8915_FLL_ENA, WM8915_FLL_ENA);
2077
2078 /* The FLL supports live reconfiguration - kick that in case we were
2079 * already enabled.
2080 */
2081 snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK);
2082
2083 /* Wait for the FLL to lock, using the interrupt if possible */
2084 if (Fref > 1000000)
2085 timeout = usecs_to_jiffies(300);
2086 else
2087 timeout = msecs_to_jiffies(2);
2088
2089 wait_for_completion_timeout(&wm8915->fll_lock, timeout);
2090
2091 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2092
2093 wm8915->fll_fref = Fref;
2094 wm8915->fll_fout = Fout;
2095 wm8915->fll_src = source;
2096
2097 return 0;
2098}
2099
2100#ifdef CONFIG_GPIOLIB
2101static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip)
2102{
2103 return container_of(chip, struct wm8915_priv, gpio_chip);
2104}
2105
2106static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2107{
2108 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2109 struct snd_soc_codec *codec = wm8915->codec;
2110
2111 snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2112 WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT);
2113}
2114
2115static int wm8915_gpio_direction_out(struct gpio_chip *chip,
2116 unsigned offset, int value)
2117{
2118 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2119 struct snd_soc_codec *codec = wm8915->codec;
2120 int val;
2121
2122 val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT);
2123
2124 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2125 WM8915_GP1_FN_MASK | WM8915_GP1_DIR |
2126 WM8915_GP1_LVL, val);
2127}
2128
2129static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset)
2130{
2131 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2132 struct snd_soc_codec *codec = wm8915->codec;
2133 int ret;
2134
2135 ret = snd_soc_read(codec, WM8915_GPIO_1 + offset);
2136 if (ret < 0)
2137 return ret;
2138
2139 return (ret & WM8915_GP1_LVL) != 0;
2140}
2141
2142static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2143{
2144 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2145 struct snd_soc_codec *codec = wm8915->codec;
2146
2147 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2148 WM8915_GP1_FN_MASK | WM8915_GP1_DIR,
2149 (1 << WM8915_GP1_FN_SHIFT) |
2150 (1 << WM8915_GP1_DIR_SHIFT));
2151}
2152
2153static struct gpio_chip wm8915_template_chip = {
2154 .label = "wm8915",
2155 .owner = THIS_MODULE,
2156 .direction_output = wm8915_gpio_direction_out,
2157 .set = wm8915_gpio_set,
2158 .direction_input = wm8915_gpio_direction_in,
2159 .get = wm8915_gpio_get,
2160 .can_sleep = 1,
2161};
2162
2163static void wm8915_init_gpio(struct snd_soc_codec *codec)
2164{
2165 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2166 int ret;
2167
2168 wm8915->gpio_chip = wm8915_template_chip;
2169 wm8915->gpio_chip.ngpio = 5;
2170 wm8915->gpio_chip.dev = codec->dev;
2171
2172 if (wm8915->pdata.gpio_base)
2173 wm8915->gpio_chip.base = wm8915->pdata.gpio_base;
2174 else
2175 wm8915->gpio_chip.base = -1;
2176
2177 ret = gpiochip_add(&wm8915->gpio_chip);
2178 if (ret != 0)
2179 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2180}
2181
2182static void wm8915_free_gpio(struct snd_soc_codec *codec)
2183{
2184 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2185 int ret;
2186
2187 ret = gpiochip_remove(&wm8915->gpio_chip);
2188 if (ret != 0)
2189 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2190}
2191#else
2192static void wm8915_init_gpio(struct snd_soc_codec *codec)
2193{
2194}
2195
2196static void wm8915_free_gpio(struct snd_soc_codec *codec)
2197{
2198}
2199#endif
2200
2201/**
2202 * wm8915_detect - Enable default WM8915 jack detection
2203 *
2204 * The WM8915 has advanced accessory detection support for headsets.
2205 * This function provides a default implementation which integrates
2206 * the majority of this functionality with minimal user configuration.
2207 *
2208 * This will detect headset, headphone and short circuit button and
2209 * will also detect inverted microphone ground connections and update
2210 * the polarity of the connections.
2211 */
2212int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2213 wm8915_polarity_fn polarity_cb)
2214{
2215 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2216
2217 wm8915->jack = jack;
2218 wm8915->detecting = true;
2219 wm8915->polarity_cb = polarity_cb;
2220
2221 if (wm8915->polarity_cb)
2222 wm8915->polarity_cb(codec, 0);
2223
2224 /* Clear discarge to avoid noise during detection */
2225 snd_soc_update_bits(codec, WM8915_MICBIAS_1,
2226 WM8915_MICB1_DISCH, 0);
2227 snd_soc_update_bits(codec, WM8915_MICBIAS_2,
2228 WM8915_MICB2_DISCH, 0);
2229
2230 /* LDO2 powers the microphones, SYSCLK clocks detection */
2231 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
2232 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2233
2234 /* We start off just enabling microphone detection - even a
2235 * plain headphone will trigger detection.
2236 */
2237 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2238 WM8915_MICD_ENA, WM8915_MICD_ENA);
2239
2240 /* Slowest detection rate, gives debounce for initial detection */
2241 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2242 WM8915_MICD_RATE_MASK,
2243 WM8915_MICD_RATE_MASK);
2244
2245 /* Enable interrupts and we're off */
2246 snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK,
2247 WM8915_IM_MICD_EINT, 0);
2248
2249 return 0;
2250}
2251EXPORT_SYMBOL_GPL(wm8915_detect);
2252
2253static void wm8915_micd(struct snd_soc_codec *codec)
2254{
2255 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2256 int val, reg;
2257
2258 val = snd_soc_read(codec, WM8915_MIC_DETECT_3);
2259
2260 dev_dbg(codec->dev, "Microphone event: %x\n", val);
2261
2262 if (!(val & WM8915_MICD_VALID)) {
2263 dev_warn(codec->dev, "Microphone detection state invalid\n");
2264 return;
2265 }
2266
2267 /* No accessory, reset everything and report removal */
2268 if (!(val & WM8915_MICD_STS)) {
2269 dev_dbg(codec->dev, "Jack removal detected\n");
2270 wm8915->jack_mic = false;
2271 wm8915->detecting = true;
2272 snd_soc_jack_report(wm8915->jack, 0,
2273 SND_JACK_HEADSET | SND_JACK_BTN_0);
2274 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2275 WM8915_MICD_RATE_MASK,
2276 WM8915_MICD_RATE_MASK);
2277 return;
2278 }
2279
2280 /* If the measurement is very high we've got a microphone but
2281 * do a little debounce to account for mechanical issues.
2282 */
2283 if (val & 0x400) {
2284 dev_dbg(codec->dev, "Microphone detected\n");
2285 snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET,
2286 SND_JACK_HEADSET | SND_JACK_BTN_0);
2287 wm8915->jack_mic = true;
2288 wm8915->detecting = false;
2289 }
2290
2291 /* If we detected a lower impedence during initial startup
2292 * then we probably have the wrong polarity, flip it. Don't
2293 * do this for the lowest impedences to speed up detection of
2294 * plain headphones.
2295 */
2296 if (wm8915->detecting && (val & 0x3f0)) {
2297 reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2);
2298 reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2299 WM8915_MICD_BIAS_SRC;
2300 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2301 WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2302 WM8915_MICD_BIAS_SRC, reg);
2303
2304 if (wm8915->polarity_cb)
2305 wm8915->polarity_cb(codec,
2306 (reg & WM8915_MICD_SRC) != 0);
2307
2308 dev_dbg(codec->dev, "Set microphone polarity to %d\n",
2309 (reg & WM8915_MICD_SRC) != 0);
2310
2311 return;
2312 }
2313
2314 /* Don't distinguish between buttons, just report any low
2315 * impedence as BTN_0.
2316 */
2317 if (val & 0x3fc) {
2318 if (wm8915->jack_mic) {
2319 dev_dbg(codec->dev, "Mic button detected\n");
2320 snd_soc_jack_report(wm8915->jack,
2321 SND_JACK_HEADSET | SND_JACK_BTN_0,
2322 SND_JACK_HEADSET | SND_JACK_BTN_0);
2323 } else {
2324 dev_dbg(codec->dev, "Headphone detected\n");
2325 snd_soc_jack_report(wm8915->jack,
2326 SND_JACK_HEADPHONE,
2327 SND_JACK_HEADSET |
2328 SND_JACK_BTN_0);
2329 wm8915->detecting = false;
2330 }
2331 }
2332
2333 /* Increase poll rate to give better responsiveness for buttons */
2334 if (!wm8915->detecting)
2335 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2336 WM8915_MICD_RATE_MASK,
2337 5 << WM8915_MICD_RATE_SHIFT);
2338}
2339
2340static irqreturn_t wm8915_irq(int irq, void *data)
2341{
2342 struct snd_soc_codec *codec = data;
2343 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2344 int irq_val;
2345
2346 irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2);
2347 if (irq_val < 0) {
2348 dev_err(codec->dev, "Failed to read IRQ status: %d\n",
2349 irq_val);
2350 return IRQ_NONE;
2351 }
2352 irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK);
2353
2354 if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) {
2355 dev_dbg(codec->dev, "DC servo IRQ\n");
2356 complete(&wm8915->dcs_done);
2357 }
2358
2359 if (irq_val & WM8915_FIFOS_ERR_EINT)
2360 dev_err(codec->dev, "Digital core FIFO error\n");
2361
2362 if (irq_val & WM8915_FLL_LOCK_EINT) {
2363 dev_dbg(codec->dev, "FLL locked\n");
2364 complete(&wm8915->fll_lock);
2365 }
2366
2367 if (irq_val & WM8915_MICD_EINT)
2368 wm8915_micd(codec);
2369
2370 if (irq_val) {
2371 snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val);
2372
2373 return IRQ_HANDLED;
2374 } else {
2375 return IRQ_NONE;
2376 }
2377}
2378
2379static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
2380{
2381 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2382 struct wm8915_pdata *pdata = &wm8915->pdata;
2383
2384 struct snd_kcontrol_new controls[] = {
2385 SOC_ENUM_EXT("DSP1 EQ Mode",
2386 wm8915->retune_mobile_enum,
2387 wm8915_get_retune_mobile_enum,
2388 wm8915_put_retune_mobile_enum),
2389 SOC_ENUM_EXT("DSP2 EQ Mode",
2390 wm8915->retune_mobile_enum,
2391 wm8915_get_retune_mobile_enum,
2392 wm8915_put_retune_mobile_enum),
2393 };
2394 int ret, i, j;
2395 const char **t;
2396
2397 /* We need an array of texts for the enum API but the number
2398 * of texts is likely to be less than the number of
2399 * configurations due to the sample rate dependency of the
2400 * configurations. */
2401 wm8915->num_retune_mobile_texts = 0;
2402 wm8915->retune_mobile_texts = NULL;
2403 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2404 for (j = 0; j < wm8915->num_retune_mobile_texts; j++) {
2405 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2406 wm8915->retune_mobile_texts[j]) == 0)
2407 break;
2408 }
2409
2410 if (j != wm8915->num_retune_mobile_texts)
2411 continue;
2412
2413 /* Expand the array... */
2414 t = krealloc(wm8915->retune_mobile_texts,
2415 sizeof(char *) *
2416 (wm8915->num_retune_mobile_texts + 1),
2417 GFP_KERNEL);
2418 if (t == NULL)
2419 continue;
2420
2421 /* ...store the new entry... */
2422 t[wm8915->num_retune_mobile_texts] =
2423 pdata->retune_mobile_cfgs[i].name;
2424
2425 /* ...and remember the new version. */
2426 wm8915->num_retune_mobile_texts++;
2427 wm8915->retune_mobile_texts = t;
2428 }
2429
2430 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2431 wm8915->num_retune_mobile_texts);
2432
2433 wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts;
2434 wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts;
2435
2436 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2437 if (ret != 0)
2438 dev_err(codec->dev,
2439 "Failed to add ReTune Mobile controls: %d\n", ret);
2440}
2441
2442static int wm8915_probe(struct snd_soc_codec *codec)
2443{
2444 int ret;
2445 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2446 struct i2c_client *i2c = to_i2c_client(codec->dev);
2447 struct snd_soc_dapm_context *dapm = &codec->dapm;
2448 int i, irq_flags;
2449
2450 wm8915->codec = codec;
2451
2452 init_completion(&wm8915->dcs_done);
2453 init_completion(&wm8915->fll_lock);
2454
2455 dapm->idle_bias_off = true;
2456 dapm->bias_level = SND_SOC_BIAS_OFF;
2457
2458 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2459 if (ret != 0) {
2460 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2461 goto err;
2462 }
2463
2464 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2465 wm8915->supplies[i].supply = wm8915_supply_names[i];
2466
2467 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies),
2468 wm8915->supplies);
2469 if (ret != 0) {
2470 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2471 goto err;
2472 }
2473
2474 wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0;
2475 wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
2476 wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
2477 wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
2478 wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
2479 wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;
2480
2481 /* This should really be moved into the regulator core */
2482 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
2483 ret = regulator_register_notifier(wm8915->supplies[i].consumer,
2484 &wm8915->disable_nb[i]);
2485 if (ret != 0) {
2486 dev_err(codec->dev,
2487 "Failed to register regulator notifier: %d\n",
2488 ret);
2489 }
2490 }
2491
2492 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
2493 wm8915->supplies);
2494 if (ret != 0) {
2495 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2496 goto err_get;
2497 }
2498
2499 if (wm8915->pdata.ldo_ena >= 0) {
2500 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1);
2501 msleep(5);
2502 }
2503
2504 ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET);
2505 if (ret < 0) {
2506 dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
2507 goto err_enable;
2508 }
2509 if (ret != 0x8915) {
2510 dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret);
2511 ret = -EINVAL;
2512 goto err_enable;
2513 }
2514
2515 ret = snd_soc_read(codec, WM8915_CHIP_REVISION);
2516 if (ret < 0) {
2517 dev_err(codec->dev, "Failed to read device revision: %d\n",
2518 ret);
2519 goto err_enable;
2520 }
2521
2522 dev_info(codec->dev, "revision %c\n",
2523 (ret & WM8915_CHIP_REV_MASK) + 'A');
2524
2525 if (wm8915->pdata.ldo_ena >= 0) {
2526 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2527 } else {
2528 ret = wm8915_reset(codec);
2529 if (ret < 0) {
2530 dev_err(codec->dev, "Failed to issue reset\n");
2531 goto err_enable;
2532 }
2533 }
2534
2535 codec->cache_only = true;
2536
2537 /* Apply platform data settings */
2538 snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL,
2539 WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK,
2540 wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT |
2541 wm8915->pdata.inr_mode);
2542
2543 for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) {
2544 if (!wm8915->pdata.gpio_default[i])
2545 continue;
2546
2547 snd_soc_write(codec, WM8915_GPIO_1 + i,
2548 wm8915->pdata.gpio_default[i] & 0xffff);
2549 }
2550
2551 if (wm8915->pdata.spkmute_seq)
2552 snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE,
2553 WM8915_SPK_MUTE_ENDIAN |
2554 WM8915_SPK_MUTE_SEQ1_MASK,
2555 wm8915->pdata.spkmute_seq);
2556
2557 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2558 WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC |
2559 WM8915_MICD_SRC, wm8915->pdata.micdet_def);
2560
2561 /* Latch volume update bits */
2562 snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME,
2563 WM8915_IN1_VU, WM8915_IN1_VU);
2564 snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME,
2565 WM8915_IN1_VU, WM8915_IN1_VU);
2566
2567 snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME,
2568 WM8915_DAC1_VU, WM8915_DAC1_VU);
2569 snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME,
2570 WM8915_DAC1_VU, WM8915_DAC1_VU);
2571 snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME,
2572 WM8915_DAC2_VU, WM8915_DAC2_VU);
2573 snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME,
2574 WM8915_DAC2_VU, WM8915_DAC2_VU);
2575
2576 snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME,
2577 WM8915_DAC1_VU, WM8915_DAC1_VU);
2578 snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME,
2579 WM8915_DAC1_VU, WM8915_DAC1_VU);
2580 snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME,
2581 WM8915_DAC2_VU, WM8915_DAC2_VU);
2582 snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME,
2583 WM8915_DAC2_VU, WM8915_DAC2_VU);
2584
2585 snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME,
2586 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2587 snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME,
2588 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2589 snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME,
2590 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2591 snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME,
2592 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2593
2594 snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME,
2595 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2596 snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME,
2597 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2598 snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME,
2599 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2600 snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME,
2601 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2602
2603 /* No support currently for the underclocked TDM modes and
2604 * pick a default TDM layout with each channel pair working with
2605 * slots 0 and 1. */
2606 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION,
2607 WM8915_AIF1RX_CHAN0_SLOTS_MASK |
2608 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2609 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2610 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION,
2611 WM8915_AIF1RX_CHAN1_SLOTS_MASK |
2612 WM8915_AIF1RX_CHAN1_START_SLOT_MASK,
2613 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2614 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION,
2615 WM8915_AIF1RX_CHAN2_SLOTS_MASK |
2616 WM8915_AIF1RX_CHAN2_START_SLOT_MASK,
2617 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2618 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION,
2619 WM8915_AIF1RX_CHAN3_SLOTS_MASK |
2620 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2621 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2622 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION,
2623 WM8915_AIF1RX_CHAN4_SLOTS_MASK |
2624 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2625 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2626 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION,
2627 WM8915_AIF1RX_CHAN5_SLOTS_MASK |
2628 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2629 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2630
2631 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION,
2632 WM8915_AIF2RX_CHAN0_SLOTS_MASK |
2633 WM8915_AIF2RX_CHAN0_START_SLOT_MASK,
2634 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2635 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION,
2636 WM8915_AIF2RX_CHAN1_SLOTS_MASK |
2637 WM8915_AIF2RX_CHAN1_START_SLOT_MASK,
2638 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2639
2640 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION,
2641 WM8915_AIF1TX_CHAN0_SLOTS_MASK |
2642 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2643 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2644 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2645 WM8915_AIF1TX_CHAN1_SLOTS_MASK |
2646 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2647 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2648 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION,
2649 WM8915_AIF1TX_CHAN2_SLOTS_MASK |
2650 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2651 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2652 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION,
2653 WM8915_AIF1TX_CHAN3_SLOTS_MASK |
2654 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2655 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2656 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION,
2657 WM8915_AIF1TX_CHAN4_SLOTS_MASK |
2658 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2659 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2660 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION,
2661 WM8915_AIF1TX_CHAN5_SLOTS_MASK |
2662 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2663 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2664
2665 snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION,
2666 WM8915_AIF2TX_CHAN0_SLOTS_MASK |
2667 WM8915_AIF2TX_CHAN0_START_SLOT_MASK,
2668 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2669 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2670 WM8915_AIF2TX_CHAN1_SLOTS_MASK |
2671 WM8915_AIF2TX_CHAN1_START_SLOT_MASK,
2672 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2673
2674 if (wm8915->pdata.num_retune_mobile_cfgs)
2675 wm8915_retune_mobile_pdata(codec);
2676 else
2677 snd_soc_add_controls(codec, wm8915_eq_controls,
2678 ARRAY_SIZE(wm8915_eq_controls));
2679
2680 /* If the TX LRCLK pins are not in LRCLK mode configure the
2681 * AIFs to source their clocks from the RX LRCLKs.
2682 */
2683 if ((snd_soc_read(codec, WM8915_GPIO_1)))
2684 snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2,
2685 WM8915_AIF1TX_LRCLK_MODE,
2686 WM8915_AIF1TX_LRCLK_MODE);
2687
2688 if ((snd_soc_read(codec, WM8915_GPIO_2)))
2689 snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2,
2690 WM8915_AIF2TX_LRCLK_MODE,
2691 WM8915_AIF2TX_LRCLK_MODE);
2692
2693 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2694
2695 wm8915_init_gpio(codec);
2696
2697 if (i2c->irq) {
2698 if (wm8915->pdata.irq_flags)
2699 irq_flags = wm8915->pdata.irq_flags;
2700 else
2701 irq_flags = IRQF_TRIGGER_LOW;
2702
2703 irq_flags |= IRQF_ONESHOT;
2704
2705 ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
2706 irq_flags, "wm8915", codec);
2707 if (ret == 0) {
2708 /* Unmask the interrupt */
2709 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2710 WM8915_IM_IRQ, 0);
2711
2712 /* Enable error reporting and DC servo status */
2713 snd_soc_update_bits(codec,
2714 WM8915_INTERRUPT_STATUS_2_MASK,
2715 WM8915_IM_DCS_DONE_23_EINT |
2716 WM8915_IM_DCS_DONE_01_EINT |
2717 WM8915_IM_FLL_LOCK_EINT |
2718 WM8915_IM_FIFOS_ERR_EINT,
2719 0);
2720 } else {
2721 dev_err(codec->dev, "Failed to request IRQ: %d\n",
2722 ret);
2723 }
2724 }
2725
2726 return 0;
2727
2728err_enable:
2729 if (wm8915->pdata.ldo_ena >= 0)
2730 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2731
2732 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2733err_get:
2734 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2735err:
2736 return ret;
2737}
2738
2739static int wm8915_remove(struct snd_soc_codec *codec)
2740{
2741 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2742 struct i2c_client *i2c = to_i2c_client(codec->dev);
2743 int i;
2744
2745 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2746 WM8915_IM_IRQ, WM8915_IM_IRQ);
2747
2748 if (i2c->irq)
2749 free_irq(i2c->irq, codec);
2750
2751 wm8915_free_gpio(codec);
2752
2753 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2754 regulator_unregister_notifier(wm8915->supplies[i].consumer,
2755 &wm8915->disable_nb[i]);
2756 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2757
2758 return 0;
2759}
2760
2761static struct snd_soc_codec_driver soc_codec_dev_wm8915 = {
2762 .probe = wm8915_probe,
2763 .remove = wm8915_remove,
2764 .set_bias_level = wm8915_set_bias_level,
2765 .seq_notifier = wm8915_seq_notifier,
2766 .reg_cache_size = WM8915_MAX_REGISTER + 1,
2767 .reg_word_size = sizeof(u16),
2768 .reg_cache_default = wm8915_reg,
2769 .volatile_register = wm8915_volatile_register,
2770 .readable_register = wm8915_readable_register,
2771 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2772 .controls = wm8915_snd_controls,
2773 .num_controls = ARRAY_SIZE(wm8915_snd_controls),
2774 .dapm_widgets = wm8915_dapm_widgets,
2775 .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets),
2776 .dapm_routes = wm8915_dapm_routes,
2777 .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes),
2778 .set_pll = wm8915_set_fll,
2779};
2780
2781#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
2782 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
2783#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
2784 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
2785 SNDRV_PCM_FMTBIT_S32_LE)
2786
2787static struct snd_soc_dai_ops wm8915_dai_ops = {
2788 .set_fmt = wm8915_set_fmt,
2789 .hw_params = wm8915_hw_params,
2790 .set_sysclk = wm8915_set_sysclk,
2791};
2792
2793static struct snd_soc_dai_driver wm8915_dai[] = {
2794 {
2795 .name = "wm8915-aif1",
2796 .playback = {
2797 .stream_name = "AIF1 Playback",
2798 .channels_min = 1,
2799 .channels_max = 6,
2800 .rates = WM8915_RATES,
2801 .formats = WM8915_FORMATS,
2802 },
2803 .capture = {
2804 .stream_name = "AIF1 Capture",
2805 .channels_min = 1,
2806 .channels_max = 6,
2807 .rates = WM8915_RATES,
2808 .formats = WM8915_FORMATS,
2809 },
2810 .ops = &wm8915_dai_ops,
2811 },
2812 {
2813 .name = "wm8915-aif2",
2814 .playback = {
2815 .stream_name = "AIF2 Playback",
2816 .channels_min = 1,
2817 .channels_max = 2,
2818 .rates = WM8915_RATES,
2819 .formats = WM8915_FORMATS,
2820 },
2821 .capture = {
2822 .stream_name = "AIF2 Capture",
2823 .channels_min = 1,
2824 .channels_max = 2,
2825 .rates = WM8915_RATES,
2826 .formats = WM8915_FORMATS,
2827 },
2828 .ops = &wm8915_dai_ops,
2829 },
2830};
2831
2832static __devinit int wm8915_i2c_probe(struct i2c_client *i2c,
2833 const struct i2c_device_id *id)
2834{
2835 struct wm8915_priv *wm8915;
2836 int ret;
2837
2838 wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL);
2839 if (wm8915 == NULL)
2840 return -ENOMEM;
2841
2842 i2c_set_clientdata(i2c, wm8915);
2843
2844 if (dev_get_platdata(&i2c->dev))
2845 memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev),
2846 sizeof(wm8915->pdata));
2847
2848 if (wm8915->pdata.ldo_ena > 0) {
2849 ret = gpio_request_one(wm8915->pdata.ldo_ena,
2850 GPIOF_OUT_INIT_LOW, "WM8915 ENA");
2851 if (ret < 0) {
2852 dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
2853 wm8915->pdata.ldo_ena, ret);
2854 goto err;
2855 }
2856 }
2857
2858 ret = snd_soc_register_codec(&i2c->dev,
2859 &soc_codec_dev_wm8915, wm8915_dai,
2860 ARRAY_SIZE(wm8915_dai));
2861 if (ret < 0)
2862 goto err_gpio;
2863
2864 return ret;
2865
2866err_gpio:
2867 if (wm8915->pdata.ldo_ena > 0)
2868 gpio_free(wm8915->pdata.ldo_ena);
2869err:
2870 kfree(wm8915);
2871
2872 return ret;
2873}
2874
2875static __devexit int wm8915_i2c_remove(struct i2c_client *client)
2876{
2877 struct wm8915_priv *wm8915 = i2c_get_clientdata(client);
2878
2879 snd_soc_unregister_codec(&client->dev);
2880 if (wm8915->pdata.ldo_ena > 0)
2881 gpio_free(wm8915->pdata.ldo_ena);
2882 kfree(i2c_get_clientdata(client));
2883 return 0;
2884}
2885
2886static const struct i2c_device_id wm8915_i2c_id[] = {
2887 { "wm8915", 0 },
2888 { }
2889};
2890MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id);
2891
2892static struct i2c_driver wm8915_i2c_driver = {
2893 .driver = {
2894 .name = "wm8915",
2895 .owner = THIS_MODULE,
2896 },
2897 .probe = wm8915_i2c_probe,
2898 .remove = __devexit_p(wm8915_i2c_remove),
2899 .id_table = wm8915_i2c_id,
2900};
2901
2902static int __init wm8915_modinit(void)
2903{
2904 int ret;
2905
2906 ret = i2c_add_driver(&wm8915_i2c_driver);
2907 if (ret != 0) {
2908 printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n",
2909 ret);
2910 }
2911
2912 return ret;
2913}
2914module_init(wm8915_modinit);
2915
2916static void __exit wm8915_exit(void)
2917{
2918 i2c_del_driver(&wm8915_i2c_driver);
2919}
2920module_exit(wm8915_exit);
2921
2922MODULE_DESCRIPTION("ASoC WM8915 driver");
2923MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2924MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8915.h b/sound/soc/codecs/wm8915.h
new file mode 100644
index 000000000000..200ffd7bf953
--- /dev/null
+++ b/sound/soc/codecs/wm8915.h
@@ -0,0 +1,3717 @@
1/*
2 * wm8915.h - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM8915_H
14#define _WM8915_H
15
16#define WM8915_SYSCLK_MCLK1 1
17#define WM8915_SYSCLK_MCLK2 2
18#define WM8915_SYSCLK_FLL 3
19
20#define WM8915_FLL_MCLK1 1
21#define WM8915_FLL_MCLK2 2
22#define WM8915_FLL_DACLRCLK1 3
23#define WM8915_FLL_BCLK1 4
24
25typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity);
26
27int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
28 wm8915_polarity_fn polarity_cb);
29
30/*
31 * Register values.
32 */
33#define WM8915_SOFTWARE_RESET 0x00
34#define WM8915_POWER_MANAGEMENT_1 0x01
35#define WM8915_POWER_MANAGEMENT_2 0x02
36#define WM8915_POWER_MANAGEMENT_3 0x03
37#define WM8915_POWER_MANAGEMENT_4 0x04
38#define WM8915_POWER_MANAGEMENT_5 0x05
39#define WM8915_POWER_MANAGEMENT_6 0x06
40#define WM8915_POWER_MANAGEMENT_7 0x07
41#define WM8915_POWER_MANAGEMENT_8 0x08
42#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10
43#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11
44#define WM8915_LINE_INPUT_CONTROL 0x12
45#define WM8915_DAC1_HPOUT1_VOLUME 0x15
46#define WM8915_DAC2_HPOUT2_VOLUME 0x16
47#define WM8915_DAC1_LEFT_VOLUME 0x18
48#define WM8915_DAC1_RIGHT_VOLUME 0x19
49#define WM8915_DAC2_LEFT_VOLUME 0x1A
50#define WM8915_DAC2_RIGHT_VOLUME 0x1B
51#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C
52#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D
53#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E
54#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F
55#define WM8915_MICBIAS_1 0x20
56#define WM8915_MICBIAS_2 0x21
57#define WM8915_LDO_1 0x28
58#define WM8915_LDO_2 0x29
59#define WM8915_ACCESSORY_DETECT_MODE_1 0x30
60#define WM8915_ACCESSORY_DETECT_MODE_2 0x31
61#define WM8915_HEADPHONE_DETECT_1 0x34
62#define WM8915_HEADPHONE_DETECT_2 0x35
63#define WM8915_MIC_DETECT_1 0x38
64#define WM8915_MIC_DETECT_2 0x39
65#define WM8915_MIC_DETECT_3 0x3A
66#define WM8915_CHARGE_PUMP_1 0x40
67#define WM8915_CHARGE_PUMP_2 0x41
68#define WM8915_DC_SERVO_1 0x50
69#define WM8915_DC_SERVO_2 0x51
70#define WM8915_DC_SERVO_3 0x52
71#define WM8915_DC_SERVO_5 0x54
72#define WM8915_DC_SERVO_6 0x55
73#define WM8915_DC_SERVO_7 0x56
74#define WM8915_DC_SERVO_READBACK_0 0x57
75#define WM8915_ANALOGUE_HP_1 0x60
76#define WM8915_ANALOGUE_HP_2 0x61
77#define WM8915_CHIP_REVISION 0x100
78#define WM8915_CONTROL_INTERFACE_1 0x101
79#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110
80#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111
81#define WM8915_AIF_CLOCKING_1 0x200
82#define WM8915_AIF_CLOCKING_2 0x201
83#define WM8915_CLOCKING_1 0x208
84#define WM8915_CLOCKING_2 0x209
85#define WM8915_AIF_RATE 0x210
86#define WM8915_FLL_CONTROL_1 0x220
87#define WM8915_FLL_CONTROL_2 0x221
88#define WM8915_FLL_CONTROL_3 0x222
89#define WM8915_FLL_CONTROL_4 0x223
90#define WM8915_FLL_CONTROL_5 0x224
91#define WM8915_FLL_CONTROL_6 0x225
92#define WM8915_FLL_EFS_1 0x226
93#define WM8915_FLL_EFS_2 0x227
94#define WM8915_AIF1_CONTROL 0x300
95#define WM8915_AIF1_BCLK 0x301
96#define WM8915_AIF1_TX_LRCLK_1 0x302
97#define WM8915_AIF1_TX_LRCLK_2 0x303
98#define WM8915_AIF1_RX_LRCLK_1 0x304
99#define WM8915_AIF1_RX_LRCLK_2 0x305
100#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306
101#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307
102#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308
103#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
104#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
105#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
106#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
107#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
108#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
109#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
110#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
111#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
112#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
113#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
114#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
115#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315
116#define WM8915_AIF1TX_TEST 0x31A
117#define WM8915_AIF2_CONTROL 0x320
118#define WM8915_AIF2_BCLK 0x321
119#define WM8915_AIF2_TX_LRCLK_1 0x322
120#define WM8915_AIF2_TX_LRCLK_2 0x323
121#define WM8915_AIF2_RX_LRCLK_1 0x324
122#define WM8915_AIF2_RX_LRCLK_2 0x325
123#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326
124#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327
125#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328
126#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
127#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
128#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
129#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
130#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D
131#define WM8915_AIF2TX_TEST 0x32F
132#define WM8915_DSP1_TX_LEFT_VOLUME 0x400
133#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401
134#define WM8915_DSP1_RX_LEFT_VOLUME 0x402
135#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403
136#define WM8915_DSP1_TX_FILTERS 0x410
137#define WM8915_DSP1_RX_FILTERS_1 0x420
138#define WM8915_DSP1_RX_FILTERS_2 0x421
139#define WM8915_DSP1_DRC_1 0x440
140#define WM8915_DSP1_DRC_2 0x441
141#define WM8915_DSP1_DRC_3 0x442
142#define WM8915_DSP1_DRC_4 0x443
143#define WM8915_DSP1_DRC_5 0x444
144#define WM8915_DSP1_RX_EQ_GAINS_1 0x480
145#define WM8915_DSP1_RX_EQ_GAINS_2 0x481
146#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482
147#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483
148#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484
149#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485
150#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486
151#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487
152#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488
153#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489
154#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A
155#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B
156#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C
157#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D
158#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E
159#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F
160#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490
161#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491
162#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492
163#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493
164#define WM8915_DSP2_TX_LEFT_VOLUME 0x500
165#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501
166#define WM8915_DSP2_RX_LEFT_VOLUME 0x502
167#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503
168#define WM8915_DSP2_TX_FILTERS 0x510
169#define WM8915_DSP2_RX_FILTERS_1 0x520
170#define WM8915_DSP2_RX_FILTERS_2 0x521
171#define WM8915_DSP2_DRC_1 0x540
172#define WM8915_DSP2_DRC_2 0x541
173#define WM8915_DSP2_DRC_3 0x542
174#define WM8915_DSP2_DRC_4 0x543
175#define WM8915_DSP2_DRC_5 0x544
176#define WM8915_DSP2_RX_EQ_GAINS_1 0x580
177#define WM8915_DSP2_RX_EQ_GAINS_2 0x581
178#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582
179#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583
180#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584
181#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585
182#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586
183#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587
184#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588
185#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589
186#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A
187#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B
188#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C
189#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D
190#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E
191#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F
192#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590
193#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591
194#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592
195#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593
196#define WM8915_DAC1_MIXER_VOLUMES 0x600
197#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601
198#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602
199#define WM8915_DAC2_MIXER_VOLUMES 0x603
200#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604
201#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605
202#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606
203#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
204#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608
205#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
206#define WM8915_DSP_TX_MIXER_SELECT 0x60A
207#define WM8915_DAC_SOFTMUTE 0x610
208#define WM8915_OVERSAMPLING 0x620
209#define WM8915_SIDETONE 0x621
210#define WM8915_GPIO_1 0x700
211#define WM8915_GPIO_2 0x701
212#define WM8915_GPIO_3 0x702
213#define WM8915_GPIO_4 0x703
214#define WM8915_GPIO_5 0x704
215#define WM8915_PULL_CONTROL_1 0x720
216#define WM8915_PULL_CONTROL_2 0x721
217#define WM8915_INTERRUPT_STATUS_1 0x730
218#define WM8915_INTERRUPT_STATUS_2 0x731
219#define WM8915_INTERRUPT_RAW_STATUS_2 0x732
220#define WM8915_INTERRUPT_STATUS_1_MASK 0x738
221#define WM8915_INTERRUPT_STATUS_2_MASK 0x739
222#define WM8915_INTERRUPT_CONTROL 0x740
223#define WM8915_LEFT_PDM_SPEAKER 0x800
224#define WM8915_RIGHT_PDM_SPEAKER 0x801
225#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802
226#define WM8915_PDM_SPEAKER_VOLUME 0x803
227#define WM8915_WRITE_SEQUENCER_0 0x3000
228#define WM8915_WRITE_SEQUENCER_1 0x3001
229#define WM8915_WRITE_SEQUENCER_2 0x3002
230#define WM8915_WRITE_SEQUENCER_3 0x3003
231#define WM8915_WRITE_SEQUENCER_4 0x3004
232#define WM8915_WRITE_SEQUENCER_5 0x3005
233#define WM8915_WRITE_SEQUENCER_6 0x3006
234#define WM8915_WRITE_SEQUENCER_7 0x3007
235#define WM8915_WRITE_SEQUENCER_8 0x3008
236#define WM8915_WRITE_SEQUENCER_9 0x3009
237#define WM8915_WRITE_SEQUENCER_10 0x300A
238#define WM8915_WRITE_SEQUENCER_11 0x300B
239#define WM8915_WRITE_SEQUENCER_12 0x300C
240#define WM8915_WRITE_SEQUENCER_13 0x300D
241#define WM8915_WRITE_SEQUENCER_14 0x300E
242#define WM8915_WRITE_SEQUENCER_15 0x300F
243#define WM8915_WRITE_SEQUENCER_16 0x3010
244#define WM8915_WRITE_SEQUENCER_17 0x3011
245#define WM8915_WRITE_SEQUENCER_18 0x3012
246#define WM8915_WRITE_SEQUENCER_19 0x3013
247#define WM8915_WRITE_SEQUENCER_20 0x3014
248#define WM8915_WRITE_SEQUENCER_21 0x3015
249#define WM8915_WRITE_SEQUENCER_22 0x3016
250#define WM8915_WRITE_SEQUENCER_23 0x3017
251#define WM8915_WRITE_SEQUENCER_24 0x3018
252#define WM8915_WRITE_SEQUENCER_25 0x3019
253#define WM8915_WRITE_SEQUENCER_26 0x301A
254#define WM8915_WRITE_SEQUENCER_27 0x301B
255#define WM8915_WRITE_SEQUENCER_28 0x301C
256#define WM8915_WRITE_SEQUENCER_29 0x301D
257#define WM8915_WRITE_SEQUENCER_30 0x301E
258#define WM8915_WRITE_SEQUENCER_31 0x301F
259#define WM8915_WRITE_SEQUENCER_32 0x3020
260#define WM8915_WRITE_SEQUENCER_33 0x3021
261#define WM8915_WRITE_SEQUENCER_34 0x3022
262#define WM8915_WRITE_SEQUENCER_35 0x3023
263#define WM8915_WRITE_SEQUENCER_36 0x3024
264#define WM8915_WRITE_SEQUENCER_37 0x3025
265#define WM8915_WRITE_SEQUENCER_38 0x3026
266#define WM8915_WRITE_SEQUENCER_39 0x3027
267#define WM8915_WRITE_SEQUENCER_40 0x3028
268#define WM8915_WRITE_SEQUENCER_41 0x3029
269#define WM8915_WRITE_SEQUENCER_42 0x302A
270#define WM8915_WRITE_SEQUENCER_43 0x302B
271#define WM8915_WRITE_SEQUENCER_44 0x302C
272#define WM8915_WRITE_SEQUENCER_45 0x302D
273#define WM8915_WRITE_SEQUENCER_46 0x302E
274#define WM8915_WRITE_SEQUENCER_47 0x302F
275#define WM8915_WRITE_SEQUENCER_48 0x3030
276#define WM8915_WRITE_SEQUENCER_49 0x3031
277#define WM8915_WRITE_SEQUENCER_50 0x3032
278#define WM8915_WRITE_SEQUENCER_51 0x3033
279#define WM8915_WRITE_SEQUENCER_52 0x3034
280#define WM8915_WRITE_SEQUENCER_53 0x3035
281#define WM8915_WRITE_SEQUENCER_54 0x3036
282#define WM8915_WRITE_SEQUENCER_55 0x3037
283#define WM8915_WRITE_SEQUENCER_56 0x3038
284#define WM8915_WRITE_SEQUENCER_57 0x3039
285#define WM8915_WRITE_SEQUENCER_58 0x303A
286#define WM8915_WRITE_SEQUENCER_59 0x303B
287#define WM8915_WRITE_SEQUENCER_60 0x303C
288#define WM8915_WRITE_SEQUENCER_61 0x303D
289#define WM8915_WRITE_SEQUENCER_62 0x303E
290#define WM8915_WRITE_SEQUENCER_63 0x303F
291#define WM8915_WRITE_SEQUENCER_64 0x3040
292#define WM8915_WRITE_SEQUENCER_65 0x3041
293#define WM8915_WRITE_SEQUENCER_66 0x3042
294#define WM8915_WRITE_SEQUENCER_67 0x3043
295#define WM8915_WRITE_SEQUENCER_68 0x3044
296#define WM8915_WRITE_SEQUENCER_69 0x3045
297#define WM8915_WRITE_SEQUENCER_70 0x3046
298#define WM8915_WRITE_SEQUENCER_71 0x3047
299#define WM8915_WRITE_SEQUENCER_72 0x3048
300#define WM8915_WRITE_SEQUENCER_73 0x3049
301#define WM8915_WRITE_SEQUENCER_74 0x304A
302#define WM8915_WRITE_SEQUENCER_75 0x304B
303#define WM8915_WRITE_SEQUENCER_76 0x304C
304#define WM8915_WRITE_SEQUENCER_77 0x304D
305#define WM8915_WRITE_SEQUENCER_78 0x304E
306#define WM8915_WRITE_SEQUENCER_79 0x304F
307#define WM8915_WRITE_SEQUENCER_80 0x3050
308#define WM8915_WRITE_SEQUENCER_81 0x3051
309#define WM8915_WRITE_SEQUENCER_82 0x3052
310#define WM8915_WRITE_SEQUENCER_83 0x3053
311#define WM8915_WRITE_SEQUENCER_84 0x3054
312#define WM8915_WRITE_SEQUENCER_85 0x3055
313#define WM8915_WRITE_SEQUENCER_86 0x3056
314#define WM8915_WRITE_SEQUENCER_87 0x3057
315#define WM8915_WRITE_SEQUENCER_88 0x3058
316#define WM8915_WRITE_SEQUENCER_89 0x3059
317#define WM8915_WRITE_SEQUENCER_90 0x305A
318#define WM8915_WRITE_SEQUENCER_91 0x305B
319#define WM8915_WRITE_SEQUENCER_92 0x305C
320#define WM8915_WRITE_SEQUENCER_93 0x305D
321#define WM8915_WRITE_SEQUENCER_94 0x305E
322#define WM8915_WRITE_SEQUENCER_95 0x305F
323#define WM8915_WRITE_SEQUENCER_96 0x3060
324#define WM8915_WRITE_SEQUENCER_97 0x3061
325#define WM8915_WRITE_SEQUENCER_98 0x3062
326#define WM8915_WRITE_SEQUENCER_99 0x3063
327#define WM8915_WRITE_SEQUENCER_100 0x3064
328#define WM8915_WRITE_SEQUENCER_101 0x3065
329#define WM8915_WRITE_SEQUENCER_102 0x3066
330#define WM8915_WRITE_SEQUENCER_103 0x3067
331#define WM8915_WRITE_SEQUENCER_104 0x3068
332#define WM8915_WRITE_SEQUENCER_105 0x3069
333#define WM8915_WRITE_SEQUENCER_106 0x306A
334#define WM8915_WRITE_SEQUENCER_107 0x306B
335#define WM8915_WRITE_SEQUENCER_108 0x306C
336#define WM8915_WRITE_SEQUENCER_109 0x306D
337#define WM8915_WRITE_SEQUENCER_110 0x306E
338#define WM8915_WRITE_SEQUENCER_111 0x306F
339#define WM8915_WRITE_SEQUENCER_112 0x3070
340#define WM8915_WRITE_SEQUENCER_113 0x3071
341#define WM8915_WRITE_SEQUENCER_114 0x3072
342#define WM8915_WRITE_SEQUENCER_115 0x3073
343#define WM8915_WRITE_SEQUENCER_116 0x3074
344#define WM8915_WRITE_SEQUENCER_117 0x3075
345#define WM8915_WRITE_SEQUENCER_118 0x3076
346#define WM8915_WRITE_SEQUENCER_119 0x3077
347#define WM8915_WRITE_SEQUENCER_120 0x3078
348#define WM8915_WRITE_SEQUENCER_121 0x3079
349#define WM8915_WRITE_SEQUENCER_122 0x307A
350#define WM8915_WRITE_SEQUENCER_123 0x307B
351#define WM8915_WRITE_SEQUENCER_124 0x307C
352#define WM8915_WRITE_SEQUENCER_125 0x307D
353#define WM8915_WRITE_SEQUENCER_126 0x307E
354#define WM8915_WRITE_SEQUENCER_127 0x307F
355#define WM8915_WRITE_SEQUENCER_128 0x3080
356#define WM8915_WRITE_SEQUENCER_129 0x3081
357#define WM8915_WRITE_SEQUENCER_130 0x3082
358#define WM8915_WRITE_SEQUENCER_131 0x3083
359#define WM8915_WRITE_SEQUENCER_132 0x3084
360#define WM8915_WRITE_SEQUENCER_133 0x3085
361#define WM8915_WRITE_SEQUENCER_134 0x3086
362#define WM8915_WRITE_SEQUENCER_135 0x3087
363#define WM8915_WRITE_SEQUENCER_136 0x3088
364#define WM8915_WRITE_SEQUENCER_137 0x3089
365#define WM8915_WRITE_SEQUENCER_138 0x308A
366#define WM8915_WRITE_SEQUENCER_139 0x308B
367#define WM8915_WRITE_SEQUENCER_140 0x308C
368#define WM8915_WRITE_SEQUENCER_141 0x308D
369#define WM8915_WRITE_SEQUENCER_142 0x308E
370#define WM8915_WRITE_SEQUENCER_143 0x308F
371#define WM8915_WRITE_SEQUENCER_144 0x3090
372#define WM8915_WRITE_SEQUENCER_145 0x3091
373#define WM8915_WRITE_SEQUENCER_146 0x3092
374#define WM8915_WRITE_SEQUENCER_147 0x3093
375#define WM8915_WRITE_SEQUENCER_148 0x3094
376#define WM8915_WRITE_SEQUENCER_149 0x3095
377#define WM8915_WRITE_SEQUENCER_150 0x3096
378#define WM8915_WRITE_SEQUENCER_151 0x3097
379#define WM8915_WRITE_SEQUENCER_152 0x3098
380#define WM8915_WRITE_SEQUENCER_153 0x3099
381#define WM8915_WRITE_SEQUENCER_154 0x309A
382#define WM8915_WRITE_SEQUENCER_155 0x309B
383#define WM8915_WRITE_SEQUENCER_156 0x309C
384#define WM8915_WRITE_SEQUENCER_157 0x309D
385#define WM8915_WRITE_SEQUENCER_158 0x309E
386#define WM8915_WRITE_SEQUENCER_159 0x309F
387#define WM8915_WRITE_SEQUENCER_160 0x30A0
388#define WM8915_WRITE_SEQUENCER_161 0x30A1
389#define WM8915_WRITE_SEQUENCER_162 0x30A2
390#define WM8915_WRITE_SEQUENCER_163 0x30A3
391#define WM8915_WRITE_SEQUENCER_164 0x30A4
392#define WM8915_WRITE_SEQUENCER_165 0x30A5
393#define WM8915_WRITE_SEQUENCER_166 0x30A6
394#define WM8915_WRITE_SEQUENCER_167 0x30A7
395#define WM8915_WRITE_SEQUENCER_168 0x30A8
396#define WM8915_WRITE_SEQUENCER_169 0x30A9
397#define WM8915_WRITE_SEQUENCER_170 0x30AA
398#define WM8915_WRITE_SEQUENCER_171 0x30AB
399#define WM8915_WRITE_SEQUENCER_172 0x30AC
400#define WM8915_WRITE_SEQUENCER_173 0x30AD
401#define WM8915_WRITE_SEQUENCER_174 0x30AE
402#define WM8915_WRITE_SEQUENCER_175 0x30AF
403#define WM8915_WRITE_SEQUENCER_176 0x30B0
404#define WM8915_WRITE_SEQUENCER_177 0x30B1
405#define WM8915_WRITE_SEQUENCER_178 0x30B2
406#define WM8915_WRITE_SEQUENCER_179 0x30B3
407#define WM8915_WRITE_SEQUENCER_180 0x30B4
408#define WM8915_WRITE_SEQUENCER_181 0x30B5
409#define WM8915_WRITE_SEQUENCER_182 0x30B6
410#define WM8915_WRITE_SEQUENCER_183 0x30B7
411#define WM8915_WRITE_SEQUENCER_184 0x30B8
412#define WM8915_WRITE_SEQUENCER_185 0x30B9
413#define WM8915_WRITE_SEQUENCER_186 0x30BA
414#define WM8915_WRITE_SEQUENCER_187 0x30BB
415#define WM8915_WRITE_SEQUENCER_188 0x30BC
416#define WM8915_WRITE_SEQUENCER_189 0x30BD
417#define WM8915_WRITE_SEQUENCER_190 0x30BE
418#define WM8915_WRITE_SEQUENCER_191 0x30BF
419#define WM8915_WRITE_SEQUENCER_192 0x30C0
420#define WM8915_WRITE_SEQUENCER_193 0x30C1
421#define WM8915_WRITE_SEQUENCER_194 0x30C2
422#define WM8915_WRITE_SEQUENCER_195 0x30C3
423#define WM8915_WRITE_SEQUENCER_196 0x30C4
424#define WM8915_WRITE_SEQUENCER_197 0x30C5
425#define WM8915_WRITE_SEQUENCER_198 0x30C6
426#define WM8915_WRITE_SEQUENCER_199 0x30C7
427#define WM8915_WRITE_SEQUENCER_200 0x30C8
428#define WM8915_WRITE_SEQUENCER_201 0x30C9
429#define WM8915_WRITE_SEQUENCER_202 0x30CA
430#define WM8915_WRITE_SEQUENCER_203 0x30CB
431#define WM8915_WRITE_SEQUENCER_204 0x30CC
432#define WM8915_WRITE_SEQUENCER_205 0x30CD
433#define WM8915_WRITE_SEQUENCER_206 0x30CE
434#define WM8915_WRITE_SEQUENCER_207 0x30CF
435#define WM8915_WRITE_SEQUENCER_208 0x30D0
436#define WM8915_WRITE_SEQUENCER_209 0x30D1
437#define WM8915_WRITE_SEQUENCER_210 0x30D2
438#define WM8915_WRITE_SEQUENCER_211 0x30D3
439#define WM8915_WRITE_SEQUENCER_212 0x30D4
440#define WM8915_WRITE_SEQUENCER_213 0x30D5
441#define WM8915_WRITE_SEQUENCER_214 0x30D6
442#define WM8915_WRITE_SEQUENCER_215 0x30D7
443#define WM8915_WRITE_SEQUENCER_216 0x30D8
444#define WM8915_WRITE_SEQUENCER_217 0x30D9
445#define WM8915_WRITE_SEQUENCER_218 0x30DA
446#define WM8915_WRITE_SEQUENCER_219 0x30DB
447#define WM8915_WRITE_SEQUENCER_220 0x30DC
448#define WM8915_WRITE_SEQUENCER_221 0x30DD
449#define WM8915_WRITE_SEQUENCER_222 0x30DE
450#define WM8915_WRITE_SEQUENCER_223 0x30DF
451#define WM8915_WRITE_SEQUENCER_224 0x30E0
452#define WM8915_WRITE_SEQUENCER_225 0x30E1
453#define WM8915_WRITE_SEQUENCER_226 0x30E2
454#define WM8915_WRITE_SEQUENCER_227 0x30E3
455#define WM8915_WRITE_SEQUENCER_228 0x30E4
456#define WM8915_WRITE_SEQUENCER_229 0x30E5
457#define WM8915_WRITE_SEQUENCER_230 0x30E6
458#define WM8915_WRITE_SEQUENCER_231 0x30E7
459#define WM8915_WRITE_SEQUENCER_232 0x30E8
460#define WM8915_WRITE_SEQUENCER_233 0x30E9
461#define WM8915_WRITE_SEQUENCER_234 0x30EA
462#define WM8915_WRITE_SEQUENCER_235 0x30EB
463#define WM8915_WRITE_SEQUENCER_236 0x30EC
464#define WM8915_WRITE_SEQUENCER_237 0x30ED
465#define WM8915_WRITE_SEQUENCER_238 0x30EE
466#define WM8915_WRITE_SEQUENCER_239 0x30EF
467#define WM8915_WRITE_SEQUENCER_240 0x30F0
468#define WM8915_WRITE_SEQUENCER_241 0x30F1
469#define WM8915_WRITE_SEQUENCER_242 0x30F2
470#define WM8915_WRITE_SEQUENCER_243 0x30F3
471#define WM8915_WRITE_SEQUENCER_244 0x30F4
472#define WM8915_WRITE_SEQUENCER_245 0x30F5
473#define WM8915_WRITE_SEQUENCER_246 0x30F6
474#define WM8915_WRITE_SEQUENCER_247 0x30F7
475#define WM8915_WRITE_SEQUENCER_248 0x30F8
476#define WM8915_WRITE_SEQUENCER_249 0x30F9
477#define WM8915_WRITE_SEQUENCER_250 0x30FA
478#define WM8915_WRITE_SEQUENCER_251 0x30FB
479#define WM8915_WRITE_SEQUENCER_252 0x30FC
480#define WM8915_WRITE_SEQUENCER_253 0x30FD
481#define WM8915_WRITE_SEQUENCER_254 0x30FE
482#define WM8915_WRITE_SEQUENCER_255 0x30FF
483#define WM8915_WRITE_SEQUENCER_256 0x3100
484#define WM8915_WRITE_SEQUENCER_257 0x3101
485#define WM8915_WRITE_SEQUENCER_258 0x3102
486#define WM8915_WRITE_SEQUENCER_259 0x3103
487#define WM8915_WRITE_SEQUENCER_260 0x3104
488#define WM8915_WRITE_SEQUENCER_261 0x3105
489#define WM8915_WRITE_SEQUENCER_262 0x3106
490#define WM8915_WRITE_SEQUENCER_263 0x3107
491#define WM8915_WRITE_SEQUENCER_264 0x3108
492#define WM8915_WRITE_SEQUENCER_265 0x3109
493#define WM8915_WRITE_SEQUENCER_266 0x310A
494#define WM8915_WRITE_SEQUENCER_267 0x310B
495#define WM8915_WRITE_SEQUENCER_268 0x310C
496#define WM8915_WRITE_SEQUENCER_269 0x310D
497#define WM8915_WRITE_SEQUENCER_270 0x310E
498#define WM8915_WRITE_SEQUENCER_271 0x310F
499#define WM8915_WRITE_SEQUENCER_272 0x3110
500#define WM8915_WRITE_SEQUENCER_273 0x3111
501#define WM8915_WRITE_SEQUENCER_274 0x3112
502#define WM8915_WRITE_SEQUENCER_275 0x3113
503#define WM8915_WRITE_SEQUENCER_276 0x3114
504#define WM8915_WRITE_SEQUENCER_277 0x3115
505#define WM8915_WRITE_SEQUENCER_278 0x3116
506#define WM8915_WRITE_SEQUENCER_279 0x3117
507#define WM8915_WRITE_SEQUENCER_280 0x3118
508#define WM8915_WRITE_SEQUENCER_281 0x3119
509#define WM8915_WRITE_SEQUENCER_282 0x311A
510#define WM8915_WRITE_SEQUENCER_283 0x311B
511#define WM8915_WRITE_SEQUENCER_284 0x311C
512#define WM8915_WRITE_SEQUENCER_285 0x311D
513#define WM8915_WRITE_SEQUENCER_286 0x311E
514#define WM8915_WRITE_SEQUENCER_287 0x311F
515#define WM8915_WRITE_SEQUENCER_288 0x3120
516#define WM8915_WRITE_SEQUENCER_289 0x3121
517#define WM8915_WRITE_SEQUENCER_290 0x3122
518#define WM8915_WRITE_SEQUENCER_291 0x3123
519#define WM8915_WRITE_SEQUENCER_292 0x3124
520#define WM8915_WRITE_SEQUENCER_293 0x3125
521#define WM8915_WRITE_SEQUENCER_294 0x3126
522#define WM8915_WRITE_SEQUENCER_295 0x3127
523#define WM8915_WRITE_SEQUENCER_296 0x3128
524#define WM8915_WRITE_SEQUENCER_297 0x3129
525#define WM8915_WRITE_SEQUENCER_298 0x312A
526#define WM8915_WRITE_SEQUENCER_299 0x312B
527#define WM8915_WRITE_SEQUENCER_300 0x312C
528#define WM8915_WRITE_SEQUENCER_301 0x312D
529#define WM8915_WRITE_SEQUENCER_302 0x312E
530#define WM8915_WRITE_SEQUENCER_303 0x312F
531#define WM8915_WRITE_SEQUENCER_304 0x3130
532#define WM8915_WRITE_SEQUENCER_305 0x3131
533#define WM8915_WRITE_SEQUENCER_306 0x3132
534#define WM8915_WRITE_SEQUENCER_307 0x3133
535#define WM8915_WRITE_SEQUENCER_308 0x3134
536#define WM8915_WRITE_SEQUENCER_309 0x3135
537#define WM8915_WRITE_SEQUENCER_310 0x3136
538#define WM8915_WRITE_SEQUENCER_311 0x3137
539#define WM8915_WRITE_SEQUENCER_312 0x3138
540#define WM8915_WRITE_SEQUENCER_313 0x3139
541#define WM8915_WRITE_SEQUENCER_314 0x313A
542#define WM8915_WRITE_SEQUENCER_315 0x313B
543#define WM8915_WRITE_SEQUENCER_316 0x313C
544#define WM8915_WRITE_SEQUENCER_317 0x313D
545#define WM8915_WRITE_SEQUENCER_318 0x313E
546#define WM8915_WRITE_SEQUENCER_319 0x313F
547#define WM8915_WRITE_SEQUENCER_320 0x3140
548#define WM8915_WRITE_SEQUENCER_321 0x3141
549#define WM8915_WRITE_SEQUENCER_322 0x3142
550#define WM8915_WRITE_SEQUENCER_323 0x3143
551#define WM8915_WRITE_SEQUENCER_324 0x3144
552#define WM8915_WRITE_SEQUENCER_325 0x3145
553#define WM8915_WRITE_SEQUENCER_326 0x3146
554#define WM8915_WRITE_SEQUENCER_327 0x3147
555#define WM8915_WRITE_SEQUENCER_328 0x3148
556#define WM8915_WRITE_SEQUENCER_329 0x3149
557#define WM8915_WRITE_SEQUENCER_330 0x314A
558#define WM8915_WRITE_SEQUENCER_331 0x314B
559#define WM8915_WRITE_SEQUENCER_332 0x314C
560#define WM8915_WRITE_SEQUENCER_333 0x314D
561#define WM8915_WRITE_SEQUENCER_334 0x314E
562#define WM8915_WRITE_SEQUENCER_335 0x314F
563#define WM8915_WRITE_SEQUENCER_336 0x3150
564#define WM8915_WRITE_SEQUENCER_337 0x3151
565#define WM8915_WRITE_SEQUENCER_338 0x3152
566#define WM8915_WRITE_SEQUENCER_339 0x3153
567#define WM8915_WRITE_SEQUENCER_340 0x3154
568#define WM8915_WRITE_SEQUENCER_341 0x3155
569#define WM8915_WRITE_SEQUENCER_342 0x3156
570#define WM8915_WRITE_SEQUENCER_343 0x3157
571#define WM8915_WRITE_SEQUENCER_344 0x3158
572#define WM8915_WRITE_SEQUENCER_345 0x3159
573#define WM8915_WRITE_SEQUENCER_346 0x315A
574#define WM8915_WRITE_SEQUENCER_347 0x315B
575#define WM8915_WRITE_SEQUENCER_348 0x315C
576#define WM8915_WRITE_SEQUENCER_349 0x315D
577#define WM8915_WRITE_SEQUENCER_350 0x315E
578#define WM8915_WRITE_SEQUENCER_351 0x315F
579#define WM8915_WRITE_SEQUENCER_352 0x3160
580#define WM8915_WRITE_SEQUENCER_353 0x3161
581#define WM8915_WRITE_SEQUENCER_354 0x3162
582#define WM8915_WRITE_SEQUENCER_355 0x3163
583#define WM8915_WRITE_SEQUENCER_356 0x3164
584#define WM8915_WRITE_SEQUENCER_357 0x3165
585#define WM8915_WRITE_SEQUENCER_358 0x3166
586#define WM8915_WRITE_SEQUENCER_359 0x3167
587#define WM8915_WRITE_SEQUENCER_360 0x3168
588#define WM8915_WRITE_SEQUENCER_361 0x3169
589#define WM8915_WRITE_SEQUENCER_362 0x316A
590#define WM8915_WRITE_SEQUENCER_363 0x316B
591#define WM8915_WRITE_SEQUENCER_364 0x316C
592#define WM8915_WRITE_SEQUENCER_365 0x316D
593#define WM8915_WRITE_SEQUENCER_366 0x316E
594#define WM8915_WRITE_SEQUENCER_367 0x316F
595#define WM8915_WRITE_SEQUENCER_368 0x3170
596#define WM8915_WRITE_SEQUENCER_369 0x3171
597#define WM8915_WRITE_SEQUENCER_370 0x3172
598#define WM8915_WRITE_SEQUENCER_371 0x3173
599#define WM8915_WRITE_SEQUENCER_372 0x3174
600#define WM8915_WRITE_SEQUENCER_373 0x3175
601#define WM8915_WRITE_SEQUENCER_374 0x3176
602#define WM8915_WRITE_SEQUENCER_375 0x3177
603#define WM8915_WRITE_SEQUENCER_376 0x3178
604#define WM8915_WRITE_SEQUENCER_377 0x3179
605#define WM8915_WRITE_SEQUENCER_378 0x317A
606#define WM8915_WRITE_SEQUENCER_379 0x317B
607#define WM8915_WRITE_SEQUENCER_380 0x317C
608#define WM8915_WRITE_SEQUENCER_381 0x317D
609#define WM8915_WRITE_SEQUENCER_382 0x317E
610#define WM8915_WRITE_SEQUENCER_383 0x317F
611#define WM8915_WRITE_SEQUENCER_384 0x3180
612#define WM8915_WRITE_SEQUENCER_385 0x3181
613#define WM8915_WRITE_SEQUENCER_386 0x3182
614#define WM8915_WRITE_SEQUENCER_387 0x3183
615#define WM8915_WRITE_SEQUENCER_388 0x3184
616#define WM8915_WRITE_SEQUENCER_389 0x3185
617#define WM8915_WRITE_SEQUENCER_390 0x3186
618#define WM8915_WRITE_SEQUENCER_391 0x3187
619#define WM8915_WRITE_SEQUENCER_392 0x3188
620#define WM8915_WRITE_SEQUENCER_393 0x3189
621#define WM8915_WRITE_SEQUENCER_394 0x318A
622#define WM8915_WRITE_SEQUENCER_395 0x318B
623#define WM8915_WRITE_SEQUENCER_396 0x318C
624#define WM8915_WRITE_SEQUENCER_397 0x318D
625#define WM8915_WRITE_SEQUENCER_398 0x318E
626#define WM8915_WRITE_SEQUENCER_399 0x318F
627#define WM8915_WRITE_SEQUENCER_400 0x3190
628#define WM8915_WRITE_SEQUENCER_401 0x3191
629#define WM8915_WRITE_SEQUENCER_402 0x3192
630#define WM8915_WRITE_SEQUENCER_403 0x3193
631#define WM8915_WRITE_SEQUENCER_404 0x3194
632#define WM8915_WRITE_SEQUENCER_405 0x3195
633#define WM8915_WRITE_SEQUENCER_406 0x3196
634#define WM8915_WRITE_SEQUENCER_407 0x3197
635#define WM8915_WRITE_SEQUENCER_408 0x3198
636#define WM8915_WRITE_SEQUENCER_409 0x3199
637#define WM8915_WRITE_SEQUENCER_410 0x319A
638#define WM8915_WRITE_SEQUENCER_411 0x319B
639#define WM8915_WRITE_SEQUENCER_412 0x319C
640#define WM8915_WRITE_SEQUENCER_413 0x319D
641#define WM8915_WRITE_SEQUENCER_414 0x319E
642#define WM8915_WRITE_SEQUENCER_415 0x319F
643#define WM8915_WRITE_SEQUENCER_416 0x31A0
644#define WM8915_WRITE_SEQUENCER_417 0x31A1
645#define WM8915_WRITE_SEQUENCER_418 0x31A2
646#define WM8915_WRITE_SEQUENCER_419 0x31A3
647#define WM8915_WRITE_SEQUENCER_420 0x31A4
648#define WM8915_WRITE_SEQUENCER_421 0x31A5
649#define WM8915_WRITE_SEQUENCER_422 0x31A6
650#define WM8915_WRITE_SEQUENCER_423 0x31A7
651#define WM8915_WRITE_SEQUENCER_424 0x31A8
652#define WM8915_WRITE_SEQUENCER_425 0x31A9
653#define WM8915_WRITE_SEQUENCER_426 0x31AA
654#define WM8915_WRITE_SEQUENCER_427 0x31AB
655#define WM8915_WRITE_SEQUENCER_428 0x31AC
656#define WM8915_WRITE_SEQUENCER_429 0x31AD
657#define WM8915_WRITE_SEQUENCER_430 0x31AE
658#define WM8915_WRITE_SEQUENCER_431 0x31AF
659#define WM8915_WRITE_SEQUENCER_432 0x31B0
660#define WM8915_WRITE_SEQUENCER_433 0x31B1
661#define WM8915_WRITE_SEQUENCER_434 0x31B2
662#define WM8915_WRITE_SEQUENCER_435 0x31B3
663#define WM8915_WRITE_SEQUENCER_436 0x31B4
664#define WM8915_WRITE_SEQUENCER_437 0x31B5
665#define WM8915_WRITE_SEQUENCER_438 0x31B6
666#define WM8915_WRITE_SEQUENCER_439 0x31B7
667#define WM8915_WRITE_SEQUENCER_440 0x31B8
668#define WM8915_WRITE_SEQUENCER_441 0x31B9
669#define WM8915_WRITE_SEQUENCER_442 0x31BA
670#define WM8915_WRITE_SEQUENCER_443 0x31BB
671#define WM8915_WRITE_SEQUENCER_444 0x31BC
672#define WM8915_WRITE_SEQUENCER_445 0x31BD
673#define WM8915_WRITE_SEQUENCER_446 0x31BE
674#define WM8915_WRITE_SEQUENCER_447 0x31BF
675#define WM8915_WRITE_SEQUENCER_448 0x31C0
676#define WM8915_WRITE_SEQUENCER_449 0x31C1
677#define WM8915_WRITE_SEQUENCER_450 0x31C2
678#define WM8915_WRITE_SEQUENCER_451 0x31C3
679#define WM8915_WRITE_SEQUENCER_452 0x31C4
680#define WM8915_WRITE_SEQUENCER_453 0x31C5
681#define WM8915_WRITE_SEQUENCER_454 0x31C6
682#define WM8915_WRITE_SEQUENCER_455 0x31C7
683#define WM8915_WRITE_SEQUENCER_456 0x31C8
684#define WM8915_WRITE_SEQUENCER_457 0x31C9
685#define WM8915_WRITE_SEQUENCER_458 0x31CA
686#define WM8915_WRITE_SEQUENCER_459 0x31CB
687#define WM8915_WRITE_SEQUENCER_460 0x31CC
688#define WM8915_WRITE_SEQUENCER_461 0x31CD
689#define WM8915_WRITE_SEQUENCER_462 0x31CE
690#define WM8915_WRITE_SEQUENCER_463 0x31CF
691#define WM8915_WRITE_SEQUENCER_464 0x31D0
692#define WM8915_WRITE_SEQUENCER_465 0x31D1
693#define WM8915_WRITE_SEQUENCER_466 0x31D2
694#define WM8915_WRITE_SEQUENCER_467 0x31D3
695#define WM8915_WRITE_SEQUENCER_468 0x31D4
696#define WM8915_WRITE_SEQUENCER_469 0x31D5
697#define WM8915_WRITE_SEQUENCER_470 0x31D6
698#define WM8915_WRITE_SEQUENCER_471 0x31D7
699#define WM8915_WRITE_SEQUENCER_472 0x31D8
700#define WM8915_WRITE_SEQUENCER_473 0x31D9
701#define WM8915_WRITE_SEQUENCER_474 0x31DA
702#define WM8915_WRITE_SEQUENCER_475 0x31DB
703#define WM8915_WRITE_SEQUENCER_476 0x31DC
704#define WM8915_WRITE_SEQUENCER_477 0x31DD
705#define WM8915_WRITE_SEQUENCER_478 0x31DE
706#define WM8915_WRITE_SEQUENCER_479 0x31DF
707#define WM8915_WRITE_SEQUENCER_480 0x31E0
708#define WM8915_WRITE_SEQUENCER_481 0x31E1
709#define WM8915_WRITE_SEQUENCER_482 0x31E2
710#define WM8915_WRITE_SEQUENCER_483 0x31E3
711#define WM8915_WRITE_SEQUENCER_484 0x31E4
712#define WM8915_WRITE_SEQUENCER_485 0x31E5
713#define WM8915_WRITE_SEQUENCER_486 0x31E6
714#define WM8915_WRITE_SEQUENCER_487 0x31E7
715#define WM8915_WRITE_SEQUENCER_488 0x31E8
716#define WM8915_WRITE_SEQUENCER_489 0x31E9
717#define WM8915_WRITE_SEQUENCER_490 0x31EA
718#define WM8915_WRITE_SEQUENCER_491 0x31EB
719#define WM8915_WRITE_SEQUENCER_492 0x31EC
720#define WM8915_WRITE_SEQUENCER_493 0x31ED
721#define WM8915_WRITE_SEQUENCER_494 0x31EE
722#define WM8915_WRITE_SEQUENCER_495 0x31EF
723#define WM8915_WRITE_SEQUENCER_496 0x31F0
724#define WM8915_WRITE_SEQUENCER_497 0x31F1
725#define WM8915_WRITE_SEQUENCER_498 0x31F2
726#define WM8915_WRITE_SEQUENCER_499 0x31F3
727#define WM8915_WRITE_SEQUENCER_500 0x31F4
728#define WM8915_WRITE_SEQUENCER_501 0x31F5
729#define WM8915_WRITE_SEQUENCER_502 0x31F6
730#define WM8915_WRITE_SEQUENCER_503 0x31F7
731#define WM8915_WRITE_SEQUENCER_504 0x31F8
732#define WM8915_WRITE_SEQUENCER_505 0x31F9
733#define WM8915_WRITE_SEQUENCER_506 0x31FA
734#define WM8915_WRITE_SEQUENCER_507 0x31FB
735#define WM8915_WRITE_SEQUENCER_508 0x31FC
736#define WM8915_WRITE_SEQUENCER_509 0x31FD
737#define WM8915_WRITE_SEQUENCER_510 0x31FE
738#define WM8915_WRITE_SEQUENCER_511 0x31FF
739
740#define WM8915_REGISTER_COUNT 706
741#define WM8915_MAX_REGISTER 0x31FF
742
743/*
744 * Field Definitions.
745 */
746
747/*
748 * R0 (0x00) - Software Reset
749 */
750#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
751#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
752#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
753
754/*
755 * R1 (0x01) - Power Management (1)
756 */
757#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */
758#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
759#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
760#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
761#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */
762#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
763#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
764#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
765#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
766#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
767#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
768#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
769#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
770#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
771#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
772#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
773#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
774#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
775#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
776#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
777#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
778#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
779#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
780#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
781#define WM8915_BG_ENA 0x0001 /* BG_ENA */
782#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */
783#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */
784#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */
785
786/*
787 * R2 (0x02) - Power Management (2)
788 */
789#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */
790#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
791#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
792#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
793#define WM8915_INL_ENA 0x0020 /* INL_ENA */
794#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */
795#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */
796#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */
797#define WM8915_INR_ENA 0x0010 /* INR_ENA */
798#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */
799#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */
800#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */
801#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */
802#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
803#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
804#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
805
806/*
807 * R3 (0x03) - Power Management (3)
808 */
809#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
810#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
811#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
812#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
813#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
814#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
815#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
816#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
817#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
818#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
819#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
820#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
821#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
822#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
823#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
824#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
825#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
826#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
827#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
828#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
829#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
830#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
831#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
832#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
833#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
834#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
835#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
836#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
837#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
838#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
839#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
840#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
841#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */
842#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
843#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
844#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
845#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */
846#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
847#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
848#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
849
850/*
851 * R4 (0x04) - Power Management (4)
852 */
853#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
854#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
855#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
856#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
857#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
858#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
859#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
860#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
861#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
862#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
863#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
864#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
865#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
866#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
867#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
868#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
869#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
870#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
871#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
872#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
873#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
874#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
875#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
876#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
877#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
878#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
879#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
880#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
881#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
882#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
883#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
884#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
885
886/*
887 * R5 (0x05) - Power Management (5)
888 */
889#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
890#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
891#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
892#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
893#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
894#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
895#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
896#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
897#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
898#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
899#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
900#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
901#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
902#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
903#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
904#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
905#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */
906#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
907#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
908#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
909#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */
910#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
911#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
912#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
913#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */
914#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
915#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
916#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
917#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */
918#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
919#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
920#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
921
922/*
923 * R6 (0x06) - Power Management (6)
924 */
925#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
926#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
927#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
928#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
929#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
930#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
931#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
932#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
933#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
934#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
935#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
936#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
937#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
938#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
939#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
940#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
941#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
942#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
943#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
944#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
945#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
946#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
947#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
948#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
949#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
950#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
951#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
952#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
953#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
954#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
955#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
956#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
957
958/*
959 * R7 (0x07) - Power Management (7)
960 */
961#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */
962#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
963#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
964#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
965#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */
966#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
967#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
968#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
969#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
970#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
971#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
972#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
973#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
974#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
975#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
976#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
977#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
978#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
979#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
980#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
981#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
982#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
983#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
984#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
985#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
986#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
987#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
988#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
989#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
990#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
991
992/*
993 * R8 (0x08) - Power Management (8)
994 */
995#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
996#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
997#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
998#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
999#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
1000#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
1001#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
1002#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
1003#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
1004#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
1005#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
1006
1007/*
1008 * R16 (0x10) - Left Line Input Volume
1009 */
1010#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1011#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1012#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1013#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1014#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */
1015#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
1016#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
1017#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
1018#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
1019#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
1020#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
1021
1022/*
1023 * R17 (0x11) - Right Line Input Volume
1024 */
1025#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1026#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1027#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1028#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1029#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */
1030#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
1031#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
1032#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
1033#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
1034#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
1035#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
1036
1037/*
1038 * R18 (0x12) - Line Input Control
1039 */
1040#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
1041#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
1042#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
1043#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
1044#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
1045#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
1046
1047/*
1048 * R21 (0x15) - DAC1 HPOUT1 Volume
1049 */
1050#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
1051#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1052#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1053#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
1054#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
1055#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
1056
1057/*
1058 * R22 (0x16) - DAC2 HPOUT2 Volume
1059 */
1060#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
1061#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1062#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1063#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
1064#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
1065#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
1066
1067/*
1068 * R24 (0x18) - DAC1 Left Volume
1069 */
1070#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
1071#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
1072#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
1073#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
1074#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1075#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1076#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1077#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1078#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
1079#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
1080#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
1081
1082/*
1083 * R25 (0x19) - DAC1 Right Volume
1084 */
1085#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
1086#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
1087#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
1088#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
1089#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1090#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1091#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1092#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1093#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
1094#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
1095#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
1096
1097/*
1098 * R26 (0x1A) - DAC2 Left Volume
1099 */
1100#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
1101#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
1102#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
1103#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
1104#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1105#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1106#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1107#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1108#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
1109#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
1110#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
1111
1112/*
1113 * R27 (0x1B) - DAC2 Right Volume
1114 */
1115#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
1116#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
1117#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
1118#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
1119#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1120#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1121#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1122#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1123#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
1124#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
1125#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
1126
1127/*
1128 * R28 (0x1C) - Output1 Left Volume
1129 */
1130#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1131#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1132#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1133#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1134#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
1135#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
1136#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
1137#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1138#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
1139#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
1140#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
1141
1142/*
1143 * R29 (0x1D) - Output1 Right Volume
1144 */
1145#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1146#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1147#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1148#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1149#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
1150#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
1151#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
1152#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1153#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
1154#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
1155#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
1156
1157/*
1158 * R30 (0x1E) - Output2 Left Volume
1159 */
1160#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1161#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1162#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1163#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1164#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
1165#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
1166#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
1167#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
1168#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
1169#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
1170#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
1171
1172/*
1173 * R31 (0x1F) - Output2 Right Volume
1174 */
1175#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1176#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1177#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1178#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1179#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
1180#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
1181#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
1182#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
1183#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
1184#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
1185#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
1186
1187/*
1188 * R32 (0x20) - MICBIAS (1)
1189 */
1190#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */
1191#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1192#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1193#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1194#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */
1195#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
1196#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
1197#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1198#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
1199#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
1200#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
1201#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1202#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1203#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1204#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1205
1206/*
1207 * R33 (0x21) - MICBIAS (2)
1208 */
1209#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */
1210#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1211#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1212#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1213#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */
1214#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
1215#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
1216#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1217#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
1218#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
1219#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
1220#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1221#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1222#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1223#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1224
1225/*
1226 * R40 (0x28) - LDO 1
1227 */
1228#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */
1229#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
1230#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
1231#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
1232#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
1233#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
1234#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
1235#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1236#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1237#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1238#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1239
1240/*
1241 * R41 (0x29) - LDO 2
1242 */
1243#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */
1244#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
1245#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
1246#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
1247#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
1248#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
1249#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
1250#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1251#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1252#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1253#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1254
1255/*
1256 * R48 (0x30) - Accessory Detect Mode 1
1257 */
1258#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
1259#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
1260#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
1261
1262/*
1263 * R49 (0x31) - Accessory Detect Mode 2
1264 */
1265#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
1266#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
1267#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
1268#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
1269#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */
1270#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */
1271#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */
1272#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */
1273#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
1274#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
1275#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
1276#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
1277
1278/*
1279 * R52 (0x34) - Headphone Detect 1
1280 */
1281#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
1282#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
1283#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
1284#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
1285#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
1286#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
1287#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
1288#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
1289#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
1290#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
1291#define WM8915_HP_POLL 0x0001 /* HP_POLL */
1292#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */
1293#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */
1294#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */
1295
1296/*
1297 * R53 (0x35) - Headphone Detect 2
1298 */
1299#define WM8915_HP_DONE 0x0080 /* HP_DONE */
1300#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */
1301#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */
1302#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */
1303#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1304#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1305#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1306
1307/*
1308 * R56 (0x38) - Mic Detect 1
1309 */
1310#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
1311#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
1312#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
1313#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
1314#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
1315#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
1316#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */
1317#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
1318#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
1319#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
1320#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */
1321#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */
1322#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */
1323#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */
1324
1325/*
1326 * R57 (0x39) - Mic Detect 2
1327 */
1328#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
1329#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
1330#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
1331
1332/*
1333 * R58 (0x3A) - Mic Detect 3
1334 */
1335#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
1336#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
1337#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
1338#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */
1339#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */
1340#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */
1341#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */
1342#define WM8915_MICD_STS 0x0001 /* MICD_STS */
1343#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */
1344#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */
1345#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */
1346
1347/*
1348 * R64 (0x40) - Charge Pump (1)
1349 */
1350#define WM8915_CP_ENA 0x8000 /* CP_ENA */
1351#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */
1352#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */
1353#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */
1354
1355/*
1356 * R65 (0x41) - Charge Pump (2)
1357 */
1358#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */
1359#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */
1360#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */
1361#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */
1362
1363/*
1364 * R80 (0x50) - DC Servo (1)
1365 */
1366#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
1367#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
1368#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
1369#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
1370#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
1371#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
1372#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
1373#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
1374#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1375#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1376#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1377#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1378#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1379#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1380#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1381#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1382
1383/*
1384 * R81 (0x51) - DC Servo (2)
1385 */
1386#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
1387#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
1388#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
1389#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
1390#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
1391#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
1392#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
1393#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
1394#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1395#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1396#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1397#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1398#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1399#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1400#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1401#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1402#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
1403#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
1404#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
1405#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
1406#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
1407#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
1408#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
1409#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
1410#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1411#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1412#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1413#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1414#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1415#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1416#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1417#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1418#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
1419#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
1420#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
1421#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
1422#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
1423#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
1424#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
1425#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
1426#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1427#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1428#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1429#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1430#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1431#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1432#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1433#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1434#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
1435#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
1436#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
1437#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
1438#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
1439#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
1440#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
1441#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
1442#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
1443#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
1444#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
1445#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1446#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
1447#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
1448#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
1449#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1450
1451/*
1452 * R82 (0x52) - DC Servo (3)
1453 */
1454#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
1455#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
1456#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
1457#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1458#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1459#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1460
1461/*
1462 * R84 (0x54) - DC Servo (5)
1463 */
1464#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
1465#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
1466#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
1467#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
1468#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
1469#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
1470
1471/*
1472 * R85 (0x55) - DC Servo (6)
1473 */
1474#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
1475#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1476#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1477#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
1478#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
1479#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
1480
1481/*
1482 * R86 (0x56) - DC Servo (7)
1483 */
1484#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1485#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1486#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1487#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1488#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1489#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1490
1491/*
1492 * R87 (0x57) - DC Servo Readback 0
1493 */
1494#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
1495#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
1496#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
1497#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
1498#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1499#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1500#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
1501#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
1502#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
1503
1504/*
1505 * R96 (0x60) - Analogue HP (1)
1506 */
1507#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1508#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1509#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1510#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1511#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1512#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1513#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1514#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1515#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1516#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1517#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1518#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1519#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1520#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1521#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1522#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1523#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1524#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1525#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1526#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1527#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1528#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1529#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1530#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1531
1532/*
1533 * R97 (0x61) - Analogue HP (2)
1534 */
1535#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
1536#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
1537#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
1538#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
1539#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
1540#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
1541#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
1542#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
1543#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
1544#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
1545#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
1546#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
1547#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
1548#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
1549#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
1550#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
1551#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
1552#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
1553#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
1554#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
1555#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
1556#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
1557#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
1558#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
1559
1560/*
1561 * R256 (0x100) - Chip Revision
1562 */
1563#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1564#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1565#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1566
1567/*
1568 * R257 (0x101) - Control Interface (1)
1569 */
1570#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */
1571#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1572#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */
1573#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */
1574
1575/*
1576 * R272 (0x110) - Write Sequencer Ctrl (1)
1577 */
1578#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1579#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1580#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1581#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1582#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1583#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1584#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1585#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1586#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */
1587#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1588#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */
1589#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */
1590#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1591#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1592#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1593
1594/*
1595 * R273 (0x111) - Write Sequencer Ctrl (2)
1596 */
1597#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
1598#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
1599#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
1600#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1601#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
1602#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
1603#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
1604
1605/*
1606 * R512 (0x200) - AIF Clocking (1)
1607 */
1608#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
1609#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
1610#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
1611#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */
1612#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
1613#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
1614#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
1615#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
1616#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
1617#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
1618#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
1619#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
1620#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
1621#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
1622#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
1623
1624/*
1625 * R513 (0x201) - AIF Clocking (2)
1626 */
1627#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
1628#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
1629#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
1630#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
1631#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
1632#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
1633
1634/*
1635 * R520 (0x208) - Clocking (1)
1636 */
1637#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */
1638#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
1639#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
1640#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
1641#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */
1642#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
1643#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
1644#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1645#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
1646#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
1647#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
1648#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
1649#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
1650#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
1651#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
1652#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
1653
1654/*
1655 * R521 (0x209) - Clocking (2)
1656 */
1657#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
1658#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
1659#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
1660#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
1661#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
1662#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
1663#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
1664#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
1665#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
1666
1667/*
1668 * R528 (0x210) - AIF Rate
1669 */
1670#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
1671#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
1672#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
1673#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
1674
1675/*
1676 * R544 (0x220) - FLL Control (1)
1677 */
1678#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1679#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1680#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1681#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1682#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */
1683#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1684#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */
1685#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */
1686
1687/*
1688 * R545 (0x221) - FLL Control (2)
1689 */
1690#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1691#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1692#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1693#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1694#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1695#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1696
1697/*
1698 * R546 (0x222) - FLL Control (3)
1699 */
1700#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
1701#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
1702#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
1703
1704/*
1705 * R547 (0x223) - FLL Control (4)
1706 */
1707#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1708#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1709#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1710#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
1711#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
1712#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
1713
1714/*
1715 * R548 (0x224) - FLL Control (5)
1716 */
1717#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
1718#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
1719#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
1720#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
1721#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
1722#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
1723#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1724#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
1725#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
1726#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
1727#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
1728#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
1729#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
1730#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
1731#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
1732#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
1733#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
1734
1735/*
1736 * R549 (0x225) - FLL Control (6)
1737 */
1738#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
1739#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1740#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1741#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
1742#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
1743#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
1744#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
1745
1746/*
1747 * R550 (0x226) - FLL EFS 1
1748 */
1749#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
1750#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
1751#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
1752
1753/*
1754 * R551 (0x227) - FLL EFS 2
1755 */
1756#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
1757#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
1758#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
1759#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
1760#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
1761#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
1762#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
1763
1764/*
1765 * R768 (0x300) - AIF1 Control
1766 */
1767#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */
1768#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
1769#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
1770#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1771#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
1772#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
1773#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
1774
1775/*
1776 * R769 (0x301) - AIF1 BCLK
1777 */
1778#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
1779#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
1780#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
1781#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1782#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
1783#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
1784#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
1785#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
1786#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
1787#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
1788#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
1789#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
1790#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
1791#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
1792#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
1793
1794/*
1795 * R770 (0x302) - AIF1 TX LRCLK(1)
1796 */
1797#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
1798#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
1799#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
1800
1801/*
1802 * R771 (0x303) - AIF1 TX LRCLK(2)
1803 */
1804#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
1805#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
1806#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
1807#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
1808#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
1809#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
1810#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
1811#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
1812#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
1813#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
1814#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
1815#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
1816#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
1817#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
1818#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
1819#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
1820
1821/*
1822 * R772 (0x304) - AIF1 RX LRCLK(1)
1823 */
1824#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
1825#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
1826#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
1827
1828/*
1829 * R773 (0x305) - AIF1 RX LRCLK(2)
1830 */
1831#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
1832#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
1833#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
1834#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
1835#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
1836#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
1837#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
1838#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
1839#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
1840#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
1841#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
1842#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
1843
1844/*
1845 * R774 (0x306) - AIF1TX Data Configuration (1)
1846 */
1847#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
1848#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
1849#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
1850#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
1851#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
1852#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
1853
1854/*
1855 * R775 (0x307) - AIF1TX Data Configuration (2)
1856 */
1857#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
1858#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
1859#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
1860#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
1861
1862/*
1863 * R776 (0x308) - AIF1RX Data Configuration
1864 */
1865#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
1866#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
1867#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
1868#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
1869#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
1870#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
1871
1872/*
1873 * R777 (0x309) - AIF1TX Channel 0 Configuration
1874 */
1875#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1876#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1877#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
1878#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
1879#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
1880#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
1881#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
1882#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1883#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1884#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1885#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1886#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1887#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1888
1889/*
1890 * R778 (0x30A) - AIF1TX Channel 1 Configuration
1891 */
1892#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1893#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1894#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
1895#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
1896#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
1897#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
1898#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
1899#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1900#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1901#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1902#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1903#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1904#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1905
1906/*
1907 * R779 (0x30B) - AIF1TX Channel 2 Configuration
1908 */
1909#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1910#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1911#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
1912#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
1913#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
1914#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
1915#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
1916#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1917#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1918#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1919#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1920#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1921#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1922
1923/*
1924 * R780 (0x30C) - AIF1TX Channel 3 Configuration
1925 */
1926#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1927#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1928#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
1929#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
1930#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
1931#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
1932#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
1933#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1934#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1935#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1936#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1937#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1938#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1939
1940/*
1941 * R781 (0x30D) - AIF1TX Channel 4 Configuration
1942 */
1943#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1944#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1945#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
1946#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
1947#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
1948#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
1949#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
1950#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1951#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1952#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1953#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1954#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1955#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1956
1957/*
1958 * R782 (0x30E) - AIF1TX Channel 5 Configuration
1959 */
1960#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1961#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1962#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
1963#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
1964#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
1965#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
1966#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
1967#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1968#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1969#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1970#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1971#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1972#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1973
1974/*
1975 * R783 (0x30F) - AIF1RX Channel 0 Configuration
1976 */
1977#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1978#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1979#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
1980#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
1981#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
1982#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
1983#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
1984#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1985#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1986#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1987#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1988#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1989#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1990
1991/*
1992 * R784 (0x310) - AIF1RX Channel 1 Configuration
1993 */
1994#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1995#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1996#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
1997#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
1998#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
1999#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
2000#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
2001#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2002#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2003#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2004#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2005#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2006#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2007
2008/*
2009 * R785 (0x311) - AIF1RX Channel 2 Configuration
2010 */
2011#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2012#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2013#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
2014#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
2015#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
2016#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
2017#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
2018#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2019#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2020#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2021#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2022#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2023#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2024
2025/*
2026 * R786 (0x312) - AIF1RX Channel 3 Configuration
2027 */
2028#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2029#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2030#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
2031#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
2032#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
2033#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
2034#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
2035#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2036#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2037#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2038#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2039#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2040#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2041
2042/*
2043 * R787 (0x313) - AIF1RX Channel 4 Configuration
2044 */
2045#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2046#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2047#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
2048#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
2049#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
2050#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
2051#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
2052#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2053#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2054#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2055#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2056#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2057#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2058
2059/*
2060 * R788 (0x314) - AIF1RX Channel 5 Configuration
2061 */
2062#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2063#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2064#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
2065#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
2066#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
2067#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
2068#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
2069#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2070#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2071#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2072#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2073#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2074#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2075
2076/*
2077 * R789 (0x315) - AIF1RX Mono Configuration
2078 */
2079#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2080#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2081#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
2082#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
2083#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2084#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2085#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
2086#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
2087#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2088#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2089#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
2090#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
2091
2092/*
2093 * R794 (0x31A) - AIF1TX Test
2094 */
2095#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
2096#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
2097#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
2098#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
2099#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
2100#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
2101#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
2102#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
2103#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
2104#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
2105#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
2106#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
2107
2108/*
2109 * R800 (0x320) - AIF2 Control
2110 */
2111#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */
2112#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
2113#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
2114#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2115#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
2116#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
2117#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
2118
2119/*
2120 * R801 (0x321) - AIF2 BCLK
2121 */
2122#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
2123#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
2124#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
2125#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2126#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
2127#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
2128#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
2129#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
2130#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
2131#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
2132#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
2133#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
2134#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
2135#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
2136#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
2137
2138/*
2139 * R802 (0x322) - AIF2 TX LRCLK(1)
2140 */
2141#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
2142#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
2143#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
2144
2145/*
2146 * R803 (0x323) - AIF2 TX LRCLK(2)
2147 */
2148#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
2149#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
2150#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
2151#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
2152#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
2153#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
2154#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
2155#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
2156#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
2157#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
2158#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
2159#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
2160#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
2161#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
2162#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
2163#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
2164
2165/*
2166 * R804 (0x324) - AIF2 RX LRCLK(1)
2167 */
2168#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
2169#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
2170#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
2171
2172/*
2173 * R805 (0x325) - AIF2 RX LRCLK(2)
2174 */
2175#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
2176#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
2177#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
2178#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
2179#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
2180#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
2181#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
2182#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
2183#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
2184#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
2185#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
2186#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
2187
2188/*
2189 * R806 (0x326) - AIF2TX Data Configuration (1)
2190 */
2191#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
2192#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
2193#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
2194#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
2195#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
2196#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
2197
2198/*
2199 * R807 (0x327) - AIF2TX Data Configuration (2)
2200 */
2201#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
2202#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
2203#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
2204#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
2205
2206/*
2207 * R808 (0x328) - AIF2RX Data Configuration
2208 */
2209#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
2210#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
2211#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
2212#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
2213#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
2214#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
2215
2216/*
2217 * R809 (0x329) - AIF2TX Channel 0 Configuration
2218 */
2219#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2220#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2221#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
2222#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
2223#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
2224#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
2225#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
2226#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2227#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2228#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2229#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2230#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2231#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2232
2233/*
2234 * R810 (0x32A) - AIF2TX Channel 1 Configuration
2235 */
2236#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2237#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2238#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
2239#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
2240#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
2241#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
2242#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
2243#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2244#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2245#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2246#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2247#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2248#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2249
2250/*
2251 * R811 (0x32B) - AIF2RX Channel 0 Configuration
2252 */
2253#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2254#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2255#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
2256#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
2257#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
2258#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
2259#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
2260#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2261#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2262#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2263#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2264#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2265#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2266
2267/*
2268 * R812 (0x32C) - AIF2RX Channel 1 Configuration
2269 */
2270#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2271#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2272#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
2273#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
2274#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
2275#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
2276#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
2277#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2278#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2279#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2280#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2281#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2282#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2283
2284/*
2285 * R813 (0x32D) - AIF2RX Mono Configuration
2286 */
2287#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2288#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2289#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
2290#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
2291
2292/*
2293 * R815 (0x32F) - AIF2TX Test
2294 */
2295#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
2296#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
2297#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
2298#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
2299
2300/*
2301 * R1024 (0x400) - DSP1 TX Left Volume
2302 */
2303#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2304#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2305#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2306#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2307#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
2308#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
2309#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
2310
2311/*
2312 * R1025 (0x401) - DSP1 TX Right Volume
2313 */
2314#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2315#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2316#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2317#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2318#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
2319#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
2320#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
2321
2322/*
2323 * R1026 (0x402) - DSP1 RX Left Volume
2324 */
2325#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2326#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2327#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2328#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2329#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
2330#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
2331#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
2332
2333/*
2334 * R1027 (0x403) - DSP1 RX Right Volume
2335 */
2336#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2337#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2338#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2339#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2340#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
2341#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
2342#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
2343
2344/*
2345 * R1040 (0x410) - DSP1 TX Filters
2346 */
2347#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */
2348#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
2349#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
2350#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
2351#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
2352#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
2353#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
2354#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
2355#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
2356#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
2357#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
2358#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
2359#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
2360#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
2361#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
2362#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
2363#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
2364#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
2365
2366/*
2367 * R1056 (0x420) - DSP1 RX Filters (1)
2368 */
2369#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
2370#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
2371#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
2372#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
2373#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
2374#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
2375#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
2376#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
2377#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
2378#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
2379#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
2380#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
2381#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
2382#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
2383#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
2384#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
2385
2386/*
2387 * R1057 (0x421) - DSP1 RX Filters (2)
2388 */
2389#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
2390#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
2391#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
2392#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
2393#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
2394#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
2395#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
2396
2397/*
2398 * R1088 (0x440) - DSP1 DRC (1)
2399 */
2400#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2401#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2402#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2403#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
2404#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
2405#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
2406#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
2407#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
2408#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
2409#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
2410#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
2411#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
2412#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
2413#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
2414#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
2415#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
2416#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
2417#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
2418#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2419#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2420#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
2421#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
2422#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
2423#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
2424#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
2425#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
2426#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
2427#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
2428#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
2429#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
2430#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
2431#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
2432#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
2433#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
2434#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
2435#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
2436#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
2437#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
2438#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
2439#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
2440#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
2441#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
2442
2443/*
2444 * R1089 (0x441) - DSP1 DRC (2)
2445 */
2446#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
2447#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
2448#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
2449#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
2450#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
2451#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
2452#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
2453#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
2454#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
2455#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
2456#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
2457#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
2458
2459/*
2460 * R1090 (0x442) - DSP1 DRC (3)
2461 */
2462#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
2463#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
2464#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
2465#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
2466#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
2467#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
2468#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
2469#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
2470#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
2471#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
2472#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
2473#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
2474#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
2475#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
2476#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
2477#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
2478#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
2479#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
2480
2481/*
2482 * R1091 (0x443) - DSP1 DRC (4)
2483 */
2484#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
2485#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
2486#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
2487#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
2488#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
2489#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
2490
2491/*
2492 * R1092 (0x444) - DSP1 DRC (5)
2493 */
2494#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
2495#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2496#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2497#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
2498#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
2499#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
2500
2501/*
2502 * R1152 (0x480) - DSP1 RX EQ Gains (1)
2503 */
2504#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2505#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2506#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2507#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2508#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2509#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2510#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
2511#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2512#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2513#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
2514#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
2515#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
2516#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
2517
2518/*
2519 * R1153 (0x481) - DSP1 RX EQ Gains (2)
2520 */
2521#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2522#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2523#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2524#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2525#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2526#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2527
2528/*
2529 * R1154 (0x482) - DSP1 RX EQ Band 1 A
2530 */
2531#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
2532#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
2533#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
2534
2535/*
2536 * R1155 (0x483) - DSP1 RX EQ Band 1 B
2537 */
2538#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
2539#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
2540#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
2541
2542/*
2543 * R1156 (0x484) - DSP1 RX EQ Band 1 PG
2544 */
2545#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
2546#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
2547#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
2548
2549/*
2550 * R1157 (0x485) - DSP1 RX EQ Band 2 A
2551 */
2552#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
2553#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
2554#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
2555
2556/*
2557 * R1158 (0x486) - DSP1 RX EQ Band 2 B
2558 */
2559#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
2560#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
2561#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
2562
2563/*
2564 * R1159 (0x487) - DSP1 RX EQ Band 2 C
2565 */
2566#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
2567#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
2568#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
2569
2570/*
2571 * R1160 (0x488) - DSP1 RX EQ Band 2 PG
2572 */
2573#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
2574#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
2575#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
2576
2577/*
2578 * R1161 (0x489) - DSP1 RX EQ Band 3 A
2579 */
2580#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
2581#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
2582#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
2583
2584/*
2585 * R1162 (0x48A) - DSP1 RX EQ Band 3 B
2586 */
2587#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
2588#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
2589#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
2590
2591/*
2592 * R1163 (0x48B) - DSP1 RX EQ Band 3 C
2593 */
2594#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
2595#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
2596#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
2597
2598/*
2599 * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
2600 */
2601#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
2602#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
2603#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
2604
2605/*
2606 * R1165 (0x48D) - DSP1 RX EQ Band 4 A
2607 */
2608#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
2609#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
2610#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
2611
2612/*
2613 * R1166 (0x48E) - DSP1 RX EQ Band 4 B
2614 */
2615#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
2616#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
2617#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
2618
2619/*
2620 * R1167 (0x48F) - DSP1 RX EQ Band 4 C
2621 */
2622#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
2623#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
2624#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
2625
2626/*
2627 * R1168 (0x490) - DSP1 RX EQ Band 4 PG
2628 */
2629#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
2630#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
2631#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
2632
2633/*
2634 * R1169 (0x491) - DSP1 RX EQ Band 5 A
2635 */
2636#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
2637#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
2638#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
2639
2640/*
2641 * R1170 (0x492) - DSP1 RX EQ Band 5 B
2642 */
2643#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
2644#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
2645#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
2646
2647/*
2648 * R1171 (0x493) - DSP1 RX EQ Band 5 PG
2649 */
2650#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
2651#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
2652#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
2653
2654/*
2655 * R1280 (0x500) - DSP2 TX Left Volume
2656 */
2657#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2658#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2659#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2660#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2661#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
2662#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
2663#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
2664
2665/*
2666 * R1281 (0x501) - DSP2 TX Right Volume
2667 */
2668#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2669#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2670#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2671#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2672#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
2673#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
2674#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
2675
2676/*
2677 * R1282 (0x502) - DSP2 RX Left Volume
2678 */
2679#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2680#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2681#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2682#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2683#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
2684#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
2685#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
2686
2687/*
2688 * R1283 (0x503) - DSP2 RX Right Volume
2689 */
2690#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2691#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2692#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2693#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2694#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
2695#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
2696#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
2697
2698/*
2699 * R1296 (0x510) - DSP2 TX Filters
2700 */
2701#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */
2702#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
2703#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
2704#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
2705#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
2706#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
2707#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
2708#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
2709#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
2710#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
2711#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
2712#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
2713#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
2714#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
2715#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
2716#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
2717#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
2718#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
2719
2720/*
2721 * R1312 (0x520) - DSP2 RX Filters (1)
2722 */
2723#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
2724#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
2725#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
2726#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
2727#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
2728#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
2729#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
2730#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
2731#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
2732#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
2733#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
2734#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
2735#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
2736#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
2737#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
2738#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
2739
2740/*
2741 * R1313 (0x521) - DSP2 RX Filters (2)
2742 */
2743#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
2744#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
2745#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
2746#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
2747#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
2748#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
2749#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
2750
2751/*
2752 * R1344 (0x540) - DSP2 DRC (1)
2753 */
2754#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2755#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2756#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2757#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
2758#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
2759#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
2760#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
2761#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
2762#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
2763#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
2764#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
2765#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
2766#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
2767#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
2768#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
2769#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
2770#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
2771#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
2772#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2773#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2774#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
2775#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
2776#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
2777#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
2778#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
2779#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
2780#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
2781#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
2782#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
2783#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
2784#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
2785#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
2786#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
2787#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
2788#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
2789#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
2790#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
2791#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
2792#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
2793#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
2794#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
2795#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
2796
2797/*
2798 * R1345 (0x541) - DSP2 DRC (2)
2799 */
2800#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
2801#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
2802#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
2803#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
2804#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
2805#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
2806#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
2807#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
2808#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
2809#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
2810#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
2811#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
2812
2813/*
2814 * R1346 (0x542) - DSP2 DRC (3)
2815 */
2816#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
2817#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
2818#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
2819#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
2820#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
2821#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
2822#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
2823#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
2824#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
2825#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
2826#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
2827#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
2828#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
2829#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
2830#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
2831#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
2832#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
2833#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
2834
2835/*
2836 * R1347 (0x543) - DSP2 DRC (4)
2837 */
2838#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
2839#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
2840#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
2841#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
2842#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
2843#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
2844
2845/*
2846 * R1348 (0x544) - DSP2 DRC (5)
2847 */
2848#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
2849#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2850#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2851#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
2852#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
2853#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
2854
2855/*
2856 * R1408 (0x580) - DSP2 RX EQ Gains (1)
2857 */
2858#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2859#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2860#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2861#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2862#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2863#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2864#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
2865#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2866#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2867#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
2868#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
2869#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
2870#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
2871
2872/*
2873 * R1409 (0x581) - DSP2 RX EQ Gains (2)
2874 */
2875#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2876#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2877#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2878#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2879#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2880#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2881
2882/*
2883 * R1410 (0x582) - DSP2 RX EQ Band 1 A
2884 */
2885#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
2886#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
2887#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
2888
2889/*
2890 * R1411 (0x583) - DSP2 RX EQ Band 1 B
2891 */
2892#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
2893#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
2894#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
2895
2896/*
2897 * R1412 (0x584) - DSP2 RX EQ Band 1 PG
2898 */
2899#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
2900#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
2901#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
2902
2903/*
2904 * R1413 (0x585) - DSP2 RX EQ Band 2 A
2905 */
2906#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
2907#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
2908#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
2909
2910/*
2911 * R1414 (0x586) - DSP2 RX EQ Band 2 B
2912 */
2913#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
2914#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
2915#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
2916
2917/*
2918 * R1415 (0x587) - DSP2 RX EQ Band 2 C
2919 */
2920#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
2921#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
2922#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
2923
2924/*
2925 * R1416 (0x588) - DSP2 RX EQ Band 2 PG
2926 */
2927#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
2928#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
2929#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
2930
2931/*
2932 * R1417 (0x589) - DSP2 RX EQ Band 3 A
2933 */
2934#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
2935#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
2936#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
2937
2938/*
2939 * R1418 (0x58A) - DSP2 RX EQ Band 3 B
2940 */
2941#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
2942#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
2943#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
2944
2945/*
2946 * R1419 (0x58B) - DSP2 RX EQ Band 3 C
2947 */
2948#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
2949#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
2950#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
2951
2952/*
2953 * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
2954 */
2955#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
2956#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
2957#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
2958
2959/*
2960 * R1421 (0x58D) - DSP2 RX EQ Band 4 A
2961 */
2962#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
2963#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
2964#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
2965
2966/*
2967 * R1422 (0x58E) - DSP2 RX EQ Band 4 B
2968 */
2969#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
2970#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
2971#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
2972
2973/*
2974 * R1423 (0x58F) - DSP2 RX EQ Band 4 C
2975 */
2976#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
2977#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
2978#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
2979
2980/*
2981 * R1424 (0x590) - DSP2 RX EQ Band 4 PG
2982 */
2983#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
2984#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
2985#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
2986
2987/*
2988 * R1425 (0x591) - DSP2 RX EQ Band 5 A
2989 */
2990#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
2991#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
2992#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
2993
2994/*
2995 * R1426 (0x592) - DSP2 RX EQ Band 5 B
2996 */
2997#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
2998#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
2999#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
3000
3001/*
3002 * R1427 (0x593) - DSP2 RX EQ Band 5 PG
3003 */
3004#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
3005#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
3006#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
3007
3008/*
3009 * R1536 (0x600) - DAC1 Mixer Volumes
3010 */
3011#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
3012#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
3013#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
3014#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
3015#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
3016#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
3017
3018/*
3019 * R1537 (0x601) - DAC1 Left Mixer Routing
3020 */
3021#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3022#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3023#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3024#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3025#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3026#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3027#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3028#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3029#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
3030#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
3031#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
3032#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
3033#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
3034#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
3035#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
3036#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
3037
3038/*
3039 * R1538 (0x602) - DAC1 Right Mixer Routing
3040 */
3041#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3042#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3043#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3044#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3045#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3046#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3047#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3048#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3049#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
3050#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
3051#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
3052#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
3053#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
3054#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
3055#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
3056#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
3057
3058/*
3059 * R1539 (0x603) - DAC2 Mixer Volumes
3060 */
3061#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
3062#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
3063#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
3064#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
3065#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
3066#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
3067
3068/*
3069 * R1540 (0x604) - DAC2 Left Mixer Routing
3070 */
3071#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3072#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3073#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3074#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3075#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3076#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3077#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3078#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3079#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
3080#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
3081#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
3082#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
3083#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
3084#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
3085#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
3086#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
3087
3088/*
3089 * R1541 (0x605) - DAC2 Right Mixer Routing
3090 */
3091#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3092#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3093#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3094#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3095#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3096#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3097#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3098#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3099#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
3100#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
3101#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
3102#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
3103#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
3104#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
3105#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
3106#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
3107
3108/*
3109 * R1542 (0x606) - DSP1 TX Left Mixer Routing
3110 */
3111#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
3112#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
3113#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
3114#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
3115#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
3116#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
3117#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
3118#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
3119
3120/*
3121 * R1543 (0x607) - DSP1 TX Right Mixer Routing
3122 */
3123#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
3124#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
3125#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
3126#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
3127#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
3128#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
3129#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
3130#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
3131
3132/*
3133 * R1544 (0x608) - DSP2 TX Left Mixer Routing
3134 */
3135#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
3136#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
3137#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
3138#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
3139#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
3140#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
3141#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
3142#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
3143
3144/*
3145 * R1545 (0x609) - DSP2 TX Right Mixer Routing
3146 */
3147#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
3148#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
3149#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
3150#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
3151#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
3152#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
3153#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
3154#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
3155
3156/*
3157 * R1546 (0x60A) - DSP TX Mixer Select
3158 */
3159#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
3160#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
3161#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
3162#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
3163
3164/*
3165 * R1552 (0x610) - DAC Softmute
3166 */
3167#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3168#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3169#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3170#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3171#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3172#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3173#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3174#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3175
3176/*
3177 * R1568 (0x620) - Oversampling
3178 */
3179#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */
3180#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
3181#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
3182#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
3183#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
3184#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
3185#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
3186#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
3187#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */
3188#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3189#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3190#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3191#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */
3192#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3193#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3194#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3195
3196/*
3197 * R1569 (0x621) - Sidetone
3198 */
3199#define WM8915_ST_LPF 0x1000 /* ST_LPF */
3200#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */
3201#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */
3202#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */
3203#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3204#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3205#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3206#define WM8915_ST_HPF 0x0040 /* ST_HPF */
3207#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */
3208#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */
3209#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */
3210#define WM8915_STR_SEL 0x0002 /* STR_SEL */
3211#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */
3212#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */
3213#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */
3214#define WM8915_STL_SEL 0x0001 /* STL_SEL */
3215#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */
3216#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */
3217#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */
3218
3219/*
3220 * R1792 (0x700) - GPIO 1
3221 */
3222#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */
3223#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */
3224#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */
3225#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */
3226#define WM8915_GP1_PU 0x4000 /* GP1_PU */
3227#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */
3228#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */
3229#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */
3230#define WM8915_GP1_PD 0x2000 /* GP1_PD */
3231#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */
3232#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */
3233#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */
3234#define WM8915_GP1_POL 0x0400 /* GP1_POL */
3235#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */
3236#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */
3237#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */
3238#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
3239#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
3240#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
3241#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
3242#define WM8915_GP1_DB 0x0100 /* GP1_DB */
3243#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */
3244#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */
3245#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */
3246#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */
3247#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */
3248#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */
3249#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */
3250#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
3251#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
3252#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
3253
3254/*
3255 * R1793 (0x701) - GPIO 2
3256 */
3257#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */
3258#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */
3259#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */
3260#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */
3261#define WM8915_GP2_PU 0x4000 /* GP2_PU */
3262#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */
3263#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */
3264#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */
3265#define WM8915_GP2_PD 0x2000 /* GP2_PD */
3266#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */
3267#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */
3268#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */
3269#define WM8915_GP2_POL 0x0400 /* GP2_POL */
3270#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */
3271#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */
3272#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */
3273#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
3274#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
3275#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
3276#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
3277#define WM8915_GP2_DB 0x0100 /* GP2_DB */
3278#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */
3279#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */
3280#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */
3281#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */
3282#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3283#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */
3284#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */
3285#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
3286#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
3287#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
3288
3289/*
3290 * R1794 (0x702) - GPIO 3
3291 */
3292#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */
3293#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */
3294#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */
3295#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */
3296#define WM8915_GP3_PU 0x4000 /* GP3_PU */
3297#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */
3298#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */
3299#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */
3300#define WM8915_GP3_PD 0x2000 /* GP3_PD */
3301#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */
3302#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */
3303#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */
3304#define WM8915_GP3_POL 0x0400 /* GP3_POL */
3305#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */
3306#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */
3307#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */
3308#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3309#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3310#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3311#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3312#define WM8915_GP3_DB 0x0100 /* GP3_DB */
3313#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */
3314#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */
3315#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */
3316#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */
3317#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3318#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */
3319#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */
3320#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
3321#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
3322#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
3323
3324/*
3325 * R1795 (0x703) - GPIO 4
3326 */
3327#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */
3328#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3329#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */
3330#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */
3331#define WM8915_GP4_PU 0x4000 /* GP4_PU */
3332#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */
3333#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */
3334#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */
3335#define WM8915_GP4_PD 0x2000 /* GP4_PD */
3336#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */
3337#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */
3338#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */
3339#define WM8915_GP4_POL 0x0400 /* GP4_POL */
3340#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */
3341#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */
3342#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */
3343#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3344#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3345#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3346#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3347#define WM8915_GP4_DB 0x0100 /* GP4_DB */
3348#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */
3349#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */
3350#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */
3351#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */
3352#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3353#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */
3354#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */
3355#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
3356#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
3357#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
3358
3359/*
3360 * R1796 (0x704) - GPIO 5
3361 */
3362#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */
3363#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3364#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */
3365#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */
3366#define WM8915_GP5_PU 0x4000 /* GP5_PU */
3367#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */
3368#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */
3369#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */
3370#define WM8915_GP5_PD 0x2000 /* GP5_PD */
3371#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */
3372#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */
3373#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */
3374#define WM8915_GP5_POL 0x0400 /* GP5_POL */
3375#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */
3376#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */
3377#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */
3378#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3379#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3380#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3381#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3382#define WM8915_GP5_DB 0x0100 /* GP5_DB */
3383#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */
3384#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */
3385#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */
3386#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */
3387#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3388#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */
3389#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */
3390#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
3391#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
3392#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
3393
3394/*
3395 * R1824 (0x720) - Pull Control (1)
3396 */
3397#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
3398#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
3399#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
3400#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3401#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
3402#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
3403#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
3404#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3405#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */
3406#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
3407#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
3408#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
3409#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */
3410#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
3411#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
3412#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3413#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */
3414#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3415#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3416#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3417#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */
3418#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3419#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3420#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3421#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3422#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3423#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3424#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3425#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3426#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3427#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3428#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3429#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3430#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3431#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3432#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3433#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3434#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3435#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3436#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3437#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */
3438#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3439#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3440#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3441#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */
3442#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3443#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3444#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3445
3446/*
3447 * R1825 (0x721) - Pull Control (2)
3448 */
3449#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
3450#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
3451#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
3452#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3453#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */
3454#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */
3455#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */
3456#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */
3457#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */
3458#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
3459#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
3460#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
3461#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */
3462#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
3463#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
3464#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
3465#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
3466#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
3467#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
3468#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
3469#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
3470#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
3471#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
3472#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
3473#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */
3474#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
3475#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
3476#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
3477#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */
3478#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
3479#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
3480#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
3481
3482/*
3483 * R1840 (0x730) - Interrupt Status 1
3484 */
3485#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */
3486#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3487#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */
3488#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */
3489#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */
3490#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3491#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */
3492#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */
3493#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */
3494#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3495#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */
3496#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */
3497#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */
3498#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3499#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */
3500#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */
3501#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */
3502#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3503#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */
3504#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */
3505
3506/*
3507 * R1841 (0x731) - Interrupt Status 2
3508 */
3509#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
3510#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
3511#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
3512#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
3513#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
3514#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
3515#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
3516#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
3517#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
3518#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
3519#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
3520#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3521#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
3522#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
3523#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
3524#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3525#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
3526#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
3527#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
3528#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
3529#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
3530#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
3531#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
3532#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
3533#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
3534#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
3535#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
3536#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
3537#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
3538#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
3539#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
3540#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
3541#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
3542#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
3543#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
3544#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
3545#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */
3546#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */
3547#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */
3548#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */
3549
3550/*
3551 * R1842 (0x732) - Interrupt Raw Status 2
3552 */
3553#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
3554#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
3555#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
3556#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
3557#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
3558#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
3559#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
3560#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
3561#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
3562#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
3563#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
3564#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
3565#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
3566#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
3567#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
3568#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
3569#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
3570#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
3571#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
3572#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
3573#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
3574#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
3575#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
3576#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
3577#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
3578#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
3579#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
3580#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
3581
3582/*
3583 * R1848 (0x738) - Interrupt Status 1 Mask
3584 */
3585#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3586#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3587#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3588#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3589#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
3590#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
3591#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
3592#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
3593#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
3594#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
3595#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
3596#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
3597#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
3598#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
3599#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
3600#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
3601#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
3602#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
3603#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
3604#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
3605
3606/*
3607 * R1849 (0x739) - Interrupt Status 2 Mask
3608 */
3609#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
3610#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
3611#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
3612#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
3613#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
3614#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
3615#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
3616#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
3617#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
3618#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
3619#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
3620#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
3621#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
3622#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
3623#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
3624#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
3625#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3626#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3627#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
3628#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
3629#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3630#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3631#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
3632#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
3633#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3634#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3635#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
3636#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
3637#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
3638#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
3639#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
3640#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
3641#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
3642#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
3643#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
3644#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
3645#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
3646#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
3647#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
3648#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
3649
3650/*
3651 * R1856 (0x740) - Interrupt Control
3652 */
3653#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */
3654#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */
3655#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */
3656#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */
3657
3658/*
3659 * R2048 (0x800) - Left PDM Speaker
3660 */
3661#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */
3662#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
3663#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
3664#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
3665#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */
3666#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
3667#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
3668#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
3669#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
3670#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
3671#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
3672#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
3673#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
3674#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
3675#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
3676
3677/*
3678 * R2049 (0x801) - Right PDM Speaker
3679 */
3680#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */
3681#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
3682#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
3683#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
3684#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */
3685#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
3686#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
3687#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
3688#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
3689#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
3690#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
3691#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
3692#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
3693#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
3694#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
3695
3696/*
3697 * R2050 (0x802) - PDM Speaker Mute Sequence
3698 */
3699#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
3700#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
3701#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
3702#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
3703#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
3704#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
3705#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
3706
3707/*
3708 * R2051 (0x803) - PDM Speaker Volume
3709 */
3710#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
3711#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
3712#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
3713#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
3714#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
3715#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
3716
3717#endif
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
new file mode 100644
index 000000000000..74983ee2b87f
--- /dev/null
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -0,0 +1,1028 @@
1/*
2 * wm8958-dsp2.c -- WM8958 DSP2 support
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <sound/soc.h>
22#include <sound/initval.h>
23#include <sound/tlv.h>
24#include <trace/events/asoc.h>
25
26#include <linux/mfd/wm8994/core.h>
27#include <linux/mfd/wm8994/registers.h>
28#include <linux/mfd/wm8994/pdata.h>
29#include <linux/mfd/wm8994/gpio.h>
30
31#include "wm8994.h"
32
33#define WM_FW_BLOCK_INFO 0xff
34#define WM_FW_BLOCK_PM 0x00
35#define WM_FW_BLOCK_X 0x01
36#define WM_FW_BLOCK_Y 0x02
37#define WM_FW_BLOCK_Z 0x03
38#define WM_FW_BLOCK_I 0x06
39#define WM_FW_BLOCK_A 0x08
40#define WM_FW_BLOCK_C 0x0c
41
42static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
43 const struct firmware *fw, bool check)
44{
45 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
46 u64 data64;
47 u32 data32;
48 const u8 *data;
49 char *str;
50 size_t block_len, len;
51 int ret = 0;
52
53 /* Suppress unneeded downloads */
54 if (wm8994->cur_fw == fw)
55 return 0;
56
57 if (fw->size < 32) {
58 dev_err(codec->dev, "%s: firmware too short\n", name);
59 goto err;
60 }
61
62 if (memcmp(fw->data, "WMFW", 4) != 0) {
63 dev_err(codec->dev, "%s: firmware has bad file magic %08x\n",
64 name, data32);
65 goto err;
66 }
67
68 memcpy(&data32, fw->data + 4, sizeof(data32));
69 len = be32_to_cpu(data32);
70
71 memcpy(&data32, fw->data + 8, sizeof(data32));
72 data32 = be32_to_cpu(data32);
73 if ((data32 >> 24) & 0xff) {
74 dev_err(codec->dev, "%s: unsupported firmware version %d\n",
75 name, (data32 >> 24) & 0xff);
76 goto err;
77 }
78 if ((data32 & 0xffff) != 8958) {
79 dev_err(codec->dev, "%s: unsupported target device %d\n",
80 name, data32 & 0xffff);
81 goto err;
82 }
83 if (((data32 >> 16) & 0xff) != 0xc) {
84 dev_err(codec->dev, "%s: unsupported target core %d\n",
85 name, (data32 >> 16) & 0xff);
86 goto err;
87 }
88
89 if (check) {
90 memcpy(&data64, fw->data + 24, sizeof(u64));
91 dev_info(codec->dev, "%s timestamp %llx\n",
92 name, be64_to_cpu(data64));
93 } else {
94 snd_soc_write(codec, 0x102, 0x2);
95 snd_soc_write(codec, 0x900, 0x2);
96 }
97
98 data = fw->data + len;
99 len = fw->size - len;
100 while (len) {
101 if (len < 12) {
102 dev_err(codec->dev, "%s short data block of %d\n",
103 name, len);
104 goto err;
105 }
106
107 memcpy(&data32, data + 4, sizeof(data32));
108 block_len = be32_to_cpu(data32);
109 if (block_len + 8 > len) {
110 dev_err(codec->dev, "%d byte block longer than file\n",
111 block_len);
112 goto err;
113 }
114 if (block_len == 0) {
115 dev_err(codec->dev, "Zero length block\n");
116 goto err;
117 }
118
119 memcpy(&data32, data, sizeof(data32));
120 data32 = be32_to_cpu(data32);
121
122 switch ((data32 >> 24) & 0xff) {
123 case WM_FW_BLOCK_INFO:
124 /* Informational text */
125 if (!check)
126 break;
127
128 str = kzalloc(block_len + 1, GFP_KERNEL);
129 if (str) {
130 memcpy(str, data + 8, block_len);
131 dev_info(codec->dev, "%s: %s\n", name, str);
132 kfree(str);
133 } else {
134 dev_err(codec->dev, "Out of memory\n");
135 }
136 break;
137 case WM_FW_BLOCK_PM:
138 case WM_FW_BLOCK_X:
139 case WM_FW_BLOCK_Y:
140 case WM_FW_BLOCK_Z:
141 case WM_FW_BLOCK_I:
142 case WM_FW_BLOCK_A:
143 case WM_FW_BLOCK_C:
144 dev_dbg(codec->dev, "%s: %d bytes of %x@%x\n", name,
145 block_len, (data32 >> 24) & 0xff,
146 data32 & 0xffffff);
147
148 if (check)
149 break;
150
151 data32 &= 0xffffff;
152
153 wm8994_bulk_write(codec->control_data,
154 data32 & 0xffffff,
155 block_len / 2,
156 (void *)(data + 8));
157
158 break;
159 default:
160 dev_warn(codec->dev, "%s: unknown block type %d\n",
161 name, (data32 >> 24) & 0xff);
162 break;
163 }
164
165 /* Round up to the next 32 bit word */
166 block_len += block_len % 4;
167
168 data += block_len + 8;
169 len -= block_len + 8;
170 }
171
172 if (!check) {
173 dev_dbg(codec->dev, "%s: download done\n", name);
174 wm8994->cur_fw = fw;
175 } else {
176 dev_info(codec->dev, "%s: got firmware\n", name);
177 }
178
179 goto ok;
180
181err:
182 ret = -EINVAL;
183ok:
184 if (!check) {
185 snd_soc_write(codec, 0x900, 0x0);
186 snd_soc_write(codec, 0x102, 0x0);
187 }
188
189 return ret;
190}
191
192static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
193{
194 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
195 struct wm8994_pdata *pdata = wm8994->pdata;
196 int i;
197
198 /* If the DSP is already running then noop */
199 if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
200 return;
201
202 /* If we have MBC firmware download it */
203 if (wm8994->mbc)
204 wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false);
205
206 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
207 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
208
209 /* If we've got user supplied MBC settings use them */
210 if (pdata && pdata->num_mbc_cfgs) {
211 struct wm8958_mbc_cfg *cfg
212 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
213
214 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
215 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
216 cfg->coeff_regs[i]);
217
218 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
219 snd_soc_write(codec,
220 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
221 cfg->cutoff_regs[i]);
222 }
223
224 /* Run the DSP */
225 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
226 WM8958_DSP2_RUNR);
227
228 /* And we're off! */
229 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
230 WM8958_MBC_ENA |
231 WM8958_MBC_SEL_MASK,
232 path << WM8958_MBC_SEL_SHIFT |
233 WM8958_MBC_ENA);
234}
235
236static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
237{
238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
239 struct wm8994_pdata *pdata = wm8994->pdata;
240 int i, ena;
241
242 if (wm8994->mbc_vss)
243 wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false);
244
245 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
246 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
247
248 /* If we've got user supplied settings use them */
249 if (pdata && pdata->num_mbc_cfgs) {
250 struct wm8958_mbc_cfg *cfg
251 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
252
253 for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
254 snd_soc_write(codec, i + 0x2800,
255 cfg->combined_regs[i]);
256 }
257
258 if (pdata && pdata->num_vss_cfgs) {
259 struct wm8958_vss_cfg *cfg
260 = &pdata->vss_cfgs[wm8994->vss_cfg];
261
262 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
263 snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
264 }
265
266 if (pdata && pdata->num_vss_hpf_cfgs) {
267 struct wm8958_vss_hpf_cfg *cfg
268 = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
269
270 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
271 snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
272 }
273
274 /* Run the DSP */
275 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
276 WM8958_DSP2_RUNR);
277
278 /* Enable the algorithms we've selected */
279 ena = 0;
280 if (wm8994->mbc_ena[path])
281 ena |= 0x8;
282 if (wm8994->hpf2_ena[path])
283 ena |= 0x4;
284 if (wm8994->hpf1_ena[path])
285 ena |= 0x2;
286 if (wm8994->vss_ena[path])
287 ena |= 0x1;
288
289 snd_soc_write(codec, 0x2201, ena);
290
291 /* Switch the DSP into the data path */
292 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
293 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
294 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
295}
296
297static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
298{
299 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
300 struct wm8994_pdata *pdata = wm8994->pdata;
301 int i;
302
303 wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
304
305 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
306 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
307
308 /* If we've got user supplied settings use them */
309 if (pdata && pdata->num_enh_eq_cfgs) {
310 struct wm8958_enh_eq_cfg *cfg
311 = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
312
313 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
314 snd_soc_write(codec, i + 0x2200,
315 cfg->regs[i]);
316 }
317
318 /* Run the DSP */
319 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
320 WM8958_DSP2_RUNR);
321
322 /* Switch the DSP into the data path */
323 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
324 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
325 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
326}
327
328static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
329{
330 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
331 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
332 int ena, reg, aif;
333
334 switch (path) {
335 case 0:
336 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
337 aif = 0;
338 break;
339 case 1:
340 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
341 aif = 0;
342 break;
343 case 2:
344 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
345 aif = 1;
346 break;
347 default:
348 BUG();
349 return;
350 }
351
352 /* Do we have both an active AIF and an active algorithm? */
353 ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] ||
354 wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] ||
355 wm8994->enh_eq_ena[path];
356 if (!pwr_reg)
357 ena = 0;
358
359 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
360
361 dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
362 path, wm8994->dsp_active, start, pwr_reg, reg);
363
364 if (start && ena) {
365 /* If either AIFnCLK is not yet enabled postpone */
366 if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
367 & WM8994_AIF1CLK_ENA_MASK) &&
368 !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
369 & WM8994_AIF2CLK_ENA_MASK))
370 return;
371
372 /* Switch the clock over to the appropriate AIF */
373 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
374 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
375 aif << WM8958_DSP2CLK_SRC_SHIFT |
376 WM8958_DSP2CLK_ENA);
377
378 if (wm8994->enh_eq_ena[path])
379 wm8958_dsp_start_enh_eq(codec, path);
380 else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
381 wm8994->hpf2_ena[path])
382 wm8958_dsp_start_vss(codec, path);
383 else if (wm8994->mbc_ena[path])
384 wm8958_dsp_start_mbc(codec, path);
385
386 wm8994->dsp_active = path;
387
388 dev_dbg(codec->dev, "DSP running in path %d\n", path);
389 }
390
391 if (!start && wm8994->dsp_active == path) {
392 /* If the DSP is already stopped then noop */
393 if (!(reg & WM8958_DSP2_ENA))
394 return;
395
396 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
397 WM8958_MBC_ENA, 0);
398 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
399 WM8958_DSP2_STOP);
400 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
401 WM8958_DSP2_ENA, 0);
402 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
403 WM8958_DSP2CLK_ENA, 0);
404
405 wm8994->dsp_active = -1;
406
407 dev_dbg(codec->dev, "DSP stopped\n");
408 }
409}
410
411int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
412 struct snd_kcontrol *kcontrol, int event)
413{
414 struct snd_soc_codec *codec = w->codec;
415 int i;
416
417 switch (event) {
418 case SND_SOC_DAPM_POST_PMU:
419 case SND_SOC_DAPM_PRE_PMU:
420 for (i = 0; i < 3; i++)
421 wm8958_dsp_apply(codec, i, 1);
422 break;
423 case SND_SOC_DAPM_POST_PMD:
424 case SND_SOC_DAPM_PRE_PMD:
425 for (i = 0; i < 3; i++)
426 wm8958_dsp_apply(codec, i, 0);
427 break;
428 }
429
430 return 0;
431}
432
433/* Check if DSP2 is in use on another AIF */
434static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
435{
436 int i;
437
438 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
439 if (i == aif)
440 continue;
441 if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] ||
442 wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i])
443 return 1;
444 }
445
446 return 0;
447}
448
449static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
450 struct snd_ctl_elem_value *ucontrol)
451{
452 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
453 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
454 struct wm8994_pdata *pdata = wm8994->pdata;
455 int value = ucontrol->value.integer.value[0];
456 int reg;
457
458 /* Don't allow on the fly reconfiguration */
459 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
460 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
461 return -EBUSY;
462
463 if (value >= pdata->num_mbc_cfgs)
464 return -EINVAL;
465
466 wm8994->mbc_cfg = value;
467
468 return 0;
469}
470
471static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_value *ucontrol)
473{
474 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
475 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
476
477 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
478
479 return 0;
480}
481
482static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
483 struct snd_ctl_elem_info *uinfo)
484{
485 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
486 uinfo->count = 1;
487 uinfo->value.integer.min = 0;
488 uinfo->value.integer.max = 1;
489 return 0;
490}
491
492static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
493 struct snd_ctl_elem_value *ucontrol)
494{
495 int mbc = kcontrol->private_value;
496 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
497 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
498
499 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
500
501 return 0;
502}
503
504static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_value *ucontrol)
506{
507 int mbc = kcontrol->private_value;
508 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
509 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
510
511 if (ucontrol->value.integer.value[0] > 1)
512 return -EINVAL;
513
514 if (wm8958_dsp2_busy(wm8994, mbc)) {
515 dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc);
516 return -EBUSY;
517 }
518
519 if (wm8994->enh_eq_ena[mbc])
520 return -EBUSY;
521
522 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
523
524 wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]);
525
526 return 0;
527}
528
529#define WM8958_MBC_SWITCH(xname, xval) {\
530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
531 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
532 .info = wm8958_mbc_info, \
533 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
534 .private_value = xval }
535
536static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
537 struct snd_ctl_elem_value *ucontrol)
538{
539 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
540 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
541 struct wm8994_pdata *pdata = wm8994->pdata;
542 int value = ucontrol->value.integer.value[0];
543 int reg;
544
545 /* Don't allow on the fly reconfiguration */
546 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
547 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
548 return -EBUSY;
549
550 if (value >= pdata->num_vss_cfgs)
551 return -EINVAL;
552
553 wm8994->vss_cfg = value;
554
555 return 0;
556}
557
558static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
559 struct snd_ctl_elem_value *ucontrol)
560{
561 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
562 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
563
564 ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
565
566 return 0;
567}
568
569static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
573 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
574 struct wm8994_pdata *pdata = wm8994->pdata;
575 int value = ucontrol->value.integer.value[0];
576 int reg;
577
578 /* Don't allow on the fly reconfiguration */
579 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
580 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
581 return -EBUSY;
582
583 if (value >= pdata->num_vss_hpf_cfgs)
584 return -EINVAL;
585
586 wm8994->vss_hpf_cfg = value;
587
588 return 0;
589}
590
591static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
593{
594 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
595 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
596
597 ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
598
599 return 0;
600}
601
602static int wm8958_vss_info(struct snd_kcontrol *kcontrol,
603 struct snd_ctl_elem_info *uinfo)
604{
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
606 uinfo->count = 1;
607 uinfo->value.integer.min = 0;
608 uinfo->value.integer.max = 1;
609 return 0;
610}
611
612static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
613 struct snd_ctl_elem_value *ucontrol)
614{
615 int vss = kcontrol->private_value;
616 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
617 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
618
619 ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
620
621 return 0;
622}
623
624static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_value *ucontrol)
626{
627 int vss = kcontrol->private_value;
628 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
629 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
630
631 if (ucontrol->value.integer.value[0] > 1)
632 return -EINVAL;
633
634 if (!wm8994->mbc_vss)
635 return -ENODEV;
636
637 if (wm8958_dsp2_busy(wm8994, vss)) {
638 dev_dbg(codec->dev, "DSP2 active on %d already\n", vss);
639 return -EBUSY;
640 }
641
642 if (wm8994->enh_eq_ena[vss])
643 return -EBUSY;
644
645 wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
646
647 wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]);
648
649 return 0;
650}
651
652
653#define WM8958_VSS_SWITCH(xname, xval) {\
654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
655 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
656 .info = wm8958_vss_info, \
657 .get = wm8958_vss_get, .put = wm8958_vss_put, \
658 .private_value = xval }
659
660static int wm8958_hpf_info(struct snd_kcontrol *kcontrol,
661 struct snd_ctl_elem_info *uinfo)
662{
663 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
664 uinfo->count = 1;
665 uinfo->value.integer.min = 0;
666 uinfo->value.integer.max = 1;
667 return 0;
668}
669
670static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
671 struct snd_ctl_elem_value *ucontrol)
672{
673 int hpf = kcontrol->private_value;
674 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
675 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
676
677 if (hpf < 3)
678 ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
679 else
680 ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3];
681
682 return 0;
683}
684
685static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
686 struct snd_ctl_elem_value *ucontrol)
687{
688 int hpf = kcontrol->private_value;
689 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
690 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
691
692 if (ucontrol->value.integer.value[0] > 1)
693 return -EINVAL;
694
695 if (!wm8994->mbc_vss)
696 return -ENODEV;
697
698 if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
699 dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf);
700 return -EBUSY;
701 }
702
703 if (wm8994->enh_eq_ena[hpf % 3])
704 return -EBUSY;
705
706 if (hpf < 3)
707 wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0];
708 else
709 wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
710
711 wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]);
712
713 return 0;
714}
715
716#define WM8958_HPF_SWITCH(xname, xval) {\
717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
718 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
719 .info = wm8958_hpf_info, \
720 .get = wm8958_hpf_get, .put = wm8958_hpf_put, \
721 .private_value = xval }
722
723static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
724 struct snd_ctl_elem_value *ucontrol)
725{
726 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
727 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
728 struct wm8994_pdata *pdata = wm8994->pdata;
729 int value = ucontrol->value.integer.value[0];
730 int reg;
731
732 /* Don't allow on the fly reconfiguration */
733 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
734 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
735 return -EBUSY;
736
737 if (value >= pdata->num_enh_eq_cfgs)
738 return -EINVAL;
739
740 wm8994->enh_eq_cfg = value;
741
742 return 0;
743}
744
745static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
746 struct snd_ctl_elem_value *ucontrol)
747{
748 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
749 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
750
751 ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
752
753 return 0;
754}
755
756static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol,
757 struct snd_ctl_elem_info *uinfo)
758{
759 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
760 uinfo->count = 1;
761 uinfo->value.integer.min = 0;
762 uinfo->value.integer.max = 1;
763 return 0;
764}
765
766static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
767 struct snd_ctl_elem_value *ucontrol)
768{
769 int eq = kcontrol->private_value;
770 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
771 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
772
773 ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
774
775 return 0;
776}
777
778static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
779 struct snd_ctl_elem_value *ucontrol)
780{
781 int eq = kcontrol->private_value;
782 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
783 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
784
785 if (ucontrol->value.integer.value[0] > 1)
786 return -EINVAL;
787
788 if (!wm8994->enh_eq)
789 return -ENODEV;
790
791 if (wm8958_dsp2_busy(wm8994, eq)) {
792 dev_dbg(codec->dev, "DSP2 active on %d already\n", eq);
793 return -EBUSY;
794 }
795
796 if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] ||
797 wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq])
798 return -EBUSY;
799
800 wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
801
802 wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]);
803
804 return 0;
805}
806
807#define WM8958_ENH_EQ_SWITCH(xname, xval) {\
808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
809 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
810 .info = wm8958_enh_eq_info, \
811 .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \
812 .private_value = xval }
813
814static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = {
815WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
816WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
817WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
818};
819
820static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = {
821WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0),
822WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1),
823WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2),
824WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0),
825WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1),
826WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2),
827WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3),
828WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4),
829WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5),
830};
831
832static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = {
833WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0),
834WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1),
835WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
836};
837
838static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
839{
840 struct snd_soc_codec *codec = context;
841 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
842
843 if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) {
844 mutex_lock(&codec->mutex);
845 wm8994->enh_eq = fw;
846 mutex_unlock(&codec->mutex);
847 }
848}
849
850static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
851{
852 struct snd_soc_codec *codec = context;
853 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
854
855 if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) {
856 mutex_lock(&codec->mutex);
857 wm8994->mbc_vss = fw;
858 mutex_unlock(&codec->mutex);
859 }
860
861 /* We can't have more than one request outstanding at once so
862 * we daisy chain.
863 */
864 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
865 "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
866 codec, wm8958_enh_eq_loaded);
867}
868
869static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
870{
871 struct snd_soc_codec *codec = context;
872 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
873
874 if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
875 return;
876
877 mutex_lock(&codec->mutex);
878 wm8994->mbc = fw;
879 mutex_unlock(&codec->mutex);
880
881 /* We can't have more than one request outstanding at once so
882 * we daisy chain.
883 */
884 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
885 "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
886 codec, wm8958_mbc_vss_loaded);
887}
888
889void wm8958_dsp2_init(struct snd_soc_codec *codec)
890{
891 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
892 struct wm8994_pdata *pdata = wm8994->pdata;
893 int ret, i;
894
895 wm8994->dsp_active = -1;
896
897 snd_soc_add_controls(codec, wm8958_mbc_snd_controls,
898 ARRAY_SIZE(wm8958_mbc_snd_controls));
899 snd_soc_add_controls(codec, wm8958_vss_snd_controls,
900 ARRAY_SIZE(wm8958_vss_snd_controls));
901 snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls,
902 ARRAY_SIZE(wm8958_enh_eq_snd_controls));
903
904
905 /* We don't *require* firmware and don't want to delay boot */
906 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
907 "wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
908 codec, wm8958_mbc_loaded);
909
910 if (!pdata)
911 return;
912
913 if (pdata->num_mbc_cfgs) {
914 struct snd_kcontrol_new control[] = {
915 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
916 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
917 };
918
919 /* We need an array of texts for the enum API */
920 wm8994->mbc_texts = kmalloc(sizeof(char *)
921 * pdata->num_mbc_cfgs, GFP_KERNEL);
922 if (!wm8994->mbc_texts) {
923 dev_err(wm8994->codec->dev,
924 "Failed to allocate %d MBC config texts\n",
925 pdata->num_mbc_cfgs);
926 return;
927 }
928
929 for (i = 0; i < pdata->num_mbc_cfgs; i++)
930 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
931
932 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
933 wm8994->mbc_enum.texts = wm8994->mbc_texts;
934
935 ret = snd_soc_add_controls(wm8994->codec, control, 1);
936 if (ret != 0)
937 dev_err(wm8994->codec->dev,
938 "Failed to add MBC mode controls: %d\n", ret);
939 }
940
941 if (pdata->num_vss_cfgs) {
942 struct snd_kcontrol_new control[] = {
943 SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum,
944 wm8958_get_vss_enum, wm8958_put_vss_enum),
945 };
946
947 /* We need an array of texts for the enum API */
948 wm8994->vss_texts = kmalloc(sizeof(char *)
949 * pdata->num_vss_cfgs, GFP_KERNEL);
950 if (!wm8994->vss_texts) {
951 dev_err(wm8994->codec->dev,
952 "Failed to allocate %d VSS config texts\n",
953 pdata->num_vss_cfgs);
954 return;
955 }
956
957 for (i = 0; i < pdata->num_vss_cfgs; i++)
958 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
959
960 wm8994->vss_enum.max = pdata->num_vss_cfgs;
961 wm8994->vss_enum.texts = wm8994->vss_texts;
962
963 ret = snd_soc_add_controls(wm8994->codec, control, 1);
964 if (ret != 0)
965 dev_err(wm8994->codec->dev,
966 "Failed to add VSS mode controls: %d\n", ret);
967 }
968
969 if (pdata->num_vss_hpf_cfgs) {
970 struct snd_kcontrol_new control[] = {
971 SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum,
972 wm8958_get_vss_hpf_enum,
973 wm8958_put_vss_hpf_enum),
974 };
975
976 /* We need an array of texts for the enum API */
977 wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
978 * pdata->num_vss_hpf_cfgs, GFP_KERNEL);
979 if (!wm8994->vss_hpf_texts) {
980 dev_err(wm8994->codec->dev,
981 "Failed to allocate %d VSS HPF config texts\n",
982 pdata->num_vss_hpf_cfgs);
983 return;
984 }
985
986 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
987 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
988
989 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
990 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
991
992 ret = snd_soc_add_controls(wm8994->codec, control, 1);
993 if (ret != 0)
994 dev_err(wm8994->codec->dev,
995 "Failed to add VSS HPFmode controls: %d\n",
996 ret);
997 }
998
999 if (pdata->num_enh_eq_cfgs) {
1000 struct snd_kcontrol_new control[] = {
1001 SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum,
1002 wm8958_get_enh_eq_enum,
1003 wm8958_put_enh_eq_enum),
1004 };
1005
1006 /* We need an array of texts for the enum API */
1007 wm8994->enh_eq_texts = kmalloc(sizeof(char *)
1008 * pdata->num_enh_eq_cfgs, GFP_KERNEL);
1009 if (!wm8994->enh_eq_texts) {
1010 dev_err(wm8994->codec->dev,
1011 "Failed to allocate %d enhanced EQ config texts\n",
1012 pdata->num_enh_eq_cfgs);
1013 return;
1014 }
1015
1016 for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
1017 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
1018
1019 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1020 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1021
1022 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1023 if (ret != 0)
1024 dev_err(wm8994->codec->dev,
1025 "Failed to add enhanced EQ controls: %d\n",
1026 ret);
1027 }
1028}
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 84e1bd1d2822..b6d47e771519 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -38,12 +38,6 @@
38#include "wm8994.h" 38#include "wm8994.h"
39#include "wm_hubs.h" 39#include "wm_hubs.h"
40 40
41struct fll_config {
42 int src;
43 int in;
44 int out;
45};
46
47#define WM8994_NUM_DRC 3 41#define WM8994_NUM_DRC 3
48#define WM8994_NUM_EQ 3 42#define WM8994_NUM_EQ 3
49 43
@@ -59,63 +53,11 @@ static int wm8994_retune_mobile_base[] = {
59 WM8994_AIF2_EQ_GAINS_1, 53 WM8994_AIF2_EQ_GAINS_1,
60}; 54};
61 55
62struct wm8994_micdet {
63 struct snd_soc_jack *jack;
64 int det;
65 int shrt;
66};
67
68/* codec private data */
69struct wm8994_priv {
70 struct wm_hubs_data hubs;
71 enum snd_soc_control_type control_type;
72 void *control_data;
73 struct snd_soc_codec *codec;
74 int sysclk[2];
75 int sysclk_rate[2];
76 int mclk[2];
77 int aifclk[2];
78 struct fll_config fll[2], fll_suspend[2];
79
80 int dac_rates[2];
81 int lrclk_shared[2];
82
83 int mbc_ena[3];
84
85 /* Platform dependent DRC configuration */
86 const char **drc_texts;
87 int drc_cfg[WM8994_NUM_DRC];
88 struct soc_enum drc_enum;
89
90 /* Platform dependent ReTune mobile configuration */
91 int num_retune_mobile_texts;
92 const char **retune_mobile_texts;
93 int retune_mobile_cfg[WM8994_NUM_EQ];
94 struct soc_enum retune_mobile_enum;
95
96 /* Platform dependent MBC configuration */
97 int mbc_cfg;
98 const char **mbc_texts;
99 struct soc_enum mbc_enum;
100
101 struct wm8994_micdet micdet[2];
102
103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data;
105 int micdet_irq;
106
107 int revision;
108 struct wm8994_pdata *pdata;
109
110 unsigned int aif1clk_enable:1;
111 unsigned int aif2clk_enable:1;
112
113 unsigned int aif1clk_disable:1;
114 unsigned int aif2clk_disable:1;
115};
116
117static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) 56static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
118{ 57{
58 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
59 struct wm8994 *control = wm8994->control_data;
60
119 switch (reg) { 61 switch (reg) {
120 case WM8994_GPIO_1: 62 case WM8994_GPIO_1:
121 case WM8994_GPIO_2: 63 case WM8994_GPIO_2:
@@ -132,6 +74,15 @@ static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
132 case WM8994_INTERRUPT_STATUS_2: 74 case WM8994_INTERRUPT_STATUS_2:
133 case WM8994_INTERRUPT_RAW_STATUS_2: 75 case WM8994_INTERRUPT_RAW_STATUS_2:
134 return 1; 76 return 1;
77
78 case WM8958_DSP2_PROGRAM:
79 case WM8958_DSP2_CONFIG:
80 case WM8958_DSP2_EXECCONTROL:
81 if (control->type == WM8958)
82 return 1;
83 else
84 return 0;
85
135 default: 86 default:
136 break; 87 break;
137 } 88 }
@@ -574,215 +525,6 @@ static const struct soc_enum dac_osr =
574static const struct soc_enum adc_osr = 525static const struct soc_enum adc_osr =
575 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); 526 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
576 527
577static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
578{
579 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
580 struct wm8994_pdata *pdata = wm8994->pdata;
581 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
582 int ena, reg, aif, i;
583
584 switch (mbc) {
585 case 0:
586 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
587 aif = 0;
588 break;
589 case 1:
590 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
591 aif = 0;
592 break;
593 case 2:
594 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
595 aif = 1;
596 break;
597 default:
598 BUG();
599 return;
600 }
601
602 /* We can only enable the MBC if the AIF is enabled and we
603 * want it to be enabled. */
604 ena = pwr_reg && wm8994->mbc_ena[mbc];
605
606 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
607
608 dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n",
609 mbc, start, pwr_reg, reg);
610
611 if (start && ena) {
612 /* If the DSP is already running then noop */
613 if (reg & WM8958_DSP2_ENA)
614 return;
615
616 /* Switch the clock over to the appropriate AIF */
617 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
618 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
619 aif << WM8958_DSP2CLK_SRC_SHIFT |
620 WM8958_DSP2CLK_ENA);
621
622 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
623 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
624
625 /* If we've got user supplied MBC settings use them */
626 if (pdata && pdata->num_mbc_cfgs) {
627 struct wm8958_mbc_cfg *cfg
628 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
629
630 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
631 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
632 cfg->coeff_regs[i]);
633
634 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
635 snd_soc_write(codec,
636 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
637 cfg->cutoff_regs[i]);
638 }
639
640 /* Run the DSP */
641 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
642 WM8958_DSP2_RUNR);
643
644 /* And we're off! */
645 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
646 WM8958_MBC_ENA | WM8958_MBC_SEL_MASK,
647 mbc << WM8958_MBC_SEL_SHIFT |
648 WM8958_MBC_ENA);
649 } else {
650 /* If the DSP is already stopped then noop */
651 if (!(reg & WM8958_DSP2_ENA))
652 return;
653
654 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
655 WM8958_MBC_ENA, 0);
656 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
657 WM8958_DSP2_ENA, 0);
658 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
659 WM8958_DSP2CLK_ENA, 0);
660 }
661}
662
663static int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
664 struct snd_kcontrol *kcontrol, int event)
665{
666 struct snd_soc_codec *codec = w->codec;
667 int mbc;
668
669 switch (w->shift) {
670 case 13:
671 case 12:
672 mbc = 2;
673 break;
674 case 11:
675 case 10:
676 mbc = 1;
677 break;
678 case 9:
679 case 8:
680 mbc = 0;
681 break;
682 default:
683 BUG();
684 return -EINVAL;
685 }
686
687 switch (event) {
688 case SND_SOC_DAPM_POST_PMU:
689 wm8958_mbc_apply(codec, mbc, 1);
690 break;
691 case SND_SOC_DAPM_POST_PMD:
692 wm8958_mbc_apply(codec, mbc, 0);
693 break;
694 }
695
696 return 0;
697}
698
699static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
701{
702 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
703 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
704 struct wm8994_pdata *pdata = wm8994->pdata;
705 int value = ucontrol->value.integer.value[0];
706 int reg;
707
708 /* Don't allow on the fly reconfiguration */
709 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
710 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
711 return -EBUSY;
712
713 if (value >= pdata->num_mbc_cfgs)
714 return -EINVAL;
715
716 wm8994->mbc_cfg = value;
717
718 return 0;
719}
720
721static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
723{
724 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
725 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
726
727 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
728
729 return 0;
730}
731
732static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
733 struct snd_ctl_elem_info *uinfo)
734{
735 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
736 uinfo->count = 1;
737 uinfo->value.integer.min = 0;
738 uinfo->value.integer.max = 1;
739 return 0;
740}
741
742static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
743 struct snd_ctl_elem_value *ucontrol)
744{
745 int mbc = kcontrol->private_value;
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
748
749 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
750
751 return 0;
752}
753
754static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756{
757 int mbc = kcontrol->private_value;
758 int i;
759 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
760 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
761
762 if (ucontrol->value.integer.value[0] > 1)
763 return -EINVAL;
764
765 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
766 if (mbc != i && wm8994->mbc_ena[i]) {
767 dev_dbg(codec->dev, "MBC %d active already\n", mbc);
768 return -EBUSY;
769 }
770 }
771
772 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
773
774 wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]);
775
776 return 0;
777}
778
779#define WM8958_MBC_SWITCH(xname, xval) {\
780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
781 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
782 .info = wm8958_mbc_info, \
783 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
784 .private_value = xval }
785
786static const struct snd_kcontrol_new wm8994_snd_controls[] = { 528static const struct snd_kcontrol_new wm8994_snd_controls[] = {
787SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, 529SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
788 WM8994_AIF1_ADC1_RIGHT_VOLUME, 530 WM8994_AIF1_ADC1_RIGHT_VOLUME,
@@ -924,9 +666,6 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
924 666
925static const struct snd_kcontrol_new wm8958_snd_controls[] = { 667static const struct snd_kcontrol_new wm8958_snd_controls[] = {
926SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), 668SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
927WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
928WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
929WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
930}; 669};
931 670
932static int clk_sys_event(struct snd_soc_dapm_widget *w, 671static int clk_sys_event(struct snd_soc_dapm_widget *w,
@@ -1032,6 +771,9 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
1032 break; 771 break;
1033 } 772 }
1034 773
774 /* We may also have postponed startup of DSP, handle that. */
775 wm8958_aif_ev(w, kcontrol, event);
776
1035 return 0; 777 return 0;
1036} 778}
1037 779
@@ -2180,6 +1922,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2180 WM8994_VMID_BUF_ENA | 1922 WM8994_VMID_BUF_ENA |
2181 WM8994_VMID_RAMP_MASK, 0); 1923 WM8994_VMID_RAMP_MASK, 0);
2182 1924
1925 wm8994->cur_fw = NULL;
1926
2183 pm_runtime_put(codec->dev); 1927 pm_runtime_put(codec->dev);
2184 } 1928 }
2185 break; 1929 break;
@@ -2676,7 +2420,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
2676 2420
2677 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2421 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2678 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 2422 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
2679 sizeof(struct fll_config)); 2423 sizeof(struct wm8994_fll_config));
2680 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0); 2424 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
2681 if (ret < 0) 2425 if (ret < 0)
2682 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", 2426 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
@@ -2862,34 +2606,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2862 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", 2606 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2863 pdata->num_retune_mobile_cfgs); 2607 pdata->num_retune_mobile_cfgs);
2864 2608
2865 if (pdata->num_mbc_cfgs) {
2866 struct snd_kcontrol_new control[] = {
2867 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
2868 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
2869 };
2870
2871 /* We need an array of texts for the enum API */
2872 wm8994->mbc_texts = kmalloc(sizeof(char *)
2873 * pdata->num_mbc_cfgs, GFP_KERNEL);
2874 if (!wm8994->mbc_texts) {
2875 dev_err(wm8994->codec->dev,
2876 "Failed to allocate %d MBC config texts\n",
2877 pdata->num_mbc_cfgs);
2878 return;
2879 }
2880
2881 for (i = 0; i < pdata->num_mbc_cfgs; i++)
2882 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
2883
2884 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
2885 wm8994->mbc_enum.texts = wm8994->mbc_texts;
2886
2887 ret = snd_soc_add_controls(wm8994->codec, control, 1);
2888 if (ret != 0)
2889 dev_err(wm8994->codec->dev,
2890 "Failed to add MBC mode controls: %d\n", ret);
2891 }
2892
2893 if (pdata->num_retune_mobile_cfgs) 2609 if (pdata->num_retune_mobile_cfgs)
2894 wm8994_handle_retune_mobile_pdata(wm8994); 2610 wm8994_handle_retune_mobile_pdata(wm8994);
2895 else 2611 else
@@ -3343,14 +3059,23 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3343 case WM8958: 3059 case WM8958:
3344 snd_soc_add_controls(codec, wm8958_snd_controls, 3060 snd_soc_add_controls(codec, wm8958_snd_controls,
3345 ARRAY_SIZE(wm8958_snd_controls)); 3061 ARRAY_SIZE(wm8958_snd_controls));
3346 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3347 ARRAY_SIZE(wm8994_lateclk_widgets));
3348 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3349 ARRAY_SIZE(wm8994_adc_widgets));
3350 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3351 ARRAY_SIZE(wm8994_dac_widgets));
3352 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3062 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3353 ARRAY_SIZE(wm8958_dapm_widgets)); 3063 ARRAY_SIZE(wm8958_dapm_widgets));
3064 if (wm8994->revision < 1) {
3065 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3066 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3067 snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
3068 ARRAY_SIZE(wm8994_adc_revd_widgets));
3069 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3070 ARRAY_SIZE(wm8994_dac_revd_widgets));
3071 } else {
3072 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3073 ARRAY_SIZE(wm8994_lateclk_widgets));
3074 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3075 ARRAY_SIZE(wm8994_adc_widgets));
3076 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3077 ARRAY_SIZE(wm8994_dac_widgets));
3078 }
3354 break; 3079 break;
3355 } 3080 }
3356 3081
@@ -3374,10 +3099,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3374 } 3099 }
3375 break; 3100 break;
3376 case WM8958: 3101 case WM8958:
3377 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, 3102 if (wm8994->revision < 1) {
3378 ARRAY_SIZE(wm8994_lateclk_intercon)); 3103 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3379 snd_soc_dapm_add_routes(dapm, wm8958_intercon, 3104 ARRAY_SIZE(wm8994_revd_intercon));
3380 ARRAY_SIZE(wm8958_intercon)); 3105 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3106 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3107 } else {
3108 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3109 ARRAY_SIZE(wm8994_lateclk_intercon));
3110 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3111 ARRAY_SIZE(wm8958_intercon));
3112 }
3113
3114 wm8958_dsp2_init(codec);
3381 break; 3115 break;
3382 } 3116 }
3383 3117
@@ -3420,6 +3154,12 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3420 free_irq(wm8994->micdet_irq, wm8994); 3154 free_irq(wm8994->micdet_irq, wm8994);
3421 break; 3155 break;
3422 } 3156 }
3157 if (wm8994->mbc)
3158 release_firmware(wm8994->mbc);
3159 if (wm8994->mbc_vss)
3160 release_firmware(wm8994->mbc_vss);
3161 if (wm8994->enh_eq)
3162 release_firmware(wm8994->enh_eq);
3423 kfree(wm8994->retune_mobile_texts); 3163 kfree(wm8994->retune_mobile_texts);
3424 kfree(wm8994->drc_texts); 3164 kfree(wm8994->drc_texts);
3425 kfree(wm8994); 3165 kfree(wm8994);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 999b8851226b..0a1db04b73bd 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -10,6 +10,9 @@
10#define _WM8994_H 10#define _WM8994_H
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13#include <linux/firmware.h>
14
15#include "wm_hubs.h"
13 16
14/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ 17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
15#define WM8994_SYSCLK_MCLK1 1 18#define WM8994_SYSCLK_MCLK1 1
@@ -45,4 +48,98 @@ struct wm8994_access_mask {
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; 48extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; 49extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
47 50
51int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
52 struct snd_kcontrol *kcontrol, int event);
53
54void wm8958_dsp2_init(struct snd_soc_codec *codec);
55
56struct wm8994_micdet {
57 struct snd_soc_jack *jack;
58 int det;
59 int shrt;
60};
61
62/* codec private data */
63struct wm8994_fll_config {
64 int src;
65 int in;
66 int out;
67};
68
69#define WM8994_NUM_DRC 3
70#define WM8994_NUM_EQ 3
71
72struct wm8994_priv {
73 struct wm_hubs_data hubs;
74 enum snd_soc_control_type control_type;
75 void *control_data;
76 struct snd_soc_codec *codec;
77 int sysclk[2];
78 int sysclk_rate[2];
79 int mclk[2];
80 int aifclk[2];
81 struct wm8994_fll_config fll[2], fll_suspend[2];
82
83 int dac_rates[2];
84 int lrclk_shared[2];
85
86 int mbc_ena[3];
87 int hpf1_ena[3];
88 int hpf2_ena[3];
89 int vss_ena[3];
90 int enh_eq_ena[3];
91
92 /* Platform dependant DRC configuration */
93 const char **drc_texts;
94 int drc_cfg[WM8994_NUM_DRC];
95 struct soc_enum drc_enum;
96
97 /* Platform dependant ReTune mobile configuration */
98 int num_retune_mobile_texts;
99 const char **retune_mobile_texts;
100 int retune_mobile_cfg[WM8994_NUM_EQ];
101 struct soc_enum retune_mobile_enum;
102
103 /* Platform dependant MBC configuration */
104 int mbc_cfg;
105 const char **mbc_texts;
106 struct soc_enum mbc_enum;
107
108 /* Platform dependant VSS configuration */
109 int vss_cfg;
110 const char **vss_texts;
111 struct soc_enum vss_enum;
112
113 /* Platform dependant VSS HPF configuration */
114 int vss_hpf_cfg;
115 const char **vss_hpf_texts;
116 struct soc_enum vss_hpf_enum;
117
118 /* Platform dependant enhanced EQ configuration */
119 int enh_eq_cfg;
120 const char **enh_eq_texts;
121 struct soc_enum enh_eq_enum;
122
123 struct wm8994_micdet micdet[2];
124
125 wm8958_micdet_cb jack_cb;
126 void *jack_cb_data;
127 int micdet_irq;
128
129 int revision;
130 struct wm8994_pdata *pdata;
131
132 unsigned int aif1clk_enable:1;
133 unsigned int aif2clk_enable:1;
134
135 unsigned int aif1clk_disable:1;
136 unsigned int aif2clk_disable:1;
137
138 int dsp_active;
139 const struct firmware *cur_fw;
140 const struct firmware *mbc;
141 const struct firmware *mbc_vss;
142 const struct firmware *enh_eq;
143};
144
48#endif 145#endif
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 47b357adabdd..646b58dda849 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -142,7 +142,7 @@ static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = {
142 * constantly enabled, we use the mutes on those inputs to simulate such 142 * constantly enabled, we use the mutes on those inputs to simulate such
143 * controls. 143 * controls.
144 */ 144 */
145static const struct snd_soc_dapm_route audio_map[] = { 145static const struct snd_soc_dapm_route wm9705_audio_map[] = {
146 /* HP mixer */ 146 /* HP mixer */
147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, 147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"},
148 {"HP Mixer", "CD Playback Switch", "CD PGA"}, 148 {"HP Mixer", "CD Playback Switch", "CD PGA"},
@@ -200,17 +200,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
200 {"Right ADC", NULL, "ADC PGA"}, 200 {"Right ADC", NULL, "ADC PGA"},
201}; 201};
202 202
203static int wm9705_add_widgets(struct snd_soc_codec *codec)
204{
205 struct snd_soc_dapm_context *dapm = &codec->dapm;
206
207 snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets,
208 ARRAY_SIZE(wm9705_dapm_widgets));
209 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
210
211 return 0;
212}
213
214/* We use a register cache to enhance read performance. */ 203/* We use a register cache to enhance read performance. */
215static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) 204static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
216{ 205{
@@ -364,7 +353,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
364 353
365 snd_soc_add_controls(codec, wm9705_snd_ac97_controls, 354 snd_soc_add_controls(codec, wm9705_snd_ac97_controls,
366 ARRAY_SIZE(wm9705_snd_ac97_controls)); 355 ARRAY_SIZE(wm9705_snd_ac97_controls));
367 wm9705_add_widgets(codec);
368 356
369 return 0; 357 return 0;
370 358
@@ -390,6 +378,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
390 .reg_word_size = sizeof(u16), 378 .reg_word_size = sizeof(u16),
391 .reg_cache_step = 2, 379 .reg_cache_step = 2,
392 .reg_cache_default = wm9705_reg, 380 .reg_cache_default = wm9705_reg,
381 .dapm_widgets = wm9705_dapm_widgets,
382 .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
383 .dapm_routes = wm9705_audio_map,
384 .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
393}; 385};
394 386
395static __devinit int wm9705_probe(struct platform_device *pdev) 387static __devinit int wm9705_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index bf5d4ef1a2a6..90117f8156e8 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -332,7 +332,7 @@ SND_SOC_DAPM_INPUT("MIC1"),
332SND_SOC_DAPM_INPUT("MIC2"), 332SND_SOC_DAPM_INPUT("MIC2"),
333}; 333};
334 334
335static const struct snd_soc_dapm_route audio_map[] = { 335static const struct snd_soc_dapm_route wm9712_audio_map[] = {
336 /* virtual mixer - mixes left & right channels for spk and mono */ 336 /* virtual mixer - mixes left & right channels for spk and mono */
337 {"AC97 Mixer", NULL, "Left DAC"}, 337 {"AC97 Mixer", NULL, "Left DAC"},
338 {"AC97 Mixer", NULL, "Right DAC"}, 338 {"AC97 Mixer", NULL, "Right DAC"},
@@ -429,17 +429,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
429 {"ROUT2", NULL, "Speaker PGA"}, 429 {"ROUT2", NULL, "Speaker PGA"},
430}; 430};
431 431
432static int wm9712_add_widgets(struct snd_soc_codec *codec)
433{
434 struct snd_soc_dapm_context *dapm = &codec->dapm;
435
436 snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets,
437 ARRAY_SIZE(wm9712_dapm_widgets));
438 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
439
440 return 0;
441}
442
443static unsigned int ac97_read(struct snd_soc_codec *codec, 432static unsigned int ac97_read(struct snd_soc_codec *codec,
444 unsigned int reg) 433 unsigned int reg)
445{ 434{
@@ -651,7 +640,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
651 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 640 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
652 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 641 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
653 ARRAY_SIZE(wm9712_snd_ac97_controls)); 642 ARRAY_SIZE(wm9712_snd_ac97_controls));
654 wm9712_add_widgets(codec);
655 643
656 return 0; 644 return 0;
657 645
@@ -678,6 +666,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
678 .reg_word_size = sizeof(u16), 666 .reg_word_size = sizeof(u16),
679 .reg_cache_step = 2, 667 .reg_cache_step = 2,
680 .reg_cache_default = wm9712_reg, 668 .reg_cache_default = wm9712_reg,
669 .dapm_widgets = wm9712_dapm_widgets,
670 .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
671 .dapm_routes = wm9712_audio_map,
672 .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
681}; 673};
682 674
683static __devinit int wm9712_probe(struct platform_device *pdev) 675static __devinit int wm9712_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 38ed98558718..7167cb6787db 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -487,7 +487,7 @@ SND_SOC_DAPM_INPUT("MIC2B"),
487SND_SOC_DAPM_VMID("VMID"), 487SND_SOC_DAPM_VMID("VMID"),
488}; 488};
489 489
490static const struct snd_soc_dapm_route audio_map[] = { 490static const struct snd_soc_dapm_route wm9713_audio_map[] = {
491 /* left HP mixer */ 491 /* left HP mixer */
492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"}, 492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -644,18 +644,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
644 {"Capture Mono Mux", "Right", "Right Capture Source"}, 644 {"Capture Mono Mux", "Right", "Right Capture Source"},
645}; 645};
646 646
647static int wm9713_add_widgets(struct snd_soc_codec *codec)
648{
649 struct snd_soc_dapm_context *dapm = &codec->dapm;
650
651 snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
652 ARRAY_SIZE(wm9713_dapm_widgets));
653
654 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
655
656 return 0;
657}
658
659static unsigned int ac97_read(struct snd_soc_codec *codec, 647static unsigned int ac97_read(struct snd_soc_codec *codec,
660 unsigned int reg) 648 unsigned int reg)
661{ 649{
@@ -1231,7 +1219,6 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1231 1219
1232 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1220 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1233 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1221 ARRAY_SIZE(wm9713_snd_ac97_controls));
1234 wm9713_add_widgets(codec);
1235 1222
1236 return 0; 1223 return 0;
1237 1224
@@ -1262,6 +1249,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1262 .reg_word_size = sizeof(u16), 1249 .reg_word_size = sizeof(u16),
1263 .reg_cache_step = 2, 1250 .reg_cache_step = 2,
1264 .reg_cache_default = wm9713_reg, 1251 .reg_cache_default = wm9713_reg,
1252 .dapm_widgets = wm9713_dapm_widgets,
1253 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
1254 .dapm_routes = wm9713_audio_map,
1255 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
1265}; 1256};
1266 1257
1267static __devinit int wm9713_probe(struct platform_device *pdev) 1258static __devinit int wm9713_probe(struct platform_device *pdev)
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index ac2ded969253..5b13feca7537 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -667,12 +667,6 @@ static int imx_ssi_probe(struct platform_device *pdev)
667 if (res) 667 if (res)
668 ssi->dma_params_rx.dma = res->start; 668 ssi->dma_params_rx.dma = res->start;
669 669
670 if ((cpu_is_mx27() || cpu_is_mx21()) &&
671 !(ssi->flags & IMX_SSI_USE_AC97) &&
672 (ssi->flags & IMX_SSI_DMA)) {
673 ssi->flags |= IMX_SSI_DMA;
674 }
675
676 platform_set_drvdata(pdev, ssi); 670 platform_set_drvdata(pdev, ssi);
677 671
678 ret = snd_soc_register_dai(&pdev->dev, dai); 672 ret = snd_soc_register_dai(&pdev->dev, dai);
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index 49723e3e7e38..c5fc339f68f1 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -27,11 +27,7 @@
27static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, 27static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget,
28 struct snd_kcontrol *ctrl, int event) 28 struct snd_kcontrol *ctrl, int event)
29{ 29{
30 int on = 0; 30 int on = !SND_SOC_DAPM_EVENT_OFF(event);
31 if (event & SND_SOC_DAPM_POST_PMU)
32 on = 1;
33 else if (event & SND_SOC_DAPM_PRE_PMD)
34 on = 0;
35 31
36 gpio_set_value(QI_LB60_SND_GPIO, on); 32 gpio_set_value(QI_LB60_SND_GPIO, on);
37 gpio_set_value(QI_LB60_AMP_GPIO, on); 33 gpio_set_value(QI_LB60_AMP_GPIO, on);
@@ -70,12 +66,6 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
70 return ret; 66 return ret;
71 } 67 }
72 68
73 snd_soc_dapm_new_controls(dapm, qi_lb60_widgets,
74 ARRAY_SIZE(qi_lb60_widgets));
75 snd_soc_dapm_add_routes(dapm, qi_lb60_routes,
76 ARRAY_SIZE(qi_lb60_routes));
77 snd_soc_dapm_sync(dapm);
78
79 return 0; 69 return 0;
80} 70}
81 71
@@ -93,10 +83,20 @@ static struct snd_soc_card qi_lb60 = {
93 .name = "QI LB60", 83 .name = "QI LB60",
94 .dai_link = &qi_lb60_dai, 84 .dai_link = &qi_lb60_dai,
95 .num_links = 1, 85 .num_links = 1,
86
87 .dapm_widgets = qi_lb60_widgets,
88 .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets),
89 .dapm_routes = qi_lb60_routes,
90 .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
96}; 91};
97 92
98static struct platform_device *qi_lb60_snd_device; 93static struct platform_device *qi_lb60_snd_device;
99 94
95static const struct gpio qi_lb60_gpios[] = {
96 { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
97 { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
98};
99
100static int __init qi_lb60_init(void) 100static int __init qi_lb60_init(void)
101{ 101{
102 int ret; 102 int ret;
@@ -106,23 +106,12 @@ static int __init qi_lb60_init(void)
106 if (!qi_lb60_snd_device) 106 if (!qi_lb60_snd_device)
107 return -ENOMEM; 107 return -ENOMEM;
108 108
109 ret = gpio_request(QI_LB60_SND_GPIO, "SND"); 109 ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
110 if (ret) { 110 if (ret) {
111 pr_err("qi_lb60 snd: Failed to request SND GPIO(%d): %d\n", 111 pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret);
112 QI_LB60_SND_GPIO, ret);
113 goto err_device_put; 112 goto err_device_put;
114 } 113 }
115 114
116 ret = gpio_request(QI_LB60_AMP_GPIO, "AMP");
117 if (ret) {
118 pr_err("qi_lb60 snd: Failed to request AMP GPIO(%d): %d\n",
119 QI_LB60_AMP_GPIO, ret);
120 goto err_gpio_free_snd;
121 }
122
123 gpio_direction_output(QI_LB60_SND_GPIO, 0);
124 gpio_direction_output(QI_LB60_AMP_GPIO, 0);
125
126 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); 115 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60);
127 116
128 ret = platform_device_add(qi_lb60_snd_device); 117 ret = platform_device_add(qi_lb60_snd_device);
@@ -135,10 +124,8 @@ static int __init qi_lb60_init(void)
135 124
136err_unset_pdata: 125err_unset_pdata:
137 platform_set_drvdata(qi_lb60_snd_device, NULL); 126 platform_set_drvdata(qi_lb60_snd_device, NULL);
138/*err_gpio_free_amp:*/ 127/*err_gpio_free_array:*/
139 gpio_free(QI_LB60_AMP_GPIO); 128 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
140err_gpio_free_snd:
141 gpio_free(QI_LB60_SND_GPIO);
142err_device_put: 129err_device_put:
143 platform_device_put(qi_lb60_snd_device); 130 platform_device_put(qi_lb60_snd_device);
144 131
@@ -148,9 +135,8 @@ module_init(qi_lb60_init);
148 135
149static void __exit qi_lb60_exit(void) 136static void __exit qi_lb60_exit(void)
150{ 137{
151 gpio_free(QI_LB60_AMP_GPIO);
152 gpio_free(QI_LB60_SND_GPIO);
153 platform_device_unregister(qi_lb60_snd_device); 138 platform_device_unregister(qi_lb60_snd_device);
139 gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
154} 140}
155module_exit(qi_lb60_exit); 141module_exit(qi_lb60_exit);
156 142
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index d567c322a2fb..9765fb81a5e3 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -249,10 +249,13 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
249 return -ENOMEM; 249 return -ENOMEM;
250 } 250 }
251 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; 251 stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
252 stream->sstdrv_ops->module_name = SST_CARD_NAMES;
252 /* registering with SST driver to get access to SST APIs to use */ 253 /* registering with SST driver to get access to SST APIs to use */
253 ret_val = register_sst_card(stream->sstdrv_ops); 254 ret_val = register_sst_card(stream->sstdrv_ops);
254 if (ret_val) { 255 if (ret_val) {
255 pr_err("sst: sst card registration failed\n"); 256 pr_err("sst: sst card registration failed\n");
257 kfree(stream->sstdrv_ops);
258 kfree(stream);
256 return ret_val; 259 return ret_val;
257 } 260 }
258 runtime->private_data = stream; 261 runtime->private_data = stream;
@@ -270,6 +273,7 @@ static int sst_platform_close(struct snd_pcm_substream *substream)
270 str_id = stream->stream_info.str_id; 273 str_id = stream->stream_info.str_id;
271 if (str_id) 274 if (str_id)
272 ret_val = stream->sstdrv_ops->pcm_control->close(str_id); 275 ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
276 unregister_sst_card(stream->sstdrv_ops);
273 kfree(stream->sstdrv_ops); 277 kfree(stream->sstdrv_ops);
274 kfree(stream); 278 kfree(stream);
275 return ret_val; 279 return ret_val;
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 9027da466cae..28757fb9df31 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -310,7 +310,7 @@ static struct snd_soc_dai_link corgi_dai = {
310 .cpu_dai_name = "pxa2xx-i2s", 310 .cpu_dai_name = "pxa2xx-i2s",
311 .codec_dai_name = "wm8731-hifi", 311 .codec_dai_name = "wm8731-hifi",
312 .platform_name = "pxa-pcm-audio", 312 .platform_name = "pxa-pcm-audio",
313 .codec_name = "wm8731-codec.0-001b", 313 .codec_name = "wm8731.0-001b",
314 .init = corgi_wm8731_init, 314 .init = corgi_wm8731_init,
315 .ops = &corgi_ops, 315 .ops = &corgi_ops,
316}; 316};
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a7d4999f9b24..da3ae4316cf2 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -276,7 +276,7 @@ static struct snd_soc_dai_link poodle_dai = {
276 .cpu_dai_name = "pxa2xx-i2s", 276 .cpu_dai_name = "pxa2xx-i2s",
277 .codec_dai_name = "wm8731-hifi", 277 .codec_dai_name = "wm8731-hifi",
278 .platform_name = "pxa-pcm-audio", 278 .platform_name = "pxa-pcm-audio",
279 .codec_name = "wm8731-codec.0-001b", 279 .codec_name = "wm8731.0-001b",
280 .init = poodle_wm8731_init, 280 .init = poodle_wm8731_init,
281 .ops = &poodle_ops, 281 .ops = &poodle_ops,
282}; 282};
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 8e1571350630..b253d864868a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -42,6 +42,7 @@
42 42
43static int spitz_jack_func; 43static int spitz_jack_func;
44static int spitz_spk_func; 44static int spitz_spk_func;
45static int spitz_mic_gpio;
45 46
46static void spitz_ext_control(struct snd_soc_codec *codec) 47static void spitz_ext_control(struct snd_soc_codec *codec)
47{ 48{
@@ -217,14 +218,7 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
217static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 218static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
218 struct snd_kcontrol *k, int event) 219 struct snd_kcontrol *k, int event)
219{ 220{
220 if (machine_is_borzoi() || machine_is_spitz()) 221 gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event));
221 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
222 SND_SOC_DAPM_EVENT_ON(event));
223
224 if (machine_is_akita())
225 gpio_set_value(AKITA_GPIO_MIC_BIAS,
226 SND_SOC_DAPM_EVENT_ON(event));
227
228 return 0; 222 return 0;
229} 223}
230 224
@@ -339,22 +333,45 @@ static int __init spitz_init(void)
339 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 333 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
340 return -ENODEV; 334 return -ENODEV;
341 335
336 if (machine_is_borzoi() || machine_is_spitz())
337 spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS;
338 else
339 spitz_mic_gpio = AKITA_GPIO_MIC_BIAS;
340
341 ret = gpio_request(spitz_mic_gpio, "MIC GPIO");
342 if (ret)
343 goto err1;
344
345 ret = gpio_direction_output(spitz_mic_gpio, 0);
346 if (ret)
347 goto err2;
348
342 spitz_snd_device = platform_device_alloc("soc-audio", -1); 349 spitz_snd_device = platform_device_alloc("soc-audio", -1);
343 if (!spitz_snd_device) 350 if (!spitz_snd_device) {
344 return -ENOMEM; 351 ret = -ENOMEM;
352 goto err2;
353 }
345 354
346 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz); 355 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
347 ret = platform_device_add(spitz_snd_device);
348 356
357 ret = platform_device_add(spitz_snd_device);
349 if (ret) 358 if (ret)
350 platform_device_put(spitz_snd_device); 359 goto err3;
360
361 return 0;
351 362
363err3:
364 platform_device_put(spitz_snd_device);
365err2:
366 gpio_free(spitz_mic_gpio);
367err1:
352 return ret; 368 return ret;
353} 369}
354 370
355static void __exit spitz_exit(void) 371static void __exit spitz_exit(void)
356{ 372{
357 platform_device_unregister(spitz_snd_device); 373 platform_device_unregister(spitz_snd_device);
374 gpio_free(spitz_mic_gpio);
358} 375}
359 376
360module_init(spitz_init); 377module_init(spitz_init);
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index a3fdfb631469..459566bfcd35 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -162,3 +162,18 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF
162 select SND_SAMSUNG_SPDIF 162 select SND_SAMSUNG_SPDIF
163 help 163 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
165
166config SND_SOC_SMDK_WM8580_PCM
167 tristate "SoC PCM Audio support for WM8580 on SMDK"
168 depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
169 select SND_SOC_WM8580
170 select SND_SAMSUNG_PCM
171 help
172 Say Y if you want to add support for SoC audio on the SMDK.
173
174config SND_SOC_SPEYSIDE
175 tristate "Audio support for Wolfson Speyside"
176 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
177 select SND_SAMSUNG_I2S
178 select SND_SOC_WM8915
179 select SND_SOC_WM9081
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 294dec05c26d..683843a2744f 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -34,6 +34,8 @@ snd-soc-smdk-wm9713-objs := smdk_wm9713.o
34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o 34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
35snd-soc-goni-wm8994-objs := goni_wm8994.o 35snd-soc-goni-wm8994-objs := goni_wm8994.o
36snd-soc-smdk-spdif-objs := smdk_spdif.o 36snd-soc-smdk-spdif-objs := smdk_spdif.o
37snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
38snd-soc-speyside-objs := speyside.o
37 39
38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -51,3 +53,5 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
51obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o 53obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
52obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o 54obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
53obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o 55obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
56obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
57obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
new file mode 100644
index 000000000000..0d12092df164
--- /dev/null
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -0,0 +1,206 @@
1/*
2 * sound/soc/samsung/smdk_wm8580pcm.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co. Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#include <sound/soc.h>
12#include <sound/pcm_params.h>
13#include <sound/pcm.h>
14
15#include <asm/mach-types.h>
16
17#include "../codecs/wm8580.h"
18#include "dma.h"
19#include "pcm.h"
20
21/*
22 * Board Settings:
23 * o '1' means 'ON'
24 * o '0' means 'OFF'
25 * o 'X' means 'Don't care'
26 *
27 * SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111
28 * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000
29 */
30
31#define SMDK_WM8580_EXT_OSC 12000000
32#define SMDK_WM8580_EXT_MCLK 4096000
33#define SMDK_WM8580_EXT_VOICE 2048000
34
35static unsigned long mclk_freq;
36static unsigned long xtal_freq;
37
38/*
39 * If MCLK clock directly gets from XTAL, we don't have to use PLL
40 * to make MCLK, but if XTAL clock source connects with other codec
41 * pin (like XTI), we should have to set codec's PLL to make MCLK.
42 * Because Samsung SoC does not support pcmcdclk output like I2S.
43 */
44
45static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params)
47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int rfs, ret;
52
53 switch (params_rate(params)) {
54 case 8000:
55 break;
56 default:
57 printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n",
58 __func__, __LINE__, params_rate(params));
59 return -EINVAL;
60 }
61
62 rfs = mclk_freq / params_rate(params) / 2;
63
64 /* Set the codec DAI configuration */
65 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
66 | SND_SOC_DAIFMT_IB_NF
67 | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 /* Set the cpu DAI configuration */
72 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
73 | SND_SOC_DAIFMT_IB_NF
74 | SND_SOC_DAIFMT_CBS_CFS);
75 if (ret < 0)
76 return ret;
77
78 if (mclk_freq == xtal_freq) {
79 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK,
80 mclk_freq, SND_SOC_CLOCK_IN);
81 if (ret < 0)
82 return ret;
83
84 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
85 WM8580_CLKSRC_MCLK);
86 if (ret < 0)
87 return ret;
88 } else {
89 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
90 mclk_freq, SND_SOC_CLOCK_IN);
91 if (ret < 0)
92 return ret;
93
94 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
95 WM8580_CLKSRC_PLLA);
96 if (ret < 0)
97 return ret;
98
99 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
100 xtal_freq, mclk_freq);
101 if (ret < 0)
102 return ret;
103 }
104
105 /* Set PCM source clock on CPU */
106 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
107 mclk_freq, SND_SOC_CLOCK_IN);
108 if (ret < 0)
109 return ret;
110
111 /* Set SCLK_DIV for making bclk */
112 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
113 if (ret < 0)
114 return ret;
115
116 return 0;
117}
118
119static struct snd_soc_ops smdk_wm8580_pcm_ops = {
120 .hw_params = smdk_wm8580_pcm_hw_params,
121};
122
123static struct snd_soc_dai_link smdk_dai[] = {
124 {
125 .name = "WM8580 PAIF PCM RX",
126 .stream_name = "Playback",
127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b",
131 .ops = &smdk_wm8580_pcm_ops,
132 }, {
133 .name = "WM8580 PAIF PCM TX",
134 .stream_name = "Capture",
135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b",
139 .ops = &smdk_wm8580_pcm_ops,
140 },
141};
142
143static struct snd_soc_card smdk_pcm = {
144 .name = "SMDK-PCM",
145 .dai_link = smdk_dai,
146 .num_links = 2,
147};
148
149/*
150 * After SMDKC110 Base Board's Rev is '0.1', 12MHz External OSC(X1)
151 * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4),
152 * 2.0484Mhz, directly with MCLK both Codec and SoC.
153 */
154static int __devinit snd_smdk_probe(struct platform_device *pdev)
155{
156 int ret = 0;
157
158 xtal_freq = SMDK_WM8580_EXT_OSC;
159 mclk_freq = SMDK_WM8580_EXT_MCLK;
160
161 if (machine_is_smdkc110() || machine_is_smdkv210())
162 xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE;
163
164 smdk_pcm.dev = &pdev->dev;
165 ret = snd_soc_register_card(&smdk_pcm);
166 if (ret) {
167 dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
168 return ret;
169 }
170
171 return 0;
172}
173
174static int __devexit snd_smdk_remove(struct platform_device *pdev)
175{
176 snd_soc_unregister_card(&smdk_pcm);
177 platform_set_drvdata(pdev, NULL);
178 return 0;
179}
180
181static struct platform_driver snd_smdk_driver = {
182 .driver = {
183 .owner = THIS_MODULE,
184 .name = "samsung-smdk-pcm",
185 },
186 .probe = snd_smdk_probe,
187 .remove = __devexit_p(snd_smdk_remove),
188};
189
190static int __init smdk_audio_init(void)
191{
192 return platform_driver_register(&snd_smdk_driver);
193}
194
195module_init(smdk_audio_init);
196
197static void __exit smdk_audio_exit(void)
198{
199 platform_driver_unregister(&snd_smdk_driver);
200}
201
202module_exit(smdk_audio_exit);
203
204MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
205MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
206MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
new file mode 100644
index 000000000000..337855a3f2fe
--- /dev/null
+++ b/sound/soc/samsung/speyside.c
@@ -0,0 +1,333 @@
1/*
2 * Speyside audio support
3 *
4 * Copyright 2011 Wolfson Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/jack.h>
15#include <linux/gpio.h>
16
17#include "../codecs/wm8915.h"
18#include "../codecs/wm9081.h"
19
20#define WM8915_HPSEL_GPIO 214
21
22static int speyside_set_bias_level(struct snd_soc_card *card,
23 enum snd_soc_bias_level level)
24{
25 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
26 int ret;
27
28 switch (level) {
29 case SND_SOC_BIAS_STANDBY:
30 ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_MCLK1,
31 32768, SND_SOC_CLOCK_IN);
32 if (ret < 0)
33 return ret;
34
35 ret = snd_soc_dai_set_pll(codec_dai, WM8915_FLL_MCLK1,
36 0, 0, 0);
37 if (ret < 0) {
38 pr_err("Failed to stop FLL\n");
39 return ret;
40 }
41
42 default:
43 break;
44 }
45
46 return 0;
47}
48
49static int speyside_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 int ret;
56
57 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
58 | SND_SOC_DAIFMT_NB_NF
59 | SND_SOC_DAIFMT_CBM_CFM);
60 if (ret < 0)
61 return ret;
62
63 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
64 | SND_SOC_DAIFMT_NB_NF
65 | SND_SOC_DAIFMT_CBM_CFM);
66 if (ret < 0)
67 return ret;
68
69 ret = snd_soc_dai_set_pll(codec_dai, 0, WM8915_FLL_MCLK1,
70 32768, 256 * 48000);
71 if (ret < 0)
72 return ret;
73
74 ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_FLL,
75 256 * 48000, SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78
79 return 0;
80}
81
82static struct snd_soc_ops speyside_ops = {
83 .hw_params = speyside_hw_params,
84};
85
86static struct snd_soc_jack speyside_headset;
87
88/* Headset jack detection DAPM pins */
89static struct snd_soc_jack_pin speyside_headset_pins[] = {
90 {
91 .pin = "Headset Mic",
92 .mask = SND_JACK_MICROPHONE,
93 },
94 {
95 .pin = "Headphone",
96 .mask = SND_JACK_HEADPHONE,
97 },
98};
99
100/* Default the headphone selection to active high */
101static int speyside_jack_polarity;
102
103static int speyside_get_micbias(struct snd_soc_dapm_widget *source,
104 struct snd_soc_dapm_widget *sink)
105{
106 if (speyside_jack_polarity && (strcmp(source->name, "MICB1") == 0))
107 return 1;
108 if (!speyside_jack_polarity && (strcmp(source->name, "MICB2") == 0))
109 return 1;
110
111 return 0;
112}
113
114static void speyside_set_polarity(struct snd_soc_codec *codec,
115 int polarity)
116{
117 speyside_jack_polarity = !polarity;
118 gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
119
120 /* Re-run DAPM to make sure we're using the correct mic bias */
121 snd_soc_dapm_sync(&codec->dapm);
122}
123
124static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd)
125{
126 struct snd_soc_dai *dai = rtd->codec_dai;
127 struct snd_soc_codec *codec = rtd->codec;
128 int ret;
129
130 ret = snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK1, 32768, 0);
131 if (ret < 0)
132 return ret;
133
134 ret = gpio_request(WM8915_HPSEL_GPIO, "HP_SEL");
135 if (ret != 0)
136 pr_err("Failed to request HP_SEL GPIO: %d\n", ret);
137 gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity);
138
139 ret = snd_soc_jack_new(codec, "Headset",
140 SND_JACK_HEADSET | SND_JACK_BTN_0,
141 &speyside_headset);
142 if (ret)
143 return ret;
144
145 ret = snd_soc_jack_add_pins(&speyside_headset,
146 ARRAY_SIZE(speyside_headset_pins),
147 speyside_headset_pins);
148 if (ret)
149 return ret;
150
151 wm8915_detect(codec, &speyside_headset, speyside_set_polarity);
152
153 return 0;
154}
155
156static int speyside_late_probe(struct snd_soc_card *card)
157{
158 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
159 snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic");
160 snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC");
161 snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC");
162 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
163 snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output");
164 snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input");
165
166 return 0;
167}
168
169static struct snd_soc_dai_link speyside_dai[] = {
170 {
171 .name = "CPU",
172 .stream_name = "CPU",
173 .cpu_dai_name = "samsung-i2s.0",
174 .codec_dai_name = "wm8915-aif1",
175 .platform_name = "samsung-audio",
176 .codec_name = "wm8915.1-001a",
177 .init = speyside_wm8915_init,
178 .ops = &speyside_ops,
179 },
180 {
181 .name = "Baseband",
182 .stream_name = "Baseband",
183 .cpu_dai_name = "wm8915-aif2",
184 .codec_dai_name = "wm1250-ev1",
185 .codec_name = "wm1250-ev1.1-0027",
186 .platform_name = "samsung-audio",
187 .ops = &speyside_ops,
188 .ignore_suspend = 1,
189 },
190};
191
192static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm)
193{
194 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
195
196 /* At any time the WM9081 is active it will have this clock */
197 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK,
198 48000 * 256, 0);
199}
200
201static struct snd_soc_aux_dev speyside_aux_dev[] = {
202 {
203 .name = "wm9081",
204 .codec_name = "wm9081.1-006c",
205 .init = speyside_wm9081_init,
206 },
207};
208
209static struct snd_soc_codec_conf speyside_codec_conf[] = {
210 {
211 .dev_name = "wm9081.1-006c",
212 .name_prefix = "Sub",
213 },
214};
215
216static const struct snd_kcontrol_new controls[] = {
217 SOC_DAPM_PIN_SWITCH("Main Speaker"),
218 SOC_DAPM_PIN_SWITCH("Main DMIC"),
219 SOC_DAPM_PIN_SWITCH("Main AMIC"),
220 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
221 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
222};
223
224static struct snd_soc_dapm_widget widgets[] = {
225 SND_SOC_DAPM_HP("Headphone", NULL),
226 SND_SOC_DAPM_MIC("Headset Mic", NULL),
227
228 SND_SOC_DAPM_SPK("Main Speaker", NULL),
229
230 SND_SOC_DAPM_MIC("Main AMIC", NULL),
231 SND_SOC_DAPM_MIC("Main DMIC", NULL),
232};
233
234static struct snd_soc_dapm_route audio_paths[] = {
235 { "IN1RN", NULL, "MICB1" },
236 { "IN1RP", NULL, "MICB1" },
237 { "IN1RN", NULL, "MICB2" },
238 { "IN1RP", NULL, "MICB2" },
239 { "MICB1", NULL, "Headset Mic", speyside_get_micbias },
240 { "MICB2", NULL, "Headset Mic", speyside_get_micbias },
241
242 { "IN1LP", NULL, "MICB2" },
243 { "IN1RN", NULL, "MICB1" },
244 { "MICB2", NULL, "Main AMIC" },
245
246 { "DMIC1DAT", NULL, "MICB1" },
247 { "DMIC2DAT", NULL, "MICB1" },
248 { "MICB1", NULL, "Main DMIC" },
249
250 { "Headphone", NULL, "HPOUT1L" },
251 { "Headphone", NULL, "HPOUT1R" },
252
253 { "Sub IN1", NULL, "HPOUT2L" },
254 { "Sub IN2", NULL, "HPOUT2R" },
255
256 { "Main Speaker", NULL, "Sub SPKN" },
257 { "Main Speaker", NULL, "Sub SPKP" },
258 { "Main Speaker", NULL, "SPKDAT" },
259};
260
261static struct snd_soc_card speyside = {
262 .name = "Speyside",
263 .dai_link = speyside_dai,
264 .num_links = ARRAY_SIZE(speyside_dai),
265 .aux_dev = speyside_aux_dev,
266 .num_aux_devs = ARRAY_SIZE(speyside_aux_dev),
267 .codec_conf = speyside_codec_conf,
268 .num_configs = ARRAY_SIZE(speyside_codec_conf),
269
270 .set_bias_level = speyside_set_bias_level,
271
272 .controls = controls,
273 .num_controls = ARRAY_SIZE(controls),
274 .dapm_widgets = widgets,
275 .num_dapm_widgets = ARRAY_SIZE(widgets),
276 .dapm_routes = audio_paths,
277 .num_dapm_routes = ARRAY_SIZE(audio_paths),
278
279 .late_probe = speyside_late_probe,
280};
281
282static __devinit int speyside_probe(struct platform_device *pdev)
283{
284 struct snd_soc_card *card = &speyside;
285 int ret;
286
287 card->dev = &pdev->dev;
288
289 ret = snd_soc_register_card(card);
290 if (ret) {
291 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
292 ret);
293 return ret;
294 }
295
296 return 0;
297}
298
299static int __devexit speyside_remove(struct platform_device *pdev)
300{
301 struct snd_soc_card *card = platform_get_drvdata(pdev);
302
303 snd_soc_unregister_card(card);
304
305 return 0;
306}
307
308static struct platform_driver speyside_driver = {
309 .driver = {
310 .name = "speyside",
311 .owner = THIS_MODULE,
312 .pm = &snd_soc_pm_ops,
313 },
314 .probe = speyside_probe,
315 .remove = __devexit_p(speyside_remove),
316};
317
318static int __init speyside_audio_init(void)
319{
320 return platform_driver_register(&speyside_driver);
321}
322module_init(speyside_audio_init);
323
324static void __exit speyside_audio_exit(void)
325{
326 platform_driver_unregister(&speyside_driver);
327}
328module_exit(speyside_audio_exit);
329
330MODULE_DESCRIPTION("Speyside audio support");
331MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
332MODULE_LICENSE("GPL");
333MODULE_ALIAS("platform:speyside");
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 5d76da43b14c..f46a198a48c0 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -20,40 +20,38 @@
20 20
21#include <trace/events/asoc.h> 21#include <trace/events/asoc.h>
22 22
23static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 23#if defined(CONFIG_SPI_MASTER)
24 unsigned int reg) 24static int do_spi_write(void *control_data, const void *msg,
25 int len)
25{ 26{
26 int ret; 27 struct spi_device *spi = control_data;
27 unsigned int val; 28 struct spi_transfer t;
29 struct spi_message m;
28 30
29 if (reg >= codec->driver->reg_cache_size || 31 if (len <= 0)
30 snd_soc_codec_volatile_register(codec, reg) || 32 return 0;
31 codec->cache_bypass) {
32 if (codec->cache_only)
33 return -1;
34 33
35 BUG_ON(!codec->hw_read); 34 spi_message_init(&m);
36 return codec->hw_read(codec, reg); 35 memset(&t, 0, sizeof t);
37 }
38 36
39 ret = snd_soc_cache_read(codec, reg, &val); 37 t.tx_buf = msg;
40 if (ret < 0) 38 t.len = len;
41 return -1; 39
42 return val; 40 spi_message_add_tail(&t, &m);
41 spi_sync(spi, &m);
42
43 return len;
43} 44}
45#endif
44 46
45static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, 47static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value) 48 unsigned int value, const void *data, int len)
47{ 49{
48 u8 data[2];
49 int ret; 50 int ret;
50 51
51 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
52 data[1] = value & 0x00ff;
53
54 if (!snd_soc_codec_volatile_register(codec, reg) && 52 if (!snd_soc_codec_volatile_register(codec, reg) &&
55 reg < codec->driver->reg_cache_size && 53 reg < codec->driver->reg_cache_size &&
56 !codec->cache_bypass) { 54 !codec->cache_bypass) {
57 ret = snd_soc_cache_write(codec, reg, value); 55 ret = snd_soc_cache_write(codec, reg, value);
58 if (ret < 0) 56 if (ret < 0)
59 return -1; 57 return -1;
@@ -64,8 +62,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
64 return 0; 62 return 0;
65 } 63 }
66 64
67 ret = codec->hw_write(codec->control_data, data, 2); 65 ret = codec->hw_write(codec->control_data, data, len);
68 if (ret == 2) 66 if (ret == len)
69 return 0; 67 return 0;
70 if (ret < 0) 68 if (ret < 0)
71 return ret; 69 return ret;
@@ -73,31 +71,54 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
73 return -EIO; 71 return -EIO;
74} 72}
75 73
74static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg)
75{
76 int ret;
77 unsigned int val;
78
79 if (reg >= codec->driver->reg_cache_size ||
80 snd_soc_codec_volatile_register(codec, reg) ||
81 codec->cache_bypass) {
82 if (codec->cache_only)
83 return -1;
84
85 BUG_ON(!codec->hw_read);
86 return codec->hw_read(codec, reg);
87 }
88
89 ret = snd_soc_cache_read(codec, reg, &val);
90 if (ret < 0)
91 return -1;
92 return val;
93}
94
95static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
96 unsigned int reg)
97{
98 return do_hw_read(codec, reg);
99}
100
101static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
102 unsigned int value)
103{
104 u8 data[2];
105
106 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
107 data[1] = value & 0x00ff;
108
109 return do_hw_write(codec, reg, value, data, 2);
110}
111
76#if defined(CONFIG_SPI_MASTER) 112#if defined(CONFIG_SPI_MASTER)
77static int snd_soc_4_12_spi_write(void *control_data, const char *data, 113static int snd_soc_4_12_spi_write(void *control_data, const char *data,
78 int len) 114 int len)
79{ 115{
80 struct spi_device *spi = control_data;
81 struct spi_transfer t;
82 struct spi_message m;
83 u8 msg[2]; 116 u8 msg[2];
84 117
85 if (len <= 0)
86 return 0;
87
88 msg[0] = data[1]; 118 msg[0] = data[1];
89 msg[1] = data[0]; 119 msg[1] = data[0];
90 120
91 spi_message_init(&m); 121 return do_spi_write(control_data, msg, len);
92 memset(&t, 0, sizeof t);
93
94 t.tx_buf = &msg[0];
95 t.len = len;
96
97 spi_message_add_tail(&t, &m);
98 spi_sync(spi, &m);
99
100 return len;
101} 122}
102#else 123#else
103#define snd_soc_4_12_spi_write NULL 124#define snd_soc_4_12_spi_write NULL
@@ -106,81 +127,30 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
106static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 127static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
107 unsigned int reg) 128 unsigned int reg)
108{ 129{
109 int ret; 130 return do_hw_read(codec, reg);
110 unsigned int val;
111
112 if (reg >= codec->driver->reg_cache_size ||
113 snd_soc_codec_volatile_register(codec, reg) ||
114 codec->cache_bypass) {
115 if (codec->cache_only)
116 return -1;
117
118 BUG_ON(!codec->hw_read);
119 return codec->hw_read(codec, reg);
120 }
121
122 ret = snd_soc_cache_read(codec, reg, &val);
123 if (ret < 0)
124 return -1;
125 return val;
126} 131}
127 132
128static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, 133static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
129 unsigned int value) 134 unsigned int value)
130{ 135{
131 u8 data[2]; 136 u8 data[2];
132 int ret;
133 137
134 data[0] = (reg << 1) | ((value >> 8) & 0x0001); 138 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
135 data[1] = value & 0x00ff; 139 data[1] = value & 0x00ff;
136 140
137 if (!snd_soc_codec_volatile_register(codec, reg) && 141 return do_hw_write(codec, reg, value, data, 2);
138 reg < codec->driver->reg_cache_size &&
139 !codec->cache_bypass) {
140 ret = snd_soc_cache_write(codec, reg, value);
141 if (ret < 0)
142 return -1;
143 }
144
145 if (codec->cache_only) {
146 codec->cache_sync = 1;
147 return 0;
148 }
149
150 ret = codec->hw_write(codec->control_data, data, 2);
151 if (ret == 2)
152 return 0;
153 if (ret < 0)
154 return ret;
155 else
156 return -EIO;
157} 142}
158 143
159#if defined(CONFIG_SPI_MASTER) 144#if defined(CONFIG_SPI_MASTER)
160static int snd_soc_7_9_spi_write(void *control_data, const char *data, 145static int snd_soc_7_9_spi_write(void *control_data, const char *data,
161 int len) 146 int len)
162{ 147{
163 struct spi_device *spi = control_data;
164 struct spi_transfer t;
165 struct spi_message m;
166 u8 msg[2]; 148 u8 msg[2];
167 149
168 if (len <= 0)
169 return 0;
170
171 msg[0] = data[0]; 150 msg[0] = data[0];
172 msg[1] = data[1]; 151 msg[1] = data[1];
173 152
174 spi_message_init(&m); 153 return do_spi_write(control_data, msg, len);
175 memset(&t, 0, sizeof t);
176
177 t.tx_buf = &msg[0];
178 t.len = len;
179
180 spi_message_add_tail(&t, &m);
181 spi_sync(spi, &m);
182
183 return len;
184} 154}
185#else 155#else
186#define snd_soc_7_9_spi_write NULL 156#define snd_soc_7_9_spi_write NULL
@@ -190,79 +160,30 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
190 unsigned int value) 160 unsigned int value)
191{ 161{
192 u8 data[2]; 162 u8 data[2];
193 int ret;
194 163
195 reg &= 0xff; 164 reg &= 0xff;
196 data[0] = reg; 165 data[0] = reg;
197 data[1] = value & 0xff; 166 data[1] = value & 0xff;
198 167
199 if (!snd_soc_codec_volatile_register(codec, reg) && 168 return do_hw_write(codec, reg, value, data, 2);
200 reg < codec->driver->reg_cache_size &&
201 !codec->cache_bypass) {
202 ret = snd_soc_cache_write(codec, reg, value);
203 if (ret < 0)
204 return -1;
205 }
206
207 if (codec->cache_only) {
208 codec->cache_sync = 1;
209 return 0;
210 }
211
212 if (codec->hw_write(codec->control_data, data, 2) == 2)
213 return 0;
214 else
215 return -EIO;
216} 169}
217 170
218static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, 171static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
219 unsigned int reg) 172 unsigned int reg)
220{ 173{
221 int ret; 174 return do_hw_read(codec, reg);
222 unsigned int val;
223
224 reg &= 0xff;
225 if (reg >= codec->driver->reg_cache_size ||
226 snd_soc_codec_volatile_register(codec, reg) ||
227 codec->cache_bypass) {
228 if (codec->cache_only)
229 return -1;
230
231 BUG_ON(!codec->hw_read);
232 return codec->hw_read(codec, reg);
233 }
234
235 ret = snd_soc_cache_read(codec, reg, &val);
236 if (ret < 0)
237 return -1;
238 return val;
239} 175}
240 176
241#if defined(CONFIG_SPI_MASTER) 177#if defined(CONFIG_SPI_MASTER)
242static int snd_soc_8_8_spi_write(void *control_data, const char *data, 178static int snd_soc_8_8_spi_write(void *control_data, const char *data,
243 int len) 179 int len)
244{ 180{
245 struct spi_device *spi = control_data;
246 struct spi_transfer t;
247 struct spi_message m;
248 u8 msg[2]; 181 u8 msg[2];
249 182
250 if (len <= 0)
251 return 0;
252
253 msg[0] = data[0]; 183 msg[0] = data[0];
254 msg[1] = data[1]; 184 msg[1] = data[1];
255 185
256 spi_message_init(&m); 186 return do_spi_write(control_data, msg, len);
257 memset(&t, 0, sizeof t);
258
259 t.tx_buf = &msg[0];
260 t.len = len;
261
262 spi_message_add_tail(&t, &m);
263 spi_sync(spi, &m);
264
265 return len;
266} 187}
267#else 188#else
268#define snd_soc_8_8_spi_write NULL 189#define snd_soc_8_8_spi_write NULL
@@ -272,112 +193,78 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
272 unsigned int value) 193 unsigned int value)
273{ 194{
274 u8 data[3]; 195 u8 data[3];
275 int ret;
276 196
277 data[0] = reg; 197 data[0] = reg;
278 data[1] = (value >> 8) & 0xff; 198 data[1] = (value >> 8) & 0xff;
279 data[2] = value & 0xff; 199 data[2] = value & 0xff;
280 200
281 if (!snd_soc_codec_volatile_register(codec, reg) && 201 return do_hw_write(codec, reg, value, data, 3);
282 reg < codec->driver->reg_cache_size &&
283 !codec->cache_bypass) {
284 ret = snd_soc_cache_write(codec, reg, value);
285 if (ret < 0)
286 return -1;
287 }
288
289 if (codec->cache_only) {
290 codec->cache_sync = 1;
291 return 0;
292 }
293
294 if (codec->hw_write(codec->control_data, data, 3) == 3)
295 return 0;
296 else
297 return -EIO;
298} 202}
299 203
300static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, 204static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
301 unsigned int reg) 205 unsigned int reg)
302{ 206{
303 int ret; 207 return do_hw_read(codec, reg);
304 unsigned int val;
305
306 if (reg >= codec->driver->reg_cache_size ||
307 snd_soc_codec_volatile_register(codec, reg) ||
308 codec->cache_bypass) {
309 if (codec->cache_only)
310 return -1;
311
312 BUG_ON(!codec->hw_read);
313 return codec->hw_read(codec, reg);
314 }
315
316 ret = snd_soc_cache_read(codec, reg, &val);
317 if (ret < 0)
318 return -1;
319 return val;
320} 208}
321 209
322#if defined(CONFIG_SPI_MASTER) 210#if defined(CONFIG_SPI_MASTER)
323static int snd_soc_8_16_spi_write(void *control_data, const char *data, 211static int snd_soc_8_16_spi_write(void *control_data, const char *data,
324 int len) 212 int len)
325{ 213{
326 struct spi_device *spi = control_data;
327 struct spi_transfer t;
328 struct spi_message m;
329 u8 msg[3]; 214 u8 msg[3];
330 215
331 if (len <= 0)
332 return 0;
333
334 msg[0] = data[0]; 216 msg[0] = data[0];
335 msg[1] = data[1]; 217 msg[1] = data[1];
336 msg[2] = data[2]; 218 msg[2] = data[2];
337 219
338 spi_message_init(&m); 220 return do_spi_write(control_data, msg, len);
339 memset(&t, 0, sizeof t);
340
341 t.tx_buf = &msg[0];
342 t.len = len;
343
344 spi_message_add_tail(&t, &m);
345 spi_sync(spi, &m);
346
347 return len;
348} 221}
349#else 222#else
350#define snd_soc_8_16_spi_write NULL 223#define snd_soc_8_16_spi_write NULL
351#endif 224#endif
352 225
353#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 226#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
354static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, 227static unsigned int do_i2c_read(struct snd_soc_codec *codec,
355 unsigned int r) 228 void *reg, int reglen,
229 void *data, int datalen)
356{ 230{
357 struct i2c_msg xfer[2]; 231 struct i2c_msg xfer[2];
358 u8 reg = r;
359 u8 data;
360 int ret; 232 int ret;
361 struct i2c_client *client = codec->control_data; 233 struct i2c_client *client = codec->control_data;
362 234
363 /* Write register */ 235 /* Write register */
364 xfer[0].addr = client->addr; 236 xfer[0].addr = client->addr;
365 xfer[0].flags = 0; 237 xfer[0].flags = 0;
366 xfer[0].len = 1; 238 xfer[0].len = reglen;
367 xfer[0].buf = &reg; 239 xfer[0].buf = reg;
368 240
369 /* Read data */ 241 /* Read data */
370 xfer[1].addr = client->addr; 242 xfer[1].addr = client->addr;
371 xfer[1].flags = I2C_M_RD; 243 xfer[1].flags = I2C_M_RD;
372 xfer[1].len = 1; 244 xfer[1].len = datalen;
373 xfer[1].buf = &data; 245 xfer[1].buf = data;
374 246
375 ret = i2c_transfer(client->adapter, xfer, 2); 247 ret = i2c_transfer(client->adapter, xfer, 2);
376 if (ret != 2) { 248 if (ret == 2)
377 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
378 return 0; 249 return 0;
379 } 250 else if (ret < 0)
251 return ret;
252 else
253 return -EIO;
254}
255#endif
256
257#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
258static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
259 unsigned int r)
260{
261 u8 reg = r;
262 u8 data;
263 int ret;
380 264
265 ret = do_i2c_read(codec, &reg, 1, &data, 1);
266 if (ret < 0)
267 return 0;
381 return data; 268 return data;
382} 269}
383#else 270#else
@@ -388,30 +275,13 @@ static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
388static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 275static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
389 unsigned int r) 276 unsigned int r)
390{ 277{
391 struct i2c_msg xfer[2];
392 u8 reg = r; 278 u8 reg = r;
393 u16 data; 279 u16 data;
394 int ret; 280 int ret;
395 struct i2c_client *client = codec->control_data;
396 281
397 /* Write register */ 282 ret = do_i2c_read(codec, &reg, 1, &data, 2);
398 xfer[0].addr = client->addr; 283 if (ret < 0)
399 xfer[0].flags = 0;
400 xfer[0].len = 1;
401 xfer[0].buf = &reg;
402
403 /* Read data */
404 xfer[1].addr = client->addr;
405 xfer[1].flags = I2C_M_RD;
406 xfer[1].len = 2;
407 xfer[1].buf = (u8 *)&data;
408
409 ret = i2c_transfer(client->adapter, xfer, 2);
410 if (ret != 2) {
411 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
412 return 0; 284 return 0;
413 }
414
415 return (data >> 8) | ((data & 0xff) << 8); 285 return (data >> 8) | ((data & 0xff) << 8);
416} 286}
417#else 287#else
@@ -422,30 +292,13 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
422static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, 292static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
423 unsigned int r) 293 unsigned int r)
424{ 294{
425 struct i2c_msg xfer[2];
426 u16 reg = r; 295 u16 reg = r;
427 u8 data; 296 u8 data;
428 int ret; 297 int ret;
429 struct i2c_client *client = codec->control_data;
430
431 /* Write register */
432 xfer[0].addr = client->addr;
433 xfer[0].flags = 0;
434 xfer[0].len = 2;
435 xfer[0].buf = (u8 *)&reg;
436
437 /* Read data */
438 xfer[1].addr = client->addr;
439 xfer[1].flags = I2C_M_RD;
440 xfer[1].len = 1;
441 xfer[1].buf = &data;
442 298
443 ret = i2c_transfer(client->adapter, xfer, 2); 299 ret = do_i2c_read(codec, &reg, 2, &data, 1);
444 if (ret != 2) { 300 if (ret < 0)
445 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
446 return 0; 301 return 0;
447 }
448
449 return data; 302 return data;
450} 303}
451#else 304#else
@@ -453,87 +306,35 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
453#endif 306#endif
454 307
455static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 308static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
456 unsigned int reg) 309 unsigned int reg)
457{ 310{
458 int ret; 311 return do_hw_read(codec, reg);
459 unsigned int val;
460
461 reg &= 0xff;
462 if (reg >= codec->driver->reg_cache_size ||
463 snd_soc_codec_volatile_register(codec, reg) ||
464 codec->cache_bypass) {
465 if (codec->cache_only)
466 return -1;
467
468 BUG_ON(!codec->hw_read);
469 return codec->hw_read(codec, reg);
470 }
471
472 ret = snd_soc_cache_read(codec, reg, &val);
473 if (ret < 0)
474 return -1;
475 return val;
476} 312}
477 313
478static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 314static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
479 unsigned int value) 315 unsigned int value)
480{ 316{
481 u8 data[3]; 317 u8 data[3];
482 int ret;
483 318
484 data[0] = (reg >> 8) & 0xff; 319 data[0] = (reg >> 8) & 0xff;
485 data[1] = reg & 0xff; 320 data[1] = reg & 0xff;
486 data[2] = value; 321 data[2] = value;
487
488 reg &= 0xff; 322 reg &= 0xff;
489 if (!snd_soc_codec_volatile_register(codec, reg) &&
490 reg < codec->driver->reg_cache_size &&
491 !codec->cache_bypass) {
492 ret = snd_soc_cache_write(codec, reg, value);
493 if (ret < 0)
494 return -1;
495 }
496 323
497 if (codec->cache_only) { 324 return do_hw_write(codec, reg, value, data, 3);
498 codec->cache_sync = 1;
499 return 0;
500 }
501
502 ret = codec->hw_write(codec->control_data, data, 3);
503 if (ret == 3)
504 return 0;
505 if (ret < 0)
506 return ret;
507 else
508 return -EIO;
509} 325}
510 326
511#if defined(CONFIG_SPI_MASTER) 327#if defined(CONFIG_SPI_MASTER)
512static int snd_soc_16_8_spi_write(void *control_data, const char *data, 328static int snd_soc_16_8_spi_write(void *control_data, const char *data,
513 int len) 329 int len)
514{ 330{
515 struct spi_device *spi = control_data;
516 struct spi_transfer t;
517 struct spi_message m;
518 u8 msg[3]; 331 u8 msg[3];
519 332
520 if (len <= 0)
521 return 0;
522
523 msg[0] = data[0]; 333 msg[0] = data[0];
524 msg[1] = data[1]; 334 msg[1] = data[1];
525 msg[2] = data[2]; 335 msg[2] = data[2];
526 336
527 spi_message_init(&m); 337 return do_spi_write(control_data, msg, len);
528 memset(&t, 0, sizeof t);
529
530 t.tx_buf = &msg[0];
531 t.len = len;
532
533 spi_message_add_tail(&t, &m);
534 spi_sync(spi, &m);
535
536 return len;
537} 338}
538#else 339#else
539#define snd_soc_16_8_spi_write NULL 340#define snd_soc_16_8_spi_write NULL
@@ -543,30 +344,13 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
543static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, 344static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
544 unsigned int r) 345 unsigned int r)
545{ 346{
546 struct i2c_msg xfer[2];
547 u16 reg = cpu_to_be16(r); 347 u16 reg = cpu_to_be16(r);
548 u16 data; 348 u16 data;
549 int ret; 349 int ret;
550 struct i2c_client *client = codec->control_data;
551
552 /* Write register */
553 xfer[0].addr = client->addr;
554 xfer[0].flags = 0;
555 xfer[0].len = 2;
556 xfer[0].buf = (u8 *)&reg;
557 350
558 /* Read data */ 351 ret = do_i2c_read(codec, &reg, 2, &data, 2);
559 xfer[1].addr = client->addr; 352 if (ret < 0)
560 xfer[1].flags = I2C_M_RD;
561 xfer[1].len = 2;
562 xfer[1].buf = (u8 *)&data;
563
564 ret = i2c_transfer(client->adapter, xfer, 2);
565 if (ret != 2) {
566 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
567 return 0; 353 return 0;
568 }
569
570 return be16_to_cpu(data); 354 return be16_to_cpu(data);
571} 355}
572#else 356#else
@@ -576,91 +360,82 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
576static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, 360static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
577 unsigned int reg) 361 unsigned int reg)
578{ 362{
579 int ret; 363 return do_hw_read(codec, reg);
580 unsigned int val;
581
582 if (reg >= codec->driver->reg_cache_size ||
583 snd_soc_codec_volatile_register(codec, reg) ||
584 codec->cache_bypass) {
585 if (codec->cache_only)
586 return -1;
587
588 BUG_ON(!codec->hw_read);
589 return codec->hw_read(codec, reg);
590 }
591
592 ret = snd_soc_cache_read(codec, reg, &val);
593 if (ret < 0)
594 return -1;
595
596 return val;
597} 364}
598 365
599static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, 366static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
600 unsigned int value) 367 unsigned int value)
601{ 368{
602 u8 data[4]; 369 u8 data[4];
603 int ret;
604 370
605 data[0] = (reg >> 8) & 0xff; 371 data[0] = (reg >> 8) & 0xff;
606 data[1] = reg & 0xff; 372 data[1] = reg & 0xff;
607 data[2] = (value >> 8) & 0xff; 373 data[2] = (value >> 8) & 0xff;
608 data[3] = value & 0xff; 374 data[3] = value & 0xff;
609 375
610 if (!snd_soc_codec_volatile_register(codec, reg) && 376 return do_hw_write(codec, reg, value, data, 4);
611 reg < codec->driver->reg_cache_size &&
612 !codec->cache_bypass) {
613 ret = snd_soc_cache_write(codec, reg, value);
614 if (ret < 0)
615 return -1;
616 }
617
618 if (codec->cache_only) {
619 codec->cache_sync = 1;
620 return 0;
621 }
622
623 ret = codec->hw_write(codec->control_data, data, 4);
624 if (ret == 4)
625 return 0;
626 if (ret < 0)
627 return ret;
628 else
629 return -EIO;
630} 377}
631 378
632#if defined(CONFIG_SPI_MASTER) 379#if defined(CONFIG_SPI_MASTER)
633static int snd_soc_16_16_spi_write(void *control_data, const char *data, 380static int snd_soc_16_16_spi_write(void *control_data, const char *data,
634 int len) 381 int len)
635{ 382{
636 struct spi_device *spi = control_data;
637 struct spi_transfer t;
638 struct spi_message m;
639 u8 msg[4]; 383 u8 msg[4];
640 384
641 if (len <= 0)
642 return 0;
643
644 msg[0] = data[0]; 385 msg[0] = data[0];
645 msg[1] = data[1]; 386 msg[1] = data[1];
646 msg[2] = data[2]; 387 msg[2] = data[2];
647 msg[3] = data[3]; 388 msg[3] = data[3];
648 389
649 spi_message_init(&m); 390 return do_spi_write(control_data, msg, len);
650 memset(&t, 0, sizeof t);
651
652 t.tx_buf = &msg[0];
653 t.len = len;
654
655 spi_message_add_tail(&t, &m);
656 spi_sync(spi, &m);
657
658 return len;
659} 391}
660#else 392#else
661#define snd_soc_16_16_spi_write NULL 393#define snd_soc_16_16_spi_write NULL
662#endif 394#endif
663 395
396/* Primitive bulk write support for soc-cache. The data pointed to by
397 * `data' needs to already be in the form the hardware expects
398 * including any leading register specific data. Any data written
399 * through this function will not go through the cache as it only
400 * handles writing to volatile or out of bounds registers.
401 */
402static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg,
403 const void *data, size_t len)
404{
405 int ret;
406
407 /* Ensure that the base register is volatile. Subsequently
408 * any other register that is touched by this routine should be
409 * volatile as well to ensure that we don't get out of sync with
410 * the cache.
411 */
412 if (!snd_soc_codec_volatile_register(codec, reg)
413 && reg < codec->driver->reg_cache_size)
414 return -EINVAL;
415
416 switch (codec->control_type) {
417#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
418 case SND_SOC_I2C:
419 ret = i2c_master_send(codec->control_data, data, len);
420 break;
421#endif
422#if defined(CONFIG_SPI_MASTER)
423 case SND_SOC_SPI:
424 ret = do_spi_write(codec->control_data, data, len);
425 break;
426#endif
427 default:
428 BUG();
429 }
430
431 if (ret == len)
432 return 0;
433 if (ret < 0)
434 return ret;
435 else
436 return -EIO;
437}
438
664static struct { 439static struct {
665 int addr_bits; 440 int addr_bits;
666 int data_bits; 441 int data_bits;
@@ -744,6 +519,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
744 519
745 codec->write = io_types[i].write; 520 codec->write = io_types[i].write;
746 codec->read = io_types[i].read; 521 codec->read = io_types[i].read;
522 codec->bulk_write_raw = snd_soc_hw_bulk_write_raw;
747 523
748 switch (control) { 524 switch (control) {
749 case SND_SOC_CUSTOM: 525 case SND_SOC_CUSTOM:
@@ -889,6 +665,8 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
889 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); 665 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
890 if (rbnode->value == rbnode->defval) 666 if (rbnode->value == rbnode->defval)
891 continue; 667 continue;
668 WARN_ON(codec->writable_register &&
669 codec->writable_register(codec, rbnode->reg));
892 ret = snd_soc_cache_read(codec, rbnode->reg, &val); 670 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
893 if (ret) 671 if (ret)
894 return ret; 672 return ret;
@@ -1149,6 +927,8 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1149 927
1150 lzo_blocks = codec->reg_cache; 928 lzo_blocks = codec->reg_cache;
1151 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { 929 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
930 WARN_ON(codec->writable_register &&
931 codec->writable_register(codec, i));
1152 ret = snd_soc_cache_read(codec, i, &val); 932 ret = snd_soc_cache_read(codec, i, &val);
1153 if (ret) 933 if (ret)
1154 return ret; 934 return ret;
@@ -1407,6 +1187,8 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1407 1187
1408 codec_drv = codec->driver; 1188 codec_drv = codec->driver;
1409 for (i = 0; i < codec_drv->reg_cache_size; ++i) { 1189 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1190 WARN_ON(codec->writable_register &&
1191 codec->writable_register(codec, i));
1410 ret = snd_soc_cache_read(codec, i, &val); 1192 ret = snd_soc_cache_read(codec, i, &val);
1411 if (ret) 1193 if (ret)
1412 return ret; 1194 return ret;
@@ -1523,7 +1305,7 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
1523 codec->cache_ops->name, codec->name); 1305 codec->cache_ops->name, codec->name);
1524 return codec->cache_ops->init(codec); 1306 return codec->cache_ops->init(codec);
1525 } 1307 }
1526 return -EINVAL; 1308 return -ENOSYS;
1527} 1309}
1528 1310
1529/* 1311/*
@@ -1538,7 +1320,7 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
1538 codec->cache_ops->name, codec->name); 1320 codec->cache_ops->name, codec->name);
1539 return codec->cache_ops->exit(codec); 1321 return codec->cache_ops->exit(codec);
1540 } 1322 }
1541 return -EINVAL; 1323 return -ENOSYS;
1542} 1324}
1543 1325
1544/** 1326/**
@@ -1562,7 +1344,7 @@ int snd_soc_cache_read(struct snd_soc_codec *codec,
1562 } 1344 }
1563 1345
1564 mutex_unlock(&codec->cache_rw_mutex); 1346 mutex_unlock(&codec->cache_rw_mutex);
1565 return -EINVAL; 1347 return -ENOSYS;
1566} 1348}
1567EXPORT_SYMBOL_GPL(snd_soc_cache_read); 1349EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1568 1350
@@ -1587,7 +1369,7 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
1587 } 1369 }
1588 1370
1589 mutex_unlock(&codec->cache_rw_mutex); 1371 mutex_unlock(&codec->cache_rw_mutex);
1590 return -EINVAL; 1372 return -ENOSYS;
1591} 1373}
1592EXPORT_SYMBOL_GPL(snd_soc_cache_write); 1374EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1593 1375
@@ -1610,7 +1392,7 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
1610 } 1392 }
1611 1393
1612 if (!codec->cache_ops || !codec->cache_ops->sync) 1394 if (!codec->cache_ops || !codec->cache_ops->sync)
1613 return -EINVAL; 1395 return -ENOSYS;
1614 1396
1615 if (codec->cache_ops->name) 1397 if (codec->cache_ops->name)
1616 name = codec->cache_ops->name; 1398 name = codec->cache_ops->name;
@@ -1677,3 +1459,17 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec,
1677 return codec->driver->reg_access_default[index].read; 1459 return codec->driver->reg_access_default[index].read;
1678} 1460}
1679EXPORT_SYMBOL_GPL(snd_soc_default_readable_register); 1461EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
1462
1463int snd_soc_default_writable_register(struct snd_soc_codec *codec,
1464 unsigned int reg)
1465{
1466 int index;
1467
1468 if (reg >= codec->driver->reg_cache_size)
1469 return 1;
1470 index = snd_soc_get_reg_access_index(codec, reg);
1471 if (index < 0)
1472 return 0;
1473 return codec->driver->reg_access_default[index].write;
1474}
1475EXPORT_SYMBOL_GPL(snd_soc_default_writable_register);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d8562ce4de7a..3b3a377d0874 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1453,6 +1453,16 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1453 } 1453 }
1454} 1454}
1455 1455
1456static void soc_remove_dai_links(struct snd_soc_card *card)
1457{
1458 int i;
1459
1460 for (i = 0; i < card->num_rtd; i++)
1461 soc_remove_dai_link(card, i);
1462
1463 card->num_rtd = 0;
1464}
1465
1456static void soc_set_name_prefix(struct snd_soc_card *card, 1466static void soc_set_name_prefix(struct snd_soc_card *card,
1457 struct snd_soc_codec *codec) 1467 struct snd_soc_codec *codec)
1458{ 1468{
@@ -1493,6 +1503,9 @@ static int soc_probe_codec(struct snd_soc_card *card,
1493 } 1503 }
1494 } 1504 }
1495 1505
1506 if (driver->controls)
1507 snd_soc_add_controls(codec, driver->controls,
1508 driver->num_controls);
1496 if (driver->dapm_widgets) 1509 if (driver->dapm_widgets)
1497 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 1510 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
1498 driver->num_dapm_widgets); 1511 driver->num_dapm_widgets);
@@ -1865,6 +1878,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1865 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1878 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1866#endif 1879#endif
1867 1880
1881 if (card->dapm_widgets)
1882 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1883 card->num_dapm_widgets);
1884
1868 /* initialise the sound card only once */ 1885 /* initialise the sound card only once */
1869 if (card->probe) { 1886 if (card->probe) {
1870 ret = card->probe(card); 1887 ret = card->probe(card);
@@ -1890,9 +1907,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1890 } 1907 }
1891 } 1908 }
1892 1909
1893 if (card->dapm_widgets) 1910 /* We should have a non-codec control add function but we don't */
1894 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, 1911 if (card->controls)
1895 card->num_dapm_widgets); 1912 snd_soc_add_controls(list_first_entry(&card->codec_dev_list,
1913 struct snd_soc_codec,
1914 card_list),
1915 card->controls,
1916 card->num_controls);
1917
1896 if (card->dapm_routes) 1918 if (card->dapm_routes)
1897 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1919 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1898 card->num_dapm_routes); 1920 card->num_dapm_routes);
@@ -1949,8 +1971,7 @@ probe_aux_dev_err:
1949 soc_remove_aux_dev(card, i); 1971 soc_remove_aux_dev(card, i);
1950 1972
1951probe_dai_err: 1973probe_dai_err:
1952 for (i = 0; i < card->num_links; i++) 1974 soc_remove_dai_links(card);
1953 soc_remove_dai_link(card, i);
1954 1975
1955card_probe_error: 1976card_probe_error:
1956 if (card->remove) 1977 if (card->remove)
@@ -2012,8 +2033,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
2012 soc_remove_aux_dev(card, i); 2033 soc_remove_aux_dev(card, i);
2013 2034
2014 /* remove and free each DAI */ 2035 /* remove and free each DAI */
2015 for (i = 0; i < card->num_rtd; i++) 2036 soc_remove_dai_links(card);
2016 soc_remove_dai_link(card, i);
2017 2037
2018 soc_cleanup_card_debugfs(card); 2038 soc_cleanup_card_debugfs(card);
2019 2039
@@ -2150,6 +2170,42 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec,
2150EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); 2170EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
2151 2171
2152/** 2172/**
2173 * snd_soc_codec_readable_register: Report if a register is readable.
2174 *
2175 * @codec: CODEC to query.
2176 * @reg: Register to query.
2177 *
2178 * Boolean function indicating if a CODEC register is readable.
2179 */
2180int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
2181 unsigned int reg)
2182{
2183 if (codec->readable_register)
2184 return codec->readable_register(codec, reg);
2185 else
2186 return 0;
2187}
2188EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register);
2189
2190/**
2191 * snd_soc_codec_writable_register: Report if a register is writable.
2192 *
2193 * @codec: CODEC to query.
2194 * @reg: Register to query.
2195 *
2196 * Boolean function indicating if a CODEC register is writable.
2197 */
2198int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
2199 unsigned int reg)
2200{
2201 if (codec->writable_register)
2202 return codec->writable_register(codec, reg);
2203 else
2204 return 0;
2205}
2206EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
2207
2208/**
2153 * snd_soc_new_ac97_codec - initailise AC97 device 2209 * snd_soc_new_ac97_codec - initailise AC97 device
2154 * @codec: audio codec 2210 * @codec: audio codec
2155 * @ops: AC97 bus operations 2211 * @ops: AC97 bus operations
@@ -2231,6 +2287,13 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec,
2231} 2287}
2232EXPORT_SYMBOL_GPL(snd_soc_write); 2288EXPORT_SYMBOL_GPL(snd_soc_write);
2233 2289
2290unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
2291 unsigned int reg, const void *data, size_t len)
2292{
2293 return codec->bulk_write_raw(codec, reg, data, len);
2294}
2295EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
2296
2234/** 2297/**
2235 * snd_soc_update_bits - update codec register bits 2298 * snd_soc_update_bits - update codec register bits
2236 * @codec: audio codec 2299 * @codec: audio codec
@@ -3669,6 +3732,7 @@ int snd_soc_register_codec(struct device *dev,
3669 codec->read = codec_drv->read; 3732 codec->read = codec_drv->read;
3670 codec->volatile_register = codec_drv->volatile_register; 3733 codec->volatile_register = codec_drv->volatile_register;
3671 codec->readable_register = codec_drv->readable_register; 3734 codec->readable_register = codec_drv->readable_register;
3735 codec->writable_register = codec_drv->writable_register;
3672 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3736 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3673 codec->dapm.dev = dev; 3737 codec->dapm.dev = dev;
3674 codec->dapm.codec = codec; 3738 codec->dapm.codec = codec;
@@ -3703,6 +3767,8 @@ int snd_soc_register_codec(struct device *dev,
3703 codec->volatile_register = snd_soc_default_volatile_register; 3767 codec->volatile_register = snd_soc_default_volatile_register;
3704 if (!codec->readable_register) 3768 if (!codec->readable_register)
3705 codec->readable_register = snd_soc_default_readable_register; 3769 codec->readable_register = snd_soc_default_readable_register;
3770 if (!codec->writable_register)
3771 codec->writable_register = snd_soc_default_writable_register;
3706 } 3772 }
3707 3773
3708 for (i = 0; i < num_dai; i++) { 3774 for (i = 0; i < num_dai; i++) {
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 81c4052c127c..2ee738c08ca4 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -322,45 +322,6 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
322 return -ENODEV; 322 return -ENODEV;
323} 323}
324 324
325/* update dapm codec register bits */
326static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
327{
328 int change, power;
329 unsigned int old, new;
330 struct snd_soc_codec *codec = widget->codec;
331 struct snd_soc_dapm_context *dapm = widget->dapm;
332 struct snd_soc_card *card = dapm->card;
333
334 /* check for valid widgets */
335 if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
336 widget->id == snd_soc_dapm_output ||
337 widget->id == snd_soc_dapm_hp ||
338 widget->id == snd_soc_dapm_mic ||
339 widget->id == snd_soc_dapm_line ||
340 widget->id == snd_soc_dapm_spk)
341 return 0;
342
343 power = widget->power;
344 if (widget->invert)
345 power = (power ? 0:1);
346
347 old = snd_soc_read(codec, widget->reg);
348 new = (old & ~(0x1 << widget->shift)) | (power << widget->shift);
349
350 change = old != new;
351 if (change) {
352 pop_dbg(dapm->dev, card->pop_time,
353 "pop test %s : %s in %d ms\n",
354 widget->name, widget->power ? "on" : "off",
355 card->pop_time);
356 pop_wait(card->pop_time);
357 snd_soc_write(codec, widget->reg, new);
358 }
359 dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg,
360 old, new, change);
361 return change;
362}
363
364/* create new dapm mixer control */ 325/* create new dapm mixer control */
365static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, 326static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
366 struct snd_soc_dapm_widget *w) 327 struct snd_soc_dapm_widget *w)
@@ -644,57 +605,6 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
644} 605}
645EXPORT_SYMBOL_GPL(dapm_reg_event); 606EXPORT_SYMBOL_GPL(dapm_reg_event);
646 607
647/* Standard power change method, used to apply power changes to most
648 * widgets.
649 */
650static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
651{
652 int ret;
653
654 /* call any power change event handlers */
655 if (w->event)
656 dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
657 w->power ? "on" : "off",
658 w->name, w->event_flags);
659
660 /* power up pre event */
661 if (w->power && w->event &&
662 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
663 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
664 if (ret < 0)
665 return ret;
666 }
667
668 /* power down pre event */
669 if (!w->power && w->event &&
670 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
671 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
672 if (ret < 0)
673 return ret;
674 }
675
676 dapm_update_bits(w);
677
678 /* power up post event */
679 if (w->power && w->event &&
680 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
681 ret = w->event(w,
682 NULL, SND_SOC_DAPM_POST_PMU);
683 if (ret < 0)
684 return ret;
685 }
686
687 /* power down post event */
688 if (!w->power && w->event &&
689 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
690 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
691 if (ret < 0)
692 return ret;
693 }
694
695 return 0;
696}
697
698/* Generic check to see if a widget should be powered. 608/* Generic check to see if a widget should be powered.
699 */ 609 */
700static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) 610static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
@@ -981,16 +891,6 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
981 NULL, SND_SOC_DAPM_POST_PMD); 891 NULL, SND_SOC_DAPM_POST_PMD);
982 break; 892 break;
983 893
984 case snd_soc_dapm_input:
985 case snd_soc_dapm_output:
986 case snd_soc_dapm_hp:
987 case snd_soc_dapm_mic:
988 case snd_soc_dapm_line:
989 case snd_soc_dapm_spk:
990 /* No register support currently */
991 ret = dapm_generic_apply_power(w);
992 break;
993
994 default: 894 default:
995 /* Queue it up for application */ 895 /* Queue it up for application */
996 cur_sort = sort[w->id]; 896 cur_sort = sort[w->id];
@@ -1201,6 +1101,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1201 } 1101 }
1202 } 1102 }
1203 1103
1104 /* Force all contexts in the card to the same bias state */
1105 power = 0;
1106 list_for_each_entry(d, &card->dapm_list, list)
1107 if (d->dev_power)
1108 power = 1;
1109 list_for_each_entry(d, &card->dapm_list, list)
1110 d->dev_power = power;
1111
1112
1204 /* Run all the bias changes in parallel */ 1113 /* Run all the bias changes in parallel */
1205 list_for_each_entry(d, &dapm->card->dapm_list, list) 1114 list_for_each_entry(d, &dapm->card->dapm_list, list)
1206 async_schedule_domain(dapm_pre_sequence_async, d, 1115 async_schedule_domain(dapm_pre_sequence_async, d,
@@ -1304,6 +1213,47 @@ static const struct file_operations dapm_widget_power_fops = {
1304 .llseek = default_llseek, 1213 .llseek = default_llseek,
1305}; 1214};
1306 1215
1216static int dapm_bias_open_file(struct inode *inode, struct file *file)
1217{
1218 file->private_data = inode->i_private;
1219 return 0;
1220}
1221
1222static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf,
1223 size_t count, loff_t *ppos)
1224{
1225 struct snd_soc_dapm_context *dapm = file->private_data;
1226 char *level;
1227
1228 switch (dapm->bias_level) {
1229 case SND_SOC_BIAS_ON:
1230 level = "On\n";
1231 break;
1232 case SND_SOC_BIAS_PREPARE:
1233 level = "Prepare\n";
1234 break;
1235 case SND_SOC_BIAS_STANDBY:
1236 level = "Standby\n";
1237 break;
1238 case SND_SOC_BIAS_OFF:
1239 level = "Off\n";
1240 break;
1241 default:
1242 BUG();
1243 level = "Unknown\n";
1244 break;
1245 }
1246
1247 return simple_read_from_buffer(user_buf, count, ppos, level,
1248 strlen(level));
1249}
1250
1251static const struct file_operations dapm_bias_fops = {
1252 .open = dapm_bias_open_file,
1253 .read = dapm_bias_read_file,
1254 .llseek = default_llseek,
1255};
1256
1307void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) 1257void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
1308{ 1258{
1309 struct snd_soc_dapm_widget *w; 1259 struct snd_soc_dapm_widget *w;
@@ -1312,6 +1262,13 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
1312 if (!dapm->debugfs_dapm) 1262 if (!dapm->debugfs_dapm)
1313 return; 1263 return;
1314 1264
1265 d = debugfs_create_file("bias_level", 0444,
1266 dapm->debugfs_dapm, dapm,
1267 &dapm_bias_fops);
1268 if (!d)
1269 dev_warn(dapm->dev,
1270 "ASoC: Failed to create bias level debugfs file\n");
1271
1315 list_for_each_entry(w, &dapm->card->widgets, list) { 1272 list_for_each_entry(w, &dapm->card->widgets, list) {
1316 if (!w->name || w->dapm != dapm) 1273 if (!w->name || w->dapm != dapm)
1317 continue; 1274 continue;
@@ -1520,6 +1477,19 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1520 } 1477 }
1521 } 1478 }
1522 1479
1480 /* Try again in other contexts */
1481 list_for_each_entry(w, &dapm->card->widgets, list) {
1482 if (!strcmp(w->name, pin)) {
1483 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n",
1484 pin, status);
1485 w->connected = status;
1486 /* Allow disabling of forced pins */
1487 if (status == 0)
1488 w->force = 0;
1489 return 0;
1490 }
1491 }
1492
1523 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 1493 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
1524 return -EINVAL; 1494 return -EINVAL;
1525} 1495}
@@ -2360,6 +2330,17 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2360 } 2330 }
2361 } 2331 }
2362 2332
2333 /* Try again with other contexts */
2334 list_for_each_entry(w, &dapm->card->widgets, list) {
2335 if (!strcmp(w->name, pin)) {
2336 dev_dbg(w->dapm->dev,
2337 "dapm: force enable pin %s\n", pin);
2338 w->connected = 1;
2339 w->force = 1;
2340 return 0;
2341 }
2342 }
2343
2363 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); 2344 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2364 return -EINVAL; 2345 return -EINVAL;
2365} 2346}
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fc017c0a7b5d..7c17b98d5846 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -325,7 +325,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
325 gpio_handler, 325 gpio_handler,
326 IRQF_TRIGGER_RISING | 326 IRQF_TRIGGER_RISING |
327 IRQF_TRIGGER_FALLING, 327 IRQF_TRIGGER_FALLING,
328 jack->codec->dev->driver->name, 328 gpios[i].name,
329 &gpios[i]); 329 &gpios[i]);
330 if (ret) 330 if (ret)
331 goto err; 331 goto err;