diff options
62 files changed, 7952 insertions, 806 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 14bc7071f9df..62b94662506f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6739,9 +6739,11 @@ F: include/linux/tifm.h | |||
6739 | 6739 | ||
6740 | TI LM49xxx FAMILY ASoC CODEC DRIVERS | 6740 | TI LM49xxx FAMILY ASoC CODEC DRIVERS |
6741 | M: M R Swami Reddy <mr.swami.reddy@ti.com> | 6741 | M: M R Swami Reddy <mr.swami.reddy@ti.com> |
6742 | M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com> | ||
6742 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 6743 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
6743 | S: Maintained | 6744 | S: Maintained |
6744 | F: sound/soc/codecs/lm49453* | 6745 | F: sound/soc/codecs/lm49453* |
6746 | F: sound/soc/codecs/isabelle* | ||
6745 | 6747 | ||
6746 | TI TWL4030 SERIES SOC CODEC DRIVER | 6748 | TI TWL4030 SERIES SOC CODEC DRIVER |
6747 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> | 6749 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 0d1112815be3..a55d5db7eb5a 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -1073,4 +1073,15 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) | |||
1073 | 1073 | ||
1074 | const char *snd_pcm_format_name(snd_pcm_format_t format); | 1074 | const char *snd_pcm_format_name(snd_pcm_format_t format); |
1075 | 1075 | ||
1076 | /** | ||
1077 | * Get a string naming the direction of a stream | ||
1078 | */ | ||
1079 | static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) | ||
1080 | { | ||
1081 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1082 | return "Playback"; | ||
1083 | else | ||
1084 | return "Capture"; | ||
1085 | } | ||
1086 | |||
1076 | #endif /* __SOUND_PCM_H */ | 1087 | #endif /* __SOUND_PCM_H */ |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index e3833d9f1914..05559e571d44 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -229,6 +229,10 @@ struct device; | |||
229 | { .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ | 229 | { .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ |
230 | .shift = wshift, .invert = winvert, \ | 230 | .shift = wshift, .invert = winvert, \ |
231 | .event = wevent, .event_flags = wflags} | 231 | .event = wevent, .event_flags = wflags} |
232 | #define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \ | ||
233 | { .id = snd_soc_dapm_clock_supply, .name = wname, \ | ||
234 | .reg = SND_SOC_NOPM, .event = dapm_clock_event, \ | ||
235 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } | ||
232 | 236 | ||
233 | /* generic widgets */ | 237 | /* generic widgets */ |
234 | #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ | 238 | #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ |
@@ -245,6 +249,7 @@ struct device; | |||
245 | .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \ | 249 | .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \ |
246 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } | 250 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } |
247 | 251 | ||
252 | |||
248 | /* dapm kcontrol types */ | 253 | /* dapm kcontrol types */ |
249 | #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ | 254 | #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ |
250 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 255 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
@@ -327,6 +332,8 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, | |||
327 | struct snd_kcontrol *kcontrol, int event); | 332 | struct snd_kcontrol *kcontrol, int event); |
328 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, | 333 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, |
329 | struct snd_kcontrol *kcontrol, int event); | 334 | struct snd_kcontrol *kcontrol, int event); |
335 | int dapm_clock_event(struct snd_soc_dapm_widget *w, | ||
336 | struct snd_kcontrol *kcontrol, int event); | ||
330 | 337 | ||
331 | /* dapm controls */ | 338 | /* dapm controls */ |
332 | int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | 339 | int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, |
@@ -432,6 +439,7 @@ enum snd_soc_dapm_type { | |||
432 | snd_soc_dapm_post, /* machine specific post widget - exec last */ | 439 | snd_soc_dapm_post, /* machine specific post widget - exec last */ |
433 | snd_soc_dapm_supply, /* power/clock supply */ | 440 | snd_soc_dapm_supply, /* power/clock supply */ |
434 | snd_soc_dapm_regulator_supply, /* external regulator */ | 441 | snd_soc_dapm_regulator_supply, /* external regulator */ |
442 | snd_soc_dapm_clock_supply, /* external clock */ | ||
435 | snd_soc_dapm_aif_in, /* audio interface input */ | 443 | snd_soc_dapm_aif_in, /* audio interface input */ |
436 | snd_soc_dapm_aif_out, /* audio interface output */ | 444 | snd_soc_dapm_aif_out, /* audio interface output */ |
437 | snd_soc_dapm_siggen, /* signal generator */ | 445 | snd_soc_dapm_siggen, /* signal generator */ |
@@ -537,6 +545,8 @@ struct snd_soc_dapm_widget { | |||
537 | struct list_head dirty; | 545 | struct list_head dirty; |
538 | int inputs; | 546 | int inputs; |
539 | int outputs; | 547 | int outputs; |
548 | |||
549 | struct clk *clk; | ||
540 | }; | 550 | }; |
541 | 551 | ||
542 | struct snd_soc_dapm_update { | 552 | struct snd_soc_dapm_update { |
diff --git a/include/sound/soc.h b/include/sound/soc.h index c703871f5f65..e4348d25fca3 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -47,6 +47,13 @@ | |||
47 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ | 47 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ |
48 | .put = snd_soc_put_volsw, \ | 48 | .put = snd_soc_put_volsw, \ |
49 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | 49 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } |
50 | #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \ | ||
51 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | ||
52 | .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \ | ||
53 | .put = snd_soc_put_volsw_range, \ | ||
54 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
55 | {.reg = xreg, .shift = xshift, .min = xmin,\ | ||
56 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
50 | #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ | 57 | #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ |
51 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 58 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
52 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 59 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
@@ -67,6 +74,16 @@ | |||
67 | {.reg = xreg, .rreg = xreg, \ | 74 | {.reg = xreg, .rreg = xreg, \ |
68 | .shift = xshift, .rshift = xshift, \ | 75 | .shift = xshift, .rshift = xshift, \ |
69 | .max = xmax, .min = xmin} } | 76 | .max = xmax, .min = xmin} } |
77 | #define SOC_SINGLE_RANGE_TLV(xname, xreg, xshift, xmin, xmax, xinvert, tlv_array) \ | ||
78 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | ||
79 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
80 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | ||
81 | .tlv.p = (tlv_array), \ | ||
82 | .info = snd_soc_info_volsw_range, \ | ||
83 | .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \ | ||
84 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
85 | {.reg = xreg, .shift = xshift, .min = xmin,\ | ||
86 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
70 | #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ | 87 | #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ |
71 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 88 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
72 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ | 89 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ |
@@ -460,6 +477,12 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, | |||
460 | struct snd_ctl_elem_value *ucontrol); | 477 | struct snd_ctl_elem_value *ucontrol); |
461 | int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, | 478 | int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, |
462 | struct snd_ctl_elem_value *ucontrol); | 479 | struct snd_ctl_elem_value *ucontrol); |
480 | int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, | ||
481 | struct snd_ctl_elem_info *uinfo); | ||
482 | int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | ||
483 | struct snd_ctl_elem_value *ucontrol); | ||
484 | int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | ||
485 | struct snd_ctl_elem_value *ucontrol); | ||
463 | int snd_soc_limit_volume(struct snd_soc_codec *codec, | 486 | int snd_soc_limit_volume(struct snd_soc_codec *codec, |
464 | const char *name, int max); | 487 | const char *name, int max); |
465 | int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, | 488 | int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, |
@@ -785,13 +808,36 @@ struct snd_soc_dai_link { | |||
785 | /* config - must be set by machine driver */ | 808 | /* config - must be set by machine driver */ |
786 | const char *name; /* Codec name */ | 809 | const char *name; /* Codec name */ |
787 | const char *stream_name; /* Stream name */ | 810 | const char *stream_name; /* Stream name */ |
788 | const char *codec_name; /* for multi-codec */ | 811 | /* |
789 | const struct device_node *codec_of_node; | 812 | * You MAY specify the link's CPU-side device, either by device name, |
790 | const char *platform_name; /* for multi-platform */ | 813 | * or by DT/OF node, but not both. If this information is omitted, |
791 | const struct device_node *platform_of_node; | 814 | * the CPU-side DAI is matched using .cpu_dai_name only, which hence |
815 | * must be globally unique. These fields are currently typically used | ||
816 | * only for codec to codec links, or systems using device tree. | ||
817 | */ | ||
818 | const char *cpu_name; | ||
819 | const struct device_node *cpu_of_node; | ||
820 | /* | ||
821 | * You MAY specify the DAI name of the CPU DAI. If this information is | ||
822 | * omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node | ||
823 | * only, which only works well when that device exposes a single DAI. | ||
824 | */ | ||
792 | const char *cpu_dai_name; | 825 | const char *cpu_dai_name; |
793 | const struct device_node *cpu_dai_of_node; | 826 | /* |
827 | * You MUST specify the link's codec, either by device name, or by | ||
828 | * DT/OF node, but not both. | ||
829 | */ | ||
830 | const char *codec_name; | ||
831 | const struct device_node *codec_of_node; | ||
832 | /* You MUST specify the DAI name within the codec */ | ||
794 | const char *codec_dai_name; | 833 | const char *codec_dai_name; |
834 | /* | ||
835 | * You MAY specify the link's platform/PCM/DMA driver, either by | ||
836 | * device name, or by DT/OF node, but not both. Some forms of link | ||
837 | * do not need a platform. | ||
838 | */ | ||
839 | const char *platform_name; | ||
840 | const struct device_node *platform_of_node; | ||
795 | int be_id; /* optional ID for machine driver BE identification */ | 841 | int be_id; /* optional ID for machine driver BE identification */ |
796 | 842 | ||
797 | const struct snd_soc_pcm_stream *params; | 843 | const struct snd_soc_pcm_stream *params; |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 1e1613a438dd..43f5240e6942 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -12,6 +12,7 @@ config SND_SOC_ALL_CODECS | |||
12 | tristate "Build all ASoC CODEC drivers" | 12 | tristate "Build all ASoC CODEC drivers" |
13 | select SND_SOC_88PM860X if MFD_88PM860X | 13 | select SND_SOC_88PM860X if MFD_88PM860X |
14 | select SND_SOC_L3 | 14 | select SND_SOC_L3 |
15 | select SND_SOC_AB8500_CODEC if ABX500_CORE | ||
15 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS | 16 | select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS |
16 | select SND_SOC_AD1836 if SPI_MASTER | 17 | select SND_SOC_AD1836 if SPI_MASTER |
17 | select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI | 18 | select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI |
@@ -35,7 +36,9 @@ config SND_SOC_ALL_CODECS | |||
35 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI | 36 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI |
36 | select SND_SOC_CX20442 | 37 | select SND_SOC_CX20442 |
37 | select SND_SOC_DA7210 if I2C | 38 | select SND_SOC_DA7210 if I2C |
39 | select SND_SOC_DA732X if I2C | ||
38 | select SND_SOC_DFBMCS320 | 40 | select SND_SOC_DFBMCS320 |
41 | select SND_SOC_ISABELLE if I2C | ||
39 | select SND_SOC_JZ4740_CODEC | 42 | select SND_SOC_JZ4740_CODEC |
40 | select SND_SOC_LM4857 if I2C | 43 | select SND_SOC_LM4857 if I2C |
41 | select SND_SOC_LM49453 if I2C | 44 | select SND_SOC_LM49453 if I2C |
@@ -131,6 +134,9 @@ config SND_SOC_WM_HUBS | |||
131 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y | 134 | default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y |
132 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m | 135 | default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m |
133 | 136 | ||
137 | config SND_SOC_AB8500_CODEC | ||
138 | tristate | ||
139 | |||
134 | config SND_SOC_AC97_CODEC | 140 | config SND_SOC_AC97_CODEC |
135 | tristate | 141 | tristate |
136 | select SND_AC97_CODEC | 142 | select SND_AC97_CODEC |
@@ -219,12 +225,18 @@ config SND_SOC_L3 | |||
219 | config SND_SOC_DA7210 | 225 | config SND_SOC_DA7210 |
220 | tristate | 226 | tristate |
221 | 227 | ||
228 | config SND_SOC_DA732X | ||
229 | tristate | ||
230 | |||
222 | config SND_SOC_DFBMCS320 | 231 | config SND_SOC_DFBMCS320 |
223 | tristate | 232 | tristate |
224 | 233 | ||
225 | config SND_SOC_DMIC | 234 | config SND_SOC_DMIC |
226 | tristate | 235 | tristate |
227 | 236 | ||
237 | config SND_SOC_ISABELLE | ||
238 | tristate | ||
239 | |||
228 | config SND_SOC_LM49453 | 240 | config SND_SOC_LM49453 |
229 | tristate | 241 | tristate |
230 | 242 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index fc27fec39487..3d30654f6fcc 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | snd-soc-88pm860x-objs := 88pm860x-codec.o | 1 | snd-soc-88pm860x-objs := 88pm860x-codec.o |
2 | snd-soc-ab8500-codec-objs := ab8500-codec.o | ||
2 | snd-soc-ac97-objs := ac97.o | 3 | snd-soc-ac97-objs := ac97.o |
3 | snd-soc-ad1836-objs := ad1836.o | 4 | snd-soc-ad1836-objs := ad1836.o |
4 | snd-soc-ad193x-objs := ad193x.o | 5 | snd-soc-ad193x-objs := ad193x.o |
@@ -21,8 +22,10 @@ snd-soc-cs4270-objs := cs4270.o | |||
21 | snd-soc-cs4271-objs := cs4271.o | 22 | snd-soc-cs4271-objs := cs4271.o |
22 | snd-soc-cx20442-objs := cx20442.o | 23 | snd-soc-cx20442-objs := cx20442.o |
23 | snd-soc-da7210-objs := da7210.o | 24 | snd-soc-da7210-objs := da7210.o |
25 | snd-soc-da732x-objs := da732x.o | ||
24 | snd-soc-dfbmcs320-objs := dfbmcs320.o | 26 | snd-soc-dfbmcs320-objs := dfbmcs320.o |
25 | snd-soc-dmic-objs := dmic.o | 27 | snd-soc-dmic-objs := dmic.o |
28 | snd-soc-isabelle-objs := isabelle.o | ||
26 | snd-soc-jz4740-codec-objs := jz4740.o | 29 | snd-soc-jz4740-codec-objs := jz4740.o |
27 | snd-soc-l3-objs := l3.o | 30 | snd-soc-l3-objs := l3.o |
28 | snd-soc-lm4857-objs := lm4857.o | 31 | snd-soc-lm4857-objs := lm4857.o |
@@ -108,6 +111,7 @@ snd-soc-max9877-objs := max9877.o | |||
108 | snd-soc-tpa6130a2-objs := tpa6130a2.o | 111 | snd-soc-tpa6130a2-objs := tpa6130a2.o |
109 | 112 | ||
110 | obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o | 113 | obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o |
114 | obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o | ||
111 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o | 115 | obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o |
112 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o | 116 | obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o |
113 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o | 117 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o |
@@ -132,8 +136,10 @@ obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o | |||
132 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o | 136 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o |
133 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o | 137 | obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o |
134 | obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o | 138 | obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o |
139 | obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o | ||
135 | obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o | 140 | obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o |
136 | obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o | 141 | obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o |
142 | obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o | ||
137 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o | 143 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o |
138 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o | 144 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o |
139 | obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o | 145 | obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c new file mode 100644 index 000000000000..95dc7d5bb076 --- /dev/null +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -0,0 +1,2521 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2012 | ||
3 | * | ||
4 | * Author: Ola Lilja <ola.o.lilja@stericsson.com>, | ||
5 | * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>, | ||
6 | * Roger Nilsson <roger.xr.nilsson@stericsson.com>, | ||
7 | * for ST-Ericsson. | ||
8 | * | ||
9 | * Based on the early work done by: | ||
10 | * Mikko J. Lehto <mikko.lehto@symbio.com>, | ||
11 | * Mikko Sarmanne <mikko.sarmanne@symbio.com>, | ||
12 | * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>, | ||
13 | * for ST-Ericsson. | ||
14 | * | ||
15 | * License terms: | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify it | ||
18 | * under the terms of the GNU General Public License version 2 as published | ||
19 | * by the Free Software Foundation. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/pm.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <linux/mfd/abx500/ab8500.h> | ||
33 | #include <linux/mfd/abx500.h> | ||
34 | #include <linux/mfd/abx500/ab8500-sysctrl.h> | ||
35 | #include <linux/mfd/abx500/ab8500-codec.h> | ||
36 | #include <linux/regulator/consumer.h> | ||
37 | |||
38 | #include <sound/core.h> | ||
39 | #include <sound/pcm.h> | ||
40 | #include <sound/pcm_params.h> | ||
41 | #include <sound/initval.h> | ||
42 | #include <sound/soc.h> | ||
43 | #include <sound/soc-dapm.h> | ||
44 | #include <sound/tlv.h> | ||
45 | |||
46 | #include "ab8500-codec.h" | ||
47 | |||
48 | /* Macrocell value definitions */ | ||
49 | #define CLK_32K_OUT2_DISABLE 0x01 | ||
50 | #define INACTIVE_RESET_AUDIO 0x02 | ||
51 | #define ENABLE_AUDIO_CLK_TO_AUDIO_BLK 0x10 | ||
52 | #define ENABLE_VINTCORE12_SUPPLY 0x04 | ||
53 | #define GPIO27_DIR_OUTPUT 0x04 | ||
54 | #define GPIO29_DIR_OUTPUT 0x10 | ||
55 | #define GPIO31_DIR_OUTPUT 0x40 | ||
56 | |||
57 | /* Macrocell register definitions */ | ||
58 | #define AB8500_CTRL3_REG 0x0200 | ||
59 | #define AB8500_GPIO_DIR4_REG 0x1013 | ||
60 | |||
61 | /* Nr of FIR/IIR-coeff banks in ANC-block */ | ||
62 | #define AB8500_NR_OF_ANC_COEFF_BANKS 2 | ||
63 | |||
64 | /* Minimum duration to keep ANC IIR Init bit high or | ||
65 | low before proceeding with the configuration sequence */ | ||
66 | #define AB8500_ANC_SM_DELAY 2000 | ||
67 | |||
68 | #define AB8500_FILTER_CONTROL(xname, xcount, xmin, xmax) \ | ||
69 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | ||
70 | .info = filter_control_info, \ | ||
71 | .get = filter_control_get, .put = filter_control_put, \ | ||
72 | .private_value = (unsigned long)&(struct filter_control) \ | ||
73 | {.count = xcount, .min = xmin, .max = xmax} } | ||
74 | |||
75 | struct filter_control { | ||
76 | long min, max; | ||
77 | unsigned int count; | ||
78 | long value[128]; | ||
79 | }; | ||
80 | |||
81 | /* Sidetone states */ | ||
82 | static const char * const enum_sid_state[] = { | ||
83 | "Unconfigured", | ||
84 | "Apply FIR", | ||
85 | "FIR is configured", | ||
86 | }; | ||
87 | enum sid_state { | ||
88 | SID_UNCONFIGURED = 0, | ||
89 | SID_APPLY_FIR = 1, | ||
90 | SID_FIR_CONFIGURED = 2, | ||
91 | }; | ||
92 | |||
93 | static const char * const enum_anc_state[] = { | ||
94 | "Unconfigured", | ||
95 | "Apply FIR and IIR", | ||
96 | "FIR and IIR are configured", | ||
97 | "Apply FIR", | ||
98 | "FIR is configured", | ||
99 | "Apply IIR", | ||
100 | "IIR is configured" | ||
101 | }; | ||
102 | enum anc_state { | ||
103 | ANC_UNCONFIGURED = 0, | ||
104 | ANC_APPLY_FIR_IIR = 1, | ||
105 | ANC_FIR_IIR_CONFIGURED = 2, | ||
106 | ANC_APPLY_FIR = 3, | ||
107 | ANC_FIR_CONFIGURED = 4, | ||
108 | ANC_APPLY_IIR = 5, | ||
109 | ANC_IIR_CONFIGURED = 6 | ||
110 | }; | ||
111 | |||
112 | /* Analog microphones */ | ||
113 | enum amic_idx { | ||
114 | AMIC_IDX_1A, | ||
115 | AMIC_IDX_1B, | ||
116 | AMIC_IDX_2 | ||
117 | }; | ||
118 | |||
119 | struct ab8500_codec_drvdata_dbg { | ||
120 | struct regulator *vaud; | ||
121 | struct regulator *vamic1; | ||
122 | struct regulator *vamic2; | ||
123 | struct regulator *vdmic; | ||
124 | }; | ||
125 | |||
126 | /* Private data for AB8500 device-driver */ | ||
127 | struct ab8500_codec_drvdata { | ||
128 | /* Sidetone */ | ||
129 | long *sid_fir_values; | ||
130 | enum sid_state sid_status; | ||
131 | |||
132 | /* ANC */ | ||
133 | struct mutex anc_lock; | ||
134 | long *anc_fir_values; | ||
135 | long *anc_iir_values; | ||
136 | enum anc_state anc_status; | ||
137 | }; | ||
138 | |||
139 | static inline const char *amic_micbias_str(enum amic_micbias micbias) | ||
140 | { | ||
141 | switch (micbias) { | ||
142 | case AMIC_MICBIAS_VAMIC1: | ||
143 | return "VAMIC1"; | ||
144 | case AMIC_MICBIAS_VAMIC2: | ||
145 | return "VAMIC2"; | ||
146 | default: | ||
147 | return "Unknown"; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static inline const char *amic_type_str(enum amic_type type) | ||
152 | { | ||
153 | switch (type) { | ||
154 | case AMIC_TYPE_DIFFERENTIAL: | ||
155 | return "DIFFERENTIAL"; | ||
156 | case AMIC_TYPE_SINGLE_ENDED: | ||
157 | return "SINGLE ENDED"; | ||
158 | default: | ||
159 | return "Unknown"; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Read'n'write functions | ||
165 | */ | ||
166 | |||
167 | /* Read a register from the audio-bank of AB8500 */ | ||
168 | static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec, | ||
169 | unsigned int reg) | ||
170 | { | ||
171 | int status; | ||
172 | unsigned int value = 0; | ||
173 | |||
174 | u8 value8; | ||
175 | status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO, | ||
176 | reg, &value8); | ||
177 | if (status < 0) { | ||
178 | dev_err(codec->dev, | ||
179 | "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n", | ||
180 | __func__, (u8)AB8500_AUDIO, (u8)reg, status); | ||
181 | } else { | ||
182 | dev_dbg(codec->dev, | ||
183 | "%s: Read 0x%02x from register 0x%02x:0x%02x\n", | ||
184 | __func__, value8, (u8)AB8500_AUDIO, (u8)reg); | ||
185 | value = (unsigned int)value8; | ||
186 | } | ||
187 | |||
188 | return value; | ||
189 | } | ||
190 | |||
191 | /* Write to a register in the audio-bank of AB8500 */ | ||
192 | static int ab8500_codec_write_reg(struct snd_soc_codec *codec, | ||
193 | unsigned int reg, unsigned int value) | ||
194 | { | ||
195 | int status; | ||
196 | |||
197 | status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO, | ||
198 | reg, value); | ||
199 | if (status < 0) | ||
200 | dev_err(codec->dev, | ||
201 | "%s: ERROR: Register (%02x:%02x) write failed (%d).\n", | ||
202 | __func__, (u8)AB8500_AUDIO, (u8)reg, status); | ||
203 | else | ||
204 | dev_dbg(codec->dev, | ||
205 | "%s: Wrote 0x%02x into register %02x:%02x\n", | ||
206 | __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg); | ||
207 | |||
208 | return status; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Controls - DAPM | ||
213 | */ | ||
214 | |||
215 | /* Earpiece */ | ||
216 | |||
217 | /* Earpiece source selector */ | ||
218 | static const char * const enum_ear_lineout_source[] = {"Headset Left", | ||
219 | "Speaker Left"}; | ||
220 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ear_lineout_source, AB8500_DMICFILTCONF, | ||
221 | AB8500_DMICFILTCONF_DA3TOEAR, enum_ear_lineout_source); | ||
222 | static const struct snd_kcontrol_new dapm_ear_lineout_source = | ||
223 | SOC_DAPM_ENUM("Earpiece or LineOut Mono Source", | ||
224 | dapm_enum_ear_lineout_source); | ||
225 | |||
226 | /* LineOut */ | ||
227 | |||
228 | /* LineOut source selector */ | ||
229 | static const char * const enum_lineout_source[] = {"Mono Path", "Stereo Path"}; | ||
230 | static SOC_ENUM_DOUBLE_DECL(dapm_enum_lineout_source, AB8500_ANACONF5, | ||
231 | AB8500_ANACONF5_HSLDACTOLOL, | ||
232 | AB8500_ANACONF5_HSRDACTOLOR, enum_lineout_source); | ||
233 | static const struct snd_kcontrol_new dapm_lineout_source[] = { | ||
234 | SOC_DAPM_ENUM("LineOut Source", dapm_enum_lineout_source), | ||
235 | }; | ||
236 | |||
237 | /* Handsfree */ | ||
238 | |||
239 | /* Speaker Left - ANC selector */ | ||
240 | static const char * const enum_HFx_sel[] = {"Audio Path", "ANC"}; | ||
241 | static SOC_ENUM_SINGLE_DECL(dapm_enum_HFl_sel, AB8500_DIGMULTCONF2, | ||
242 | AB8500_DIGMULTCONF2_HFLSEL, enum_HFx_sel); | ||
243 | static const struct snd_kcontrol_new dapm_HFl_select[] = { | ||
244 | SOC_DAPM_ENUM("Speaker Left Source", dapm_enum_HFl_sel), | ||
245 | }; | ||
246 | |||
247 | /* Speaker Right - ANC selector */ | ||
248 | static SOC_ENUM_SINGLE_DECL(dapm_enum_HFr_sel, AB8500_DIGMULTCONF2, | ||
249 | AB8500_DIGMULTCONF2_HFRSEL, enum_HFx_sel); | ||
250 | static const struct snd_kcontrol_new dapm_HFr_select[] = { | ||
251 | SOC_DAPM_ENUM("Speaker Right Source", dapm_enum_HFr_sel), | ||
252 | }; | ||
253 | |||
254 | /* Mic 1 */ | ||
255 | |||
256 | /* Mic 1 - Mic 1a or 1b selector */ | ||
257 | static const char * const enum_mic1ab_sel[] = {"Mic 1b", "Mic 1a"}; | ||
258 | static SOC_ENUM_SINGLE_DECL(dapm_enum_mic1ab_sel, AB8500_ANACONF3, | ||
259 | AB8500_ANACONF3_MIC1SEL, enum_mic1ab_sel); | ||
260 | static const struct snd_kcontrol_new dapm_mic1ab_mux[] = { | ||
261 | SOC_DAPM_ENUM("Mic 1a or 1b Select", dapm_enum_mic1ab_sel), | ||
262 | }; | ||
263 | |||
264 | /* Mic 1 - AD3 - Mic 1 or DMic 3 selector */ | ||
265 | static const char * const enum_ad3_sel[] = {"Mic 1", "DMic 3"}; | ||
266 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad3_sel, AB8500_DIGMULTCONF1, | ||
267 | AB8500_DIGMULTCONF1_AD3SEL, enum_ad3_sel); | ||
268 | static const struct snd_kcontrol_new dapm_ad3_select[] = { | ||
269 | SOC_DAPM_ENUM("AD3 Source Select", dapm_enum_ad3_sel), | ||
270 | }; | ||
271 | |||
272 | /* Mic 1 - AD6 - Mic 1 or DMic 6 selector */ | ||
273 | static const char * const enum_ad6_sel[] = {"Mic 1", "DMic 6"}; | ||
274 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad6_sel, AB8500_DIGMULTCONF1, | ||
275 | AB8500_DIGMULTCONF1_AD6SEL, enum_ad6_sel); | ||
276 | static const struct snd_kcontrol_new dapm_ad6_select[] = { | ||
277 | SOC_DAPM_ENUM("AD6 Source Select", dapm_enum_ad6_sel), | ||
278 | }; | ||
279 | |||
280 | /* Mic 2 */ | ||
281 | |||
282 | /* Mic 2 - AD5 - Mic 2 or DMic 5 selector */ | ||
283 | static const char * const enum_ad5_sel[] = {"Mic 2", "DMic 5"}; | ||
284 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad5_sel, AB8500_DIGMULTCONF1, | ||
285 | AB8500_DIGMULTCONF1_AD5SEL, enum_ad5_sel); | ||
286 | static const struct snd_kcontrol_new dapm_ad5_select[] = { | ||
287 | SOC_DAPM_ENUM("AD5 Source Select", dapm_enum_ad5_sel), | ||
288 | }; | ||
289 | |||
290 | /* LineIn */ | ||
291 | |||
292 | /* LineIn left - AD1 - LineIn Left or DMic 1 selector */ | ||
293 | static const char * const enum_ad1_sel[] = {"LineIn Left", "DMic 1"}; | ||
294 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad1_sel, AB8500_DIGMULTCONF1, | ||
295 | AB8500_DIGMULTCONF1_AD1SEL, enum_ad1_sel); | ||
296 | static const struct snd_kcontrol_new dapm_ad1_select[] = { | ||
297 | SOC_DAPM_ENUM("AD1 Source Select", dapm_enum_ad1_sel), | ||
298 | }; | ||
299 | |||
300 | /* LineIn right - Mic 2 or LineIn Right selector */ | ||
301 | static const char * const enum_mic2lr_sel[] = {"Mic 2", "LineIn Right"}; | ||
302 | static SOC_ENUM_SINGLE_DECL(dapm_enum_mic2lr_sel, AB8500_ANACONF3, | ||
303 | AB8500_ANACONF3_LINRSEL, enum_mic2lr_sel); | ||
304 | static const struct snd_kcontrol_new dapm_mic2lr_select[] = { | ||
305 | SOC_DAPM_ENUM("Mic 2 or LINR Select", dapm_enum_mic2lr_sel), | ||
306 | }; | ||
307 | |||
308 | /* LineIn right - AD2 - LineIn Right or DMic2 selector */ | ||
309 | static const char * const enum_ad2_sel[] = {"LineIn Right", "DMic 2"}; | ||
310 | static SOC_ENUM_SINGLE_DECL(dapm_enum_ad2_sel, AB8500_DIGMULTCONF1, | ||
311 | AB8500_DIGMULTCONF1_AD2SEL, enum_ad2_sel); | ||
312 | static const struct snd_kcontrol_new dapm_ad2_select[] = { | ||
313 | SOC_DAPM_ENUM("AD2 Source Select", dapm_enum_ad2_sel), | ||
314 | }; | ||
315 | |||
316 | |||
317 | /* ANC */ | ||
318 | |||
319 | static const char * const enum_anc_in_sel[] = {"Mic 1 / DMic 6", | ||
320 | "Mic 2 / DMic 5"}; | ||
321 | static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_in_sel, AB8500_DMICFILTCONF, | ||
322 | AB8500_DMICFILTCONF_ANCINSEL, enum_anc_in_sel); | ||
323 | static const struct snd_kcontrol_new dapm_anc_in_select[] = { | ||
324 | SOC_DAPM_ENUM("ANC Source", dapm_enum_anc_in_sel), | ||
325 | }; | ||
326 | |||
327 | /* ANC - Enable/Disable */ | ||
328 | static const struct snd_kcontrol_new dapm_anc_enable[] = { | ||
329 | SOC_DAPM_SINGLE("Switch", AB8500_ANCCONF1, | ||
330 | AB8500_ANCCONF1_ENANC, 0, 0), | ||
331 | }; | ||
332 | |||
333 | /* ANC to Earpiece - Mute */ | ||
334 | static const struct snd_kcontrol_new dapm_anc_ear_mute[] = { | ||
335 | SOC_DAPM_SINGLE("Switch", AB8500_DIGMULTCONF1, | ||
336 | AB8500_DIGMULTCONF1_ANCSEL, 1, 0), | ||
337 | }; | ||
338 | |||
339 | |||
340 | |||
341 | /* Sidetone left */ | ||
342 | |||
343 | /* Sidetone left - Input selector */ | ||
344 | static const char * const enum_stfir1_in_sel[] = { | ||
345 | "LineIn Left", "LineIn Right", "Mic 1", "Headset Left" | ||
346 | }; | ||
347 | static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir1_in_sel, AB8500_DIGMULTCONF2, | ||
348 | AB8500_DIGMULTCONF2_FIRSID1SEL, enum_stfir1_in_sel); | ||
349 | static const struct snd_kcontrol_new dapm_stfir1_in_select[] = { | ||
350 | SOC_DAPM_ENUM("Sidetone Left Source", dapm_enum_stfir1_in_sel), | ||
351 | }; | ||
352 | |||
353 | /* Sidetone right path */ | ||
354 | |||
355 | /* Sidetone right - Input selector */ | ||
356 | static const char * const enum_stfir2_in_sel[] = { | ||
357 | "LineIn Right", "Mic 1", "DMic 4", "Headset Right" | ||
358 | }; | ||
359 | static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir2_in_sel, AB8500_DIGMULTCONF2, | ||
360 | AB8500_DIGMULTCONF2_FIRSID2SEL, enum_stfir2_in_sel); | ||
361 | static const struct snd_kcontrol_new dapm_stfir2_in_select[] = { | ||
362 | SOC_DAPM_ENUM("Sidetone Right Source", dapm_enum_stfir2_in_sel), | ||
363 | }; | ||
364 | |||
365 | /* Vibra */ | ||
366 | |||
367 | static const char * const enum_pwm2vibx[] = {"Audio Path", "PWM Generator"}; | ||
368 | |||
369 | static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib1, AB8500_PWMGENCONF1, | ||
370 | AB8500_PWMGENCONF1_PWMTOVIB1, enum_pwm2vibx); | ||
371 | |||
372 | static const struct snd_kcontrol_new dapm_pwm2vib1[] = { | ||
373 | SOC_DAPM_ENUM("Vibra 1 Controller", dapm_enum_pwm2vib1), | ||
374 | }; | ||
375 | |||
376 | static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib2, AB8500_PWMGENCONF1, | ||
377 | AB8500_PWMGENCONF1_PWMTOVIB2, enum_pwm2vibx); | ||
378 | |||
379 | static const struct snd_kcontrol_new dapm_pwm2vib2[] = { | ||
380 | SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2), | ||
381 | }; | ||
382 | |||
383 | /* | ||
384 | * DAPM-widgets | ||
385 | */ | ||
386 | |||
387 | static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { | ||
388 | |||
389 | /* Clocks */ | ||
390 | SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"), | ||
391 | |||
392 | /* Regulators */ | ||
393 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0), | ||
394 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0), | ||
395 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0), | ||
396 | SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0), | ||
397 | |||
398 | /* Power */ | ||
399 | SND_SOC_DAPM_SUPPLY("Audio Power", | ||
400 | AB8500_POWERUP, AB8500_POWERUP_POWERUP, 0, | ||
401 | NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
402 | SND_SOC_DAPM_SUPPLY("Audio Analog Power", | ||
403 | AB8500_POWERUP, AB8500_POWERUP_ENANA, 0, | ||
404 | NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
405 | |||
406 | /* Main supply node */ | ||
407 | SND_SOC_DAPM_SUPPLY("Main Supply", SND_SOC_NOPM, 0, 0, | ||
408 | NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
409 | |||
410 | /* DA/AD */ | ||
411 | |||
412 | SND_SOC_DAPM_INPUT("ADC Input"), | ||
413 | SND_SOC_DAPM_ADC("ADC", "ab8500_0c", SND_SOC_NOPM, 0, 0), | ||
414 | |||
415 | SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), | ||
416 | SND_SOC_DAPM_OUTPUT("DAC Output"), | ||
417 | |||
418 | SND_SOC_DAPM_AIF_IN("DA_IN1", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
419 | SND_SOC_DAPM_AIF_IN("DA_IN2", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
420 | SND_SOC_DAPM_AIF_IN("DA_IN3", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
421 | SND_SOC_DAPM_AIF_IN("DA_IN4", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
422 | SND_SOC_DAPM_AIF_IN("DA_IN5", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
423 | SND_SOC_DAPM_AIF_IN("DA_IN6", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
424 | SND_SOC_DAPM_AIF_OUT("AD_OUT1", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
425 | SND_SOC_DAPM_AIF_OUT("AD_OUT2", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
426 | SND_SOC_DAPM_AIF_OUT("AD_OUT3", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
427 | SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
428 | SND_SOC_DAPM_AIF_OUT("AD_OUT57", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
429 | SND_SOC_DAPM_AIF_OUT("AD_OUT68", NULL, 0, SND_SOC_NOPM, 0, 0), | ||
430 | |||
431 | /* Headset path */ | ||
432 | |||
433 | SND_SOC_DAPM_SUPPLY("Charge Pump", AB8500_ANACONF5, | ||
434 | AB8500_ANACONF5_ENCPHS, 0, NULL, 0), | ||
435 | |||
436 | SND_SOC_DAPM_DAC("DA1 Enable", "ab8500_0p", | ||
437 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA1, 0), | ||
438 | SND_SOC_DAPM_DAC("DA2 Enable", "ab8500_0p", | ||
439 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA2, 0), | ||
440 | |||
441 | SND_SOC_DAPM_PGA("HSL Digital Volume", SND_SOC_NOPM, 0, 0, | ||
442 | NULL, 0), | ||
443 | SND_SOC_DAPM_PGA("HSR Digital Volume", SND_SOC_NOPM, 0, 0, | ||
444 | NULL, 0), | ||
445 | |||
446 | SND_SOC_DAPM_DAC("HSL DAC", "ab8500_0p", | ||
447 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSL, 0), | ||
448 | SND_SOC_DAPM_DAC("HSR DAC", "ab8500_0p", | ||
449 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSR, 0), | ||
450 | SND_SOC_DAPM_MIXER("HSL DAC Mute", AB8500_MUTECONF, | ||
451 | AB8500_MUTECONF_MUTDACHSL, 1, | ||
452 | NULL, 0), | ||
453 | SND_SOC_DAPM_MIXER("HSR DAC Mute", AB8500_MUTECONF, | ||
454 | AB8500_MUTECONF_MUTDACHSR, 1, | ||
455 | NULL, 0), | ||
456 | SND_SOC_DAPM_DAC("HSL DAC Driver", "ab8500_0p", | ||
457 | AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSL, 0), | ||
458 | SND_SOC_DAPM_DAC("HSR DAC Driver", "ab8500_0p", | ||
459 | AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSR, 0), | ||
460 | |||
461 | SND_SOC_DAPM_MIXER("HSL Mute", | ||
462 | AB8500_MUTECONF, AB8500_MUTECONF_MUTHSL, 1, | ||
463 | NULL, 0), | ||
464 | SND_SOC_DAPM_MIXER("HSR Mute", | ||
465 | AB8500_MUTECONF, AB8500_MUTECONF_MUTHSR, 1, | ||
466 | NULL, 0), | ||
467 | SND_SOC_DAPM_MIXER("HSL Enable", | ||
468 | AB8500_ANACONF4, AB8500_ANACONF4_ENHSL, 0, | ||
469 | NULL, 0), | ||
470 | SND_SOC_DAPM_MIXER("HSR Enable", | ||
471 | AB8500_ANACONF4, AB8500_ANACONF4_ENHSR, 0, | ||
472 | NULL, 0), | ||
473 | SND_SOC_DAPM_PGA("HSL Volume", | ||
474 | SND_SOC_NOPM, 0, 0, | ||
475 | NULL, 0), | ||
476 | SND_SOC_DAPM_PGA("HSR Volume", | ||
477 | SND_SOC_NOPM, 0, 0, | ||
478 | NULL, 0), | ||
479 | |||
480 | SND_SOC_DAPM_OUTPUT("Headset Left"), | ||
481 | SND_SOC_DAPM_OUTPUT("Headset Right"), | ||
482 | |||
483 | /* LineOut path */ | ||
484 | |||
485 | SND_SOC_DAPM_MUX("LineOut Source", | ||
486 | SND_SOC_NOPM, 0, 0, dapm_lineout_source), | ||
487 | |||
488 | SND_SOC_DAPM_MIXER("LOL Disable HFL", | ||
489 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 1, | ||
490 | NULL, 0), | ||
491 | SND_SOC_DAPM_MIXER("LOR Disable HFR", | ||
492 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 1, | ||
493 | NULL, 0), | ||
494 | |||
495 | SND_SOC_DAPM_MIXER("LOL Enable", | ||
496 | AB8500_ANACONF5, AB8500_ANACONF5_ENLOL, 0, | ||
497 | NULL, 0), | ||
498 | SND_SOC_DAPM_MIXER("LOR Enable", | ||
499 | AB8500_ANACONF5, AB8500_ANACONF5_ENLOR, 0, | ||
500 | NULL, 0), | ||
501 | |||
502 | SND_SOC_DAPM_OUTPUT("LineOut Left"), | ||
503 | SND_SOC_DAPM_OUTPUT("LineOut Right"), | ||
504 | |||
505 | /* Earpiece path */ | ||
506 | |||
507 | SND_SOC_DAPM_MUX("Earpiece or LineOut Mono Source", | ||
508 | SND_SOC_NOPM, 0, 0, &dapm_ear_lineout_source), | ||
509 | SND_SOC_DAPM_MIXER("EAR DAC", | ||
510 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACEAR, 0, | ||
511 | NULL, 0), | ||
512 | SND_SOC_DAPM_MIXER("EAR Mute", | ||
513 | AB8500_MUTECONF, AB8500_MUTECONF_MUTEAR, 1, | ||
514 | NULL, 0), | ||
515 | SND_SOC_DAPM_MIXER("EAR Enable", | ||
516 | AB8500_ANACONF4, AB8500_ANACONF4_ENEAR, 0, | ||
517 | NULL, 0), | ||
518 | |||
519 | SND_SOC_DAPM_OUTPUT("Earpiece"), | ||
520 | |||
521 | /* Handsfree path */ | ||
522 | |||
523 | SND_SOC_DAPM_MIXER("DA3 Channel Volume", | ||
524 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA3, 0, | ||
525 | NULL, 0), | ||
526 | SND_SOC_DAPM_MIXER("DA4 Channel Volume", | ||
527 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA4, 0, | ||
528 | NULL, 0), | ||
529 | SND_SOC_DAPM_MUX("Speaker Left Source", | ||
530 | SND_SOC_NOPM, 0, 0, dapm_HFl_select), | ||
531 | SND_SOC_DAPM_MUX("Speaker Right Source", | ||
532 | SND_SOC_NOPM, 0, 0, dapm_HFr_select), | ||
533 | SND_SOC_DAPM_MIXER("HFL DAC", AB8500_DAPATHCONF, | ||
534 | AB8500_DAPATHCONF_ENDACHFL, 0, | ||
535 | NULL, 0), | ||
536 | SND_SOC_DAPM_MIXER("HFR DAC", | ||
537 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHFR, 0, | ||
538 | NULL, 0), | ||
539 | SND_SOC_DAPM_MIXER("DA4 or ANC path to HfR", | ||
540 | AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFREN, 0, | ||
541 | NULL, 0), | ||
542 | SND_SOC_DAPM_MIXER("DA3 or ANC path to HfL", | ||
543 | AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFLEN, 0, | ||
544 | NULL, 0), | ||
545 | SND_SOC_DAPM_MIXER("HFL Enable", | ||
546 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 0, | ||
547 | NULL, 0), | ||
548 | SND_SOC_DAPM_MIXER("HFR Enable", | ||
549 | AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 0, | ||
550 | NULL, 0), | ||
551 | |||
552 | SND_SOC_DAPM_OUTPUT("Speaker Left"), | ||
553 | SND_SOC_DAPM_OUTPUT("Speaker Right"), | ||
554 | |||
555 | /* Vibrator path */ | ||
556 | |||
557 | SND_SOC_DAPM_INPUT("PWMGEN1"), | ||
558 | SND_SOC_DAPM_INPUT("PWMGEN2"), | ||
559 | |||
560 | SND_SOC_DAPM_MIXER("DA5 Channel Volume", | ||
561 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA5, 0, | ||
562 | NULL, 0), | ||
563 | SND_SOC_DAPM_MIXER("DA6 Channel Volume", | ||
564 | AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA6, 0, | ||
565 | NULL, 0), | ||
566 | SND_SOC_DAPM_MIXER("VIB1 DAC", | ||
567 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB1, 0, | ||
568 | NULL, 0), | ||
569 | SND_SOC_DAPM_MIXER("VIB2 DAC", | ||
570 | AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB2, 0, | ||
571 | NULL, 0), | ||
572 | SND_SOC_DAPM_MUX("Vibra 1 Controller", | ||
573 | SND_SOC_NOPM, 0, 0, dapm_pwm2vib1), | ||
574 | SND_SOC_DAPM_MUX("Vibra 2 Controller", | ||
575 | SND_SOC_NOPM, 0, 0, dapm_pwm2vib2), | ||
576 | SND_SOC_DAPM_MIXER("VIB1 Enable", | ||
577 | AB8500_ANACONF4, AB8500_ANACONF4_ENVIB1, 0, | ||
578 | NULL, 0), | ||
579 | SND_SOC_DAPM_MIXER("VIB2 Enable", | ||
580 | AB8500_ANACONF4, AB8500_ANACONF4_ENVIB2, 0, | ||
581 | NULL, 0), | ||
582 | |||
583 | SND_SOC_DAPM_OUTPUT("Vibra 1"), | ||
584 | SND_SOC_DAPM_OUTPUT("Vibra 2"), | ||
585 | |||
586 | /* Mic 1 */ | ||
587 | |||
588 | SND_SOC_DAPM_INPUT("Mic 1"), | ||
589 | |||
590 | SND_SOC_DAPM_MUX("Mic 1a or 1b Select", | ||
591 | SND_SOC_NOPM, 0, 0, dapm_mic1ab_mux), | ||
592 | SND_SOC_DAPM_MIXER("MIC1 Mute", | ||
593 | AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC1, 1, | ||
594 | NULL, 0), | ||
595 | SND_SOC_DAPM_MIXER("MIC1A V-AMICx Enable", | ||
596 | AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0, | ||
597 | NULL, 0), | ||
598 | SND_SOC_DAPM_MIXER("MIC1B V-AMICx Enable", | ||
599 | AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0, | ||
600 | NULL, 0), | ||
601 | SND_SOC_DAPM_MIXER("MIC1 ADC", | ||
602 | AB8500_ANACONF3, AB8500_ANACONF3_ENADCMIC, 0, | ||
603 | NULL, 0), | ||
604 | SND_SOC_DAPM_MUX("AD3 Source Select", | ||
605 | SND_SOC_NOPM, 0, 0, dapm_ad3_select), | ||
606 | SND_SOC_DAPM_MIXER("AD3 Channel Volume", | ||
607 | SND_SOC_NOPM, 0, 0, | ||
608 | NULL, 0), | ||
609 | SND_SOC_DAPM_MIXER("AD3 Enable", | ||
610 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, 0, | ||
611 | NULL, 0), | ||
612 | |||
613 | /* Mic 2 */ | ||
614 | |||
615 | SND_SOC_DAPM_INPUT("Mic 2"), | ||
616 | |||
617 | SND_SOC_DAPM_MIXER("MIC2 Mute", | ||
618 | AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC2, 1, | ||
619 | NULL, 0), | ||
620 | SND_SOC_DAPM_MIXER("MIC2 V-AMICx Enable", AB8500_ANACONF2, | ||
621 | AB8500_ANACONF2_ENMIC2, 0, | ||
622 | NULL, 0), | ||
623 | |||
624 | /* LineIn */ | ||
625 | |||
626 | SND_SOC_DAPM_INPUT("LineIn Left"), | ||
627 | SND_SOC_DAPM_INPUT("LineIn Right"), | ||
628 | |||
629 | SND_SOC_DAPM_MIXER("LINL Mute", | ||
630 | AB8500_ANACONF2, AB8500_ANACONF2_MUTLINL, 1, | ||
631 | NULL, 0), | ||
632 | SND_SOC_DAPM_MIXER("LINR Mute", | ||
633 | AB8500_ANACONF2, AB8500_ANACONF2_MUTLINR, 1, | ||
634 | NULL, 0), | ||
635 | SND_SOC_DAPM_MIXER("LINL Enable", AB8500_ANACONF2, | ||
636 | AB8500_ANACONF2_ENLINL, 0, | ||
637 | NULL, 0), | ||
638 | SND_SOC_DAPM_MIXER("LINR Enable", AB8500_ANACONF2, | ||
639 | AB8500_ANACONF2_ENLINR, 0, | ||
640 | NULL, 0), | ||
641 | |||
642 | /* LineIn Bypass path */ | ||
643 | SND_SOC_DAPM_MIXER("LINL to HSL Volume", | ||
644 | SND_SOC_NOPM, 0, 0, | ||
645 | NULL, 0), | ||
646 | SND_SOC_DAPM_MIXER("LINR to HSR Volume", | ||
647 | SND_SOC_NOPM, 0, 0, | ||
648 | NULL, 0), | ||
649 | |||
650 | /* LineIn, Mic 2 */ | ||
651 | SND_SOC_DAPM_MUX("Mic 2 or LINR Select", | ||
652 | SND_SOC_NOPM, 0, 0, dapm_mic2lr_select), | ||
653 | SND_SOC_DAPM_MIXER("LINL ADC", AB8500_ANACONF3, | ||
654 | AB8500_ANACONF3_ENADCLINL, 0, | ||
655 | NULL, 0), | ||
656 | SND_SOC_DAPM_MIXER("LINR ADC", AB8500_ANACONF3, | ||
657 | AB8500_ANACONF3_ENADCLINR, 0, | ||
658 | NULL, 0), | ||
659 | SND_SOC_DAPM_MUX("AD1 Source Select", | ||
660 | SND_SOC_NOPM, 0, 0, dapm_ad1_select), | ||
661 | SND_SOC_DAPM_MUX("AD2 Source Select", | ||
662 | SND_SOC_NOPM, 0, 0, dapm_ad2_select), | ||
663 | SND_SOC_DAPM_MIXER("AD1 Channel Volume", | ||
664 | SND_SOC_NOPM, 0, 0, | ||
665 | NULL, 0), | ||
666 | SND_SOC_DAPM_MIXER("AD2 Channel Volume", | ||
667 | SND_SOC_NOPM, 0, 0, | ||
668 | NULL, 0), | ||
669 | |||
670 | SND_SOC_DAPM_MIXER("AD12 Enable", | ||
671 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD12, 0, | ||
672 | NULL, 0), | ||
673 | |||
674 | /* HD Capture path */ | ||
675 | |||
676 | SND_SOC_DAPM_MUX("AD5 Source Select", | ||
677 | SND_SOC_NOPM, 0, 0, dapm_ad5_select), | ||
678 | SND_SOC_DAPM_MUX("AD6 Source Select", | ||
679 | SND_SOC_NOPM, 0, 0, dapm_ad6_select), | ||
680 | SND_SOC_DAPM_MIXER("AD5 Channel Volume", | ||
681 | SND_SOC_NOPM, 0, 0, | ||
682 | NULL, 0), | ||
683 | SND_SOC_DAPM_MIXER("AD6 Channel Volume", | ||
684 | SND_SOC_NOPM, 0, 0, | ||
685 | NULL, 0), | ||
686 | SND_SOC_DAPM_MIXER("AD57 Enable", | ||
687 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0, | ||
688 | NULL, 0), | ||
689 | SND_SOC_DAPM_MIXER("AD68 Enable", | ||
690 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0, | ||
691 | NULL, 0), | ||
692 | |||
693 | /* Digital Microphone path */ | ||
694 | |||
695 | SND_SOC_DAPM_INPUT("DMic 1"), | ||
696 | SND_SOC_DAPM_INPUT("DMic 2"), | ||
697 | SND_SOC_DAPM_INPUT("DMic 3"), | ||
698 | SND_SOC_DAPM_INPUT("DMic 4"), | ||
699 | SND_SOC_DAPM_INPUT("DMic 5"), | ||
700 | SND_SOC_DAPM_INPUT("DMic 6"), | ||
701 | |||
702 | SND_SOC_DAPM_MIXER("DMIC1", | ||
703 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0, | ||
704 | NULL, 0), | ||
705 | SND_SOC_DAPM_MIXER("DMIC2", | ||
706 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0, | ||
707 | NULL, 0), | ||
708 | SND_SOC_DAPM_MIXER("DMIC3", | ||
709 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0, | ||
710 | NULL, 0), | ||
711 | SND_SOC_DAPM_MIXER("DMIC4", | ||
712 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0, | ||
713 | NULL, 0), | ||
714 | SND_SOC_DAPM_MIXER("DMIC5", | ||
715 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0, | ||
716 | NULL, 0), | ||
717 | SND_SOC_DAPM_MIXER("DMIC6", | ||
718 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0, | ||
719 | NULL, 0), | ||
720 | SND_SOC_DAPM_MIXER("AD4 Channel Volume", | ||
721 | SND_SOC_NOPM, 0, 0, | ||
722 | NULL, 0), | ||
723 | SND_SOC_DAPM_MIXER("AD4 Enable", | ||
724 | AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, | ||
725 | 0, NULL, 0), | ||
726 | |||
727 | /* Acoustical Noise Cancellation path */ | ||
728 | |||
729 | SND_SOC_DAPM_INPUT("ANC Configure Input"), | ||
730 | SND_SOC_DAPM_OUTPUT("ANC Configure Output"), | ||
731 | |||
732 | SND_SOC_DAPM_MUX("ANC Source", | ||
733 | SND_SOC_NOPM, 0, 0, | ||
734 | dapm_anc_in_select), | ||
735 | SND_SOC_DAPM_SWITCH("ANC", | ||
736 | SND_SOC_NOPM, 0, 0, | ||
737 | dapm_anc_enable), | ||
738 | SND_SOC_DAPM_SWITCH("ANC to Earpiece", | ||
739 | SND_SOC_NOPM, 0, 0, | ||
740 | dapm_anc_ear_mute), | ||
741 | |||
742 | /* Sidetone Filter path */ | ||
743 | |||
744 | SND_SOC_DAPM_MUX("Sidetone Left Source", | ||
745 | SND_SOC_NOPM, 0, 0, | ||
746 | dapm_stfir1_in_select), | ||
747 | SND_SOC_DAPM_MUX("Sidetone Right Source", | ||
748 | SND_SOC_NOPM, 0, 0, | ||
749 | dapm_stfir2_in_select), | ||
750 | SND_SOC_DAPM_MIXER("STFIR1 Control", | ||
751 | SND_SOC_NOPM, 0, 0, | ||
752 | NULL, 0), | ||
753 | SND_SOC_DAPM_MIXER("STFIR2 Control", | ||
754 | SND_SOC_NOPM, 0, 0, | ||
755 | NULL, 0), | ||
756 | SND_SOC_DAPM_MIXER("STFIR1 Volume", | ||
757 | SND_SOC_NOPM, 0, 0, | ||
758 | NULL, 0), | ||
759 | SND_SOC_DAPM_MIXER("STFIR2 Volume", | ||
760 | SND_SOC_NOPM, 0, 0, | ||
761 | NULL, 0), | ||
762 | }; | ||
763 | |||
764 | /* | ||
765 | * DAPM-routes | ||
766 | */ | ||
767 | static const struct snd_soc_dapm_route ab8500_dapm_routes[] = { | ||
768 | /* Power AB8500 audio-block when AD/DA is active */ | ||
769 | {"Main Supply", NULL, "V-AUD"}, | ||
770 | {"Main Supply", NULL, "audioclk"}, | ||
771 | {"Main Supply", NULL, "Audio Power"}, | ||
772 | {"Main Supply", NULL, "Audio Analog Power"}, | ||
773 | |||
774 | {"DAC", NULL, "ab8500_0p"}, | ||
775 | {"DAC", NULL, "Main Supply"}, | ||
776 | {"ADC", NULL, "ab8500_0c"}, | ||
777 | {"ADC", NULL, "Main Supply"}, | ||
778 | |||
779 | /* ANC Configure */ | ||
780 | {"ANC Configure Input", NULL, "Main Supply"}, | ||
781 | {"ANC Configure Output", NULL, "ANC Configure Input"}, | ||
782 | |||
783 | /* AD/DA */ | ||
784 | {"ADC", NULL, "ADC Input"}, | ||
785 | {"DAC Output", NULL, "DAC"}, | ||
786 | |||
787 | /* Powerup charge pump if DA1/2 is in use */ | ||
788 | |||
789 | {"DA_IN1", NULL, "ab8500_0p"}, | ||
790 | {"DA_IN1", NULL, "Charge Pump"}, | ||
791 | {"DA_IN2", NULL, "ab8500_0p"}, | ||
792 | {"DA_IN2", NULL, "Charge Pump"}, | ||
793 | |||
794 | /* Headset path */ | ||
795 | |||
796 | {"DA1 Enable", NULL, "DA_IN1"}, | ||
797 | {"DA2 Enable", NULL, "DA_IN2"}, | ||
798 | |||
799 | {"HSL Digital Volume", NULL, "DA1 Enable"}, | ||
800 | {"HSR Digital Volume", NULL, "DA2 Enable"}, | ||
801 | |||
802 | {"HSL DAC", NULL, "HSL Digital Volume"}, | ||
803 | {"HSR DAC", NULL, "HSR Digital Volume"}, | ||
804 | |||
805 | {"HSL DAC Mute", NULL, "HSL DAC"}, | ||
806 | {"HSR DAC Mute", NULL, "HSR DAC"}, | ||
807 | |||
808 | {"HSL DAC Driver", NULL, "HSL DAC Mute"}, | ||
809 | {"HSR DAC Driver", NULL, "HSR DAC Mute"}, | ||
810 | |||
811 | {"HSL Mute", NULL, "HSL DAC Driver"}, | ||
812 | {"HSR Mute", NULL, "HSR DAC Driver"}, | ||
813 | |||
814 | {"HSL Enable", NULL, "HSL Mute"}, | ||
815 | {"HSR Enable", NULL, "HSR Mute"}, | ||
816 | |||
817 | {"HSL Volume", NULL, "HSL Enable"}, | ||
818 | {"HSR Volume", NULL, "HSR Enable"}, | ||
819 | |||
820 | {"Headset Left", NULL, "HSL Volume"}, | ||
821 | {"Headset Right", NULL, "HSR Volume"}, | ||
822 | |||
823 | /* HF or LineOut path */ | ||
824 | |||
825 | {"DA_IN3", NULL, "ab8500_0p"}, | ||
826 | {"DA3 Channel Volume", NULL, "DA_IN3"}, | ||
827 | {"DA_IN4", NULL, "ab8500_0p"}, | ||
828 | {"DA4 Channel Volume", NULL, "DA_IN4"}, | ||
829 | |||
830 | {"Speaker Left Source", "Audio Path", "DA3 Channel Volume"}, | ||
831 | {"Speaker Right Source", "Audio Path", "DA4 Channel Volume"}, | ||
832 | |||
833 | {"DA3 or ANC path to HfL", NULL, "Speaker Left Source"}, | ||
834 | {"DA4 or ANC path to HfR", NULL, "Speaker Right Source"}, | ||
835 | |||
836 | /* HF path */ | ||
837 | |||
838 | {"HFL DAC", NULL, "DA3 or ANC path to HfL"}, | ||
839 | {"HFR DAC", NULL, "DA4 or ANC path to HfR"}, | ||
840 | |||
841 | {"HFL Enable", NULL, "HFL DAC"}, | ||
842 | {"HFR Enable", NULL, "HFR DAC"}, | ||
843 | |||
844 | {"Speaker Left", NULL, "HFL Enable"}, | ||
845 | {"Speaker Right", NULL, "HFR Enable"}, | ||
846 | |||
847 | /* Earpiece path */ | ||
848 | |||
849 | {"Earpiece or LineOut Mono Source", "Headset Left", | ||
850 | "HSL Digital Volume"}, | ||
851 | {"Earpiece or LineOut Mono Source", "Speaker Left", | ||
852 | "DA3 or ANC path to HfL"}, | ||
853 | |||
854 | {"EAR DAC", NULL, "Earpiece or LineOut Mono Source"}, | ||
855 | |||
856 | {"EAR Mute", NULL, "EAR DAC"}, | ||
857 | |||
858 | {"EAR Enable", NULL, "EAR Mute"}, | ||
859 | |||
860 | {"Earpiece", NULL, "EAR Enable"}, | ||
861 | |||
862 | /* LineOut path stereo */ | ||
863 | |||
864 | {"LineOut Source", "Stereo Path", "HSL DAC Driver"}, | ||
865 | {"LineOut Source", "Stereo Path", "HSR DAC Driver"}, | ||
866 | |||
867 | /* LineOut path mono */ | ||
868 | |||
869 | {"LineOut Source", "Mono Path", "EAR DAC"}, | ||
870 | |||
871 | /* LineOut path */ | ||
872 | |||
873 | {"LOL Disable HFL", NULL, "LineOut Source"}, | ||
874 | {"LOR Disable HFR", NULL, "LineOut Source"}, | ||
875 | |||
876 | {"LOL Enable", NULL, "LOL Disable HFL"}, | ||
877 | {"LOR Enable", NULL, "LOR Disable HFR"}, | ||
878 | |||
879 | {"LineOut Left", NULL, "LOL Enable"}, | ||
880 | {"LineOut Right", NULL, "LOR Enable"}, | ||
881 | |||
882 | /* Vibrator path */ | ||
883 | |||
884 | {"DA_IN5", NULL, "ab8500_0p"}, | ||
885 | {"DA5 Channel Volume", NULL, "DA_IN5"}, | ||
886 | {"DA_IN6", NULL, "ab8500_0p"}, | ||
887 | {"DA6 Channel Volume", NULL, "DA_IN6"}, | ||
888 | |||
889 | {"VIB1 DAC", NULL, "DA5 Channel Volume"}, | ||
890 | {"VIB2 DAC", NULL, "DA6 Channel Volume"}, | ||
891 | |||
892 | {"Vibra 1 Controller", "Audio Path", "VIB1 DAC"}, | ||
893 | {"Vibra 2 Controller", "Audio Path", "VIB2 DAC"}, | ||
894 | {"Vibra 1 Controller", "PWM Generator", "PWMGEN1"}, | ||
895 | {"Vibra 2 Controller", "PWM Generator", "PWMGEN2"}, | ||
896 | |||
897 | {"VIB1 Enable", NULL, "Vibra 1 Controller"}, | ||
898 | {"VIB2 Enable", NULL, "Vibra 2 Controller"}, | ||
899 | |||
900 | {"Vibra 1", NULL, "VIB1 Enable"}, | ||
901 | {"Vibra 2", NULL, "VIB2 Enable"}, | ||
902 | |||
903 | |||
904 | /* Mic 2 */ | ||
905 | |||
906 | {"MIC2 V-AMICx Enable", NULL, "Mic 2"}, | ||
907 | |||
908 | /* LineIn */ | ||
909 | {"LINL Mute", NULL, "LineIn Left"}, | ||
910 | {"LINR Mute", NULL, "LineIn Right"}, | ||
911 | |||
912 | {"LINL Enable", NULL, "LINL Mute"}, | ||
913 | {"LINR Enable", NULL, "LINR Mute"}, | ||
914 | |||
915 | /* LineIn, Mic 2 */ | ||
916 | {"Mic 2 or LINR Select", "LineIn Right", "LINR Enable"}, | ||
917 | {"Mic 2 or LINR Select", "Mic 2", "MIC2 V-AMICx Enable"}, | ||
918 | |||
919 | {"LINL ADC", NULL, "LINL Enable"}, | ||
920 | {"LINR ADC", NULL, "Mic 2 or LINR Select"}, | ||
921 | |||
922 | {"AD1 Source Select", "LineIn Left", "LINL ADC"}, | ||
923 | {"AD2 Source Select", "LineIn Right", "LINR ADC"}, | ||
924 | |||
925 | {"AD1 Channel Volume", NULL, "AD1 Source Select"}, | ||
926 | {"AD2 Channel Volume", NULL, "AD2 Source Select"}, | ||
927 | |||
928 | {"AD12 Enable", NULL, "AD1 Channel Volume"}, | ||
929 | {"AD12 Enable", NULL, "AD2 Channel Volume"}, | ||
930 | |||
931 | {"AD_OUT1", NULL, "ab8500_0c"}, | ||
932 | {"AD_OUT1", NULL, "AD12 Enable"}, | ||
933 | {"AD_OUT2", NULL, "ab8500_0c"}, | ||
934 | {"AD_OUT2", NULL, "AD12 Enable"}, | ||
935 | |||
936 | /* Mic 1 */ | ||
937 | |||
938 | {"MIC1 Mute", NULL, "Mic 1"}, | ||
939 | |||
940 | {"MIC1A V-AMICx Enable", NULL, "MIC1 Mute"}, | ||
941 | {"MIC1B V-AMICx Enable", NULL, "MIC1 Mute"}, | ||
942 | |||
943 | {"Mic 1a or 1b Select", "Mic 1a", "MIC1A V-AMICx Enable"}, | ||
944 | {"Mic 1a or 1b Select", "Mic 1b", "MIC1B V-AMICx Enable"}, | ||
945 | |||
946 | {"MIC1 ADC", NULL, "Mic 1a or 1b Select"}, | ||
947 | |||
948 | {"AD3 Source Select", "Mic 1", "MIC1 ADC"}, | ||
949 | |||
950 | {"AD3 Channel Volume", NULL, "AD3 Source Select"}, | ||
951 | |||
952 | {"AD3 Enable", NULL, "AD3 Channel Volume"}, | ||
953 | |||
954 | {"AD_OUT3", NULL, "ab8500_0c"}, | ||
955 | {"AD_OUT3", NULL, "AD3 Enable"}, | ||
956 | |||
957 | /* HD Capture path */ | ||
958 | |||
959 | {"AD5 Source Select", "Mic 2", "LINR ADC"}, | ||
960 | {"AD6 Source Select", "Mic 1", "MIC1 ADC"}, | ||
961 | |||
962 | {"AD5 Channel Volume", NULL, "AD5 Source Select"}, | ||
963 | {"AD6 Channel Volume", NULL, "AD6 Source Select"}, | ||
964 | |||
965 | {"AD57 Enable", NULL, "AD5 Channel Volume"}, | ||
966 | {"AD68 Enable", NULL, "AD6 Channel Volume"}, | ||
967 | |||
968 | {"AD_OUT57", NULL, "ab8500_0c"}, | ||
969 | {"AD_OUT57", NULL, "AD57 Enable"}, | ||
970 | {"AD_OUT68", NULL, "ab8500_0c"}, | ||
971 | {"AD_OUT68", NULL, "AD68 Enable"}, | ||
972 | |||
973 | /* Digital Microphone path */ | ||
974 | |||
975 | {"DMic 1", NULL, "V-DMIC"}, | ||
976 | {"DMic 2", NULL, "V-DMIC"}, | ||
977 | {"DMic 3", NULL, "V-DMIC"}, | ||
978 | {"DMic 4", NULL, "V-DMIC"}, | ||
979 | {"DMic 5", NULL, "V-DMIC"}, | ||
980 | {"DMic 6", NULL, "V-DMIC"}, | ||
981 | |||
982 | {"AD1 Source Select", NULL, "DMic 1"}, | ||
983 | {"AD2 Source Select", NULL, "DMic 2"}, | ||
984 | {"AD3 Source Select", NULL, "DMic 3"}, | ||
985 | {"AD5 Source Select", NULL, "DMic 5"}, | ||
986 | {"AD6 Source Select", NULL, "DMic 6"}, | ||
987 | |||
988 | {"AD4 Channel Volume", NULL, "DMic 4"}, | ||
989 | {"AD4 Enable", NULL, "AD4 Channel Volume"}, | ||
990 | |||
991 | {"AD_OUT4", NULL, "ab8500_0c"}, | ||
992 | {"AD_OUT4", NULL, "AD4 Enable"}, | ||
993 | |||
994 | /* LineIn Bypass path */ | ||
995 | |||
996 | {"LINL to HSL Volume", NULL, "LINL Enable"}, | ||
997 | {"LINR to HSR Volume", NULL, "LINR Enable"}, | ||
998 | |||
999 | {"HSL DAC Driver", NULL, "LINL to HSL Volume"}, | ||
1000 | {"HSR DAC Driver", NULL, "LINR to HSR Volume"}, | ||
1001 | |||
1002 | /* ANC path (Acoustic Noise Cancellation) */ | ||
1003 | |||
1004 | {"ANC Source", "Mic 2 / DMic 5", "AD5 Channel Volume"}, | ||
1005 | {"ANC Source", "Mic 1 / DMic 6", "AD6 Channel Volume"}, | ||
1006 | |||
1007 | {"ANC", "Switch", "ANC Source"}, | ||
1008 | |||
1009 | {"Speaker Left Source", "ANC", "ANC"}, | ||
1010 | {"Speaker Right Source", "ANC", "ANC"}, | ||
1011 | {"ANC to Earpiece", "Switch", "ANC"}, | ||
1012 | |||
1013 | {"HSL Digital Volume", NULL, "ANC to Earpiece"}, | ||
1014 | |||
1015 | /* Sidetone Filter path */ | ||
1016 | |||
1017 | {"Sidetone Left Source", "LineIn Left", "AD12 Enable"}, | ||
1018 | {"Sidetone Left Source", "LineIn Right", "AD12 Enable"}, | ||
1019 | {"Sidetone Left Source", "Mic 1", "AD3 Enable"}, | ||
1020 | {"Sidetone Left Source", "Headset Left", "DA_IN1"}, | ||
1021 | {"Sidetone Right Source", "LineIn Right", "AD12 Enable"}, | ||
1022 | {"Sidetone Right Source", "Mic 1", "AD3 Enable"}, | ||
1023 | {"Sidetone Right Source", "DMic 4", "AD4 Enable"}, | ||
1024 | {"Sidetone Right Source", "Headset Right", "DA_IN2"}, | ||
1025 | |||
1026 | {"STFIR1 Control", NULL, "Sidetone Left Source"}, | ||
1027 | {"STFIR2 Control", NULL, "Sidetone Right Source"}, | ||
1028 | |||
1029 | {"STFIR1 Volume", NULL, "STFIR1 Control"}, | ||
1030 | {"STFIR2 Volume", NULL, "STFIR2 Control"}, | ||
1031 | |||
1032 | {"DA1 Enable", NULL, "STFIR1 Volume"}, | ||
1033 | {"DA2 Enable", NULL, "STFIR2 Volume"}, | ||
1034 | }; | ||
1035 | |||
1036 | static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1a_vamicx[] = { | ||
1037 | {"MIC1A V-AMICx Enable", NULL, "V-AMIC1"}, | ||
1038 | {"MIC1A V-AMICx Enable", NULL, "V-AMIC2"}, | ||
1039 | }; | ||
1040 | |||
1041 | static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1b_vamicx[] = { | ||
1042 | {"MIC1B V-AMICx Enable", NULL, "V-AMIC1"}, | ||
1043 | {"MIC1B V-AMICx Enable", NULL, "V-AMIC2"}, | ||
1044 | }; | ||
1045 | |||
1046 | static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = { | ||
1047 | {"MIC2 V-AMICx Enable", NULL, "V-AMIC1"}, | ||
1048 | {"MIC2 V-AMICx Enable", NULL, "V-AMIC2"}, | ||
1049 | }; | ||
1050 | |||
1051 | /* ANC FIR-coefficients configuration sequence */ | ||
1052 | static void anc_fir(struct snd_soc_codec *codec, | ||
1053 | unsigned int bnk, unsigned int par, unsigned int val) | ||
1054 | { | ||
1055 | if (par == 0 && bnk == 0) | ||
1056 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1057 | BIT(AB8500_ANCCONF1_ANCFIRUPDATE), | ||
1058 | BIT(AB8500_ANCCONF1_ANCFIRUPDATE)); | ||
1059 | |||
1060 | snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff); | ||
1061 | snd_soc_write(codec, AB8500_ANCCONF6, val & 0xff); | ||
1062 | |||
1063 | if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1) | ||
1064 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1065 | BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0); | ||
1066 | } | ||
1067 | |||
1068 | /* ANC IIR-coefficients configuration sequence */ | ||
1069 | static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk, | ||
1070 | unsigned int par, unsigned int val) | ||
1071 | { | ||
1072 | if (par == 0) { | ||
1073 | if (bnk == 0) { | ||
1074 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1075 | BIT(AB8500_ANCCONF1_ANCIIRINIT), | ||
1076 | BIT(AB8500_ANCCONF1_ANCIIRINIT)); | ||
1077 | usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY); | ||
1078 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1079 | BIT(AB8500_ANCCONF1_ANCIIRINIT), 0); | ||
1080 | usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY); | ||
1081 | } else { | ||
1082 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1083 | BIT(AB8500_ANCCONF1_ANCIIRUPDATE), | ||
1084 | BIT(AB8500_ANCCONF1_ANCIIRUPDATE)); | ||
1085 | } | ||
1086 | } else if (par > 3) { | ||
1087 | snd_soc_write(codec, AB8500_ANCCONF7, 0); | ||
1088 | snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff); | ||
1089 | } | ||
1090 | |||
1091 | snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff); | ||
1092 | snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff); | ||
1093 | |||
1094 | if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1) | ||
1095 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1096 | BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0); | ||
1097 | } | ||
1098 | |||
1099 | /* ANC IIR-/FIR-coefficients configuration sequence */ | ||
1100 | static void anc_configure(struct snd_soc_codec *codec, | ||
1101 | bool apply_fir, bool apply_iir) | ||
1102 | { | ||
1103 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1104 | unsigned int bnk, par, val; | ||
1105 | |||
1106 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | ||
1107 | |||
1108 | if (apply_fir) | ||
1109 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1110 | BIT(AB8500_ANCCONF1_ENANC), 0); | ||
1111 | |||
1112 | snd_soc_update_bits(codec, AB8500_ANCCONF1, | ||
1113 | BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC)); | ||
1114 | |||
1115 | if (apply_fir) | ||
1116 | for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++) | ||
1117 | for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) { | ||
1118 | val = snd_soc_read(codec, | ||
1119 | drvdata->anc_fir_values[par]); | ||
1120 | anc_fir(codec, bnk, par, val); | ||
1121 | } | ||
1122 | |||
1123 | if (apply_iir) | ||
1124 | for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++) | ||
1125 | for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) { | ||
1126 | val = snd_soc_read(codec, | ||
1127 | drvdata->anc_iir_values[par]); | ||
1128 | anc_iir(codec, bnk, par, val); | ||
1129 | } | ||
1130 | |||
1131 | dev_dbg(codec->dev, "%s: Exit.\n", __func__); | ||
1132 | } | ||
1133 | |||
1134 | /* | ||
1135 | * Control-events | ||
1136 | */ | ||
1137 | |||
1138 | static int sid_status_control_get(struct snd_kcontrol *kcontrol, | ||
1139 | struct snd_ctl_elem_value *ucontrol) | ||
1140 | { | ||
1141 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1142 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1143 | |||
1144 | mutex_lock(&codec->mutex); | ||
1145 | ucontrol->value.integer.value[0] = drvdata->sid_status; | ||
1146 | mutex_unlock(&codec->mutex); | ||
1147 | |||
1148 | return 0; | ||
1149 | } | ||
1150 | |||
1151 | /* Write sidetone FIR-coefficients configuration sequence */ | ||
1152 | static int sid_status_control_put(struct snd_kcontrol *kcontrol, | ||
1153 | struct snd_ctl_elem_value *ucontrol) | ||
1154 | { | ||
1155 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1156 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1157 | unsigned int param, sidconf, val; | ||
1158 | int status = 1; | ||
1159 | |||
1160 | dev_dbg(codec->dev, "%s: Enter\n", __func__); | ||
1161 | |||
1162 | if (ucontrol->value.integer.value[0] != SID_APPLY_FIR) { | ||
1163 | dev_err(codec->dev, | ||
1164 | "%s: ERROR: This control supports '%s' only!\n", | ||
1165 | __func__, enum_sid_state[SID_APPLY_FIR]); | ||
1166 | return -EIO; | ||
1167 | } | ||
1168 | |||
1169 | mutex_lock(&codec->mutex); | ||
1170 | |||
1171 | sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF); | ||
1172 | if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) { | ||
1173 | if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) { | ||
1174 | dev_err(codec->dev, "%s: Sidetone busy while off!\n", | ||
1175 | __func__); | ||
1176 | status = -EPERM; | ||
1177 | } else { | ||
1178 | status = -EBUSY; | ||
1179 | } | ||
1180 | goto out; | ||
1181 | } | ||
1182 | |||
1183 | snd_soc_write(codec, AB8500_SIDFIRADR, 0); | ||
1184 | |||
1185 | for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) { | ||
1186 | val = snd_soc_read(codec, drvdata->sid_fir_values[param]); | ||
1187 | snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff); | ||
1188 | snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff); | ||
1189 | } | ||
1190 | |||
1191 | snd_soc_update_bits(codec, AB8500_SIDFIRADR, | ||
1192 | BIT(AB8500_SIDFIRADR_FIRSIDSET), | ||
1193 | BIT(AB8500_SIDFIRADR_FIRSIDSET)); | ||
1194 | snd_soc_update_bits(codec, AB8500_SIDFIRADR, | ||
1195 | BIT(AB8500_SIDFIRADR_FIRSIDSET), 0); | ||
1196 | |||
1197 | drvdata->sid_status = SID_FIR_CONFIGURED; | ||
1198 | |||
1199 | out: | ||
1200 | mutex_unlock(&codec->mutex); | ||
1201 | |||
1202 | dev_dbg(codec->dev, "%s: Exit\n", __func__); | ||
1203 | |||
1204 | return status; | ||
1205 | } | ||
1206 | |||
1207 | static int anc_status_control_get(struct snd_kcontrol *kcontrol, | ||
1208 | struct snd_ctl_elem_value *ucontrol) | ||
1209 | { | ||
1210 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1211 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1212 | |||
1213 | mutex_lock(&codec->mutex); | ||
1214 | ucontrol->value.integer.value[0] = drvdata->anc_status; | ||
1215 | mutex_unlock(&codec->mutex); | ||
1216 | |||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | static int anc_status_control_put(struct snd_kcontrol *kcontrol, | ||
1221 | struct snd_ctl_elem_value *ucontrol) | ||
1222 | { | ||
1223 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1224 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | ||
1225 | struct device *dev = codec->dev; | ||
1226 | bool apply_fir, apply_iir; | ||
1227 | int req, status; | ||
1228 | |||
1229 | dev_dbg(dev, "%s: Enter.\n", __func__); | ||
1230 | |||
1231 | mutex_lock(&drvdata->anc_lock); | ||
1232 | |||
1233 | req = ucontrol->value.integer.value[0]; | ||
1234 | if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR && | ||
1235 | req != ANC_APPLY_IIR) { | ||
1236 | dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n", | ||
1237 | __func__, enum_anc_state[req]); | ||
1238 | return -EINVAL; | ||
1239 | } | ||
1240 | apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR; | ||
1241 | apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR; | ||
1242 | |||
1243 | status = snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
1244 | "ANC Configure Input"); | ||
1245 | if (status < 0) { | ||
1246 | dev_err(dev, | ||
1247 | "%s: ERROR: Failed to enable power (status = %d)!\n", | ||
1248 | __func__, status); | ||
1249 | goto cleanup; | ||
1250 | } | ||
1251 | snd_soc_dapm_sync(&codec->dapm); | ||
1252 | |||
1253 | mutex_lock(&codec->mutex); | ||
1254 | anc_configure(codec, apply_fir, apply_iir); | ||
1255 | mutex_unlock(&codec->mutex); | ||
1256 | |||
1257 | if (apply_fir) { | ||
1258 | if (drvdata->anc_status == ANC_IIR_CONFIGURED) | ||
1259 | drvdata->anc_status = ANC_FIR_IIR_CONFIGURED; | ||
1260 | else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED) | ||
1261 | drvdata->anc_status = ANC_FIR_CONFIGURED; | ||
1262 | } | ||
1263 | if (apply_iir) { | ||
1264 | if (drvdata->anc_status == ANC_FIR_CONFIGURED) | ||
1265 | drvdata->anc_status = ANC_FIR_IIR_CONFIGURED; | ||
1266 | else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED) | ||
1267 | drvdata->anc_status = ANC_IIR_CONFIGURED; | ||
1268 | } | ||
1269 | |||
1270 | status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); | ||
1271 | snd_soc_dapm_sync(&codec->dapm); | ||
1272 | |||
1273 | cleanup: | ||
1274 | mutex_unlock(&drvdata->anc_lock); | ||
1275 | |||
1276 | if (status < 0) | ||
1277 | dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n", | ||
1278 | __func__, status); | ||
1279 | |||
1280 | dev_dbg(dev, "%s: Exit.\n", __func__); | ||
1281 | |||
1282 | return (status < 0) ? status : 1; | ||
1283 | } | ||
1284 | |||
1285 | static int filter_control_info(struct snd_kcontrol *kcontrol, | ||
1286 | struct snd_ctl_elem_info *uinfo) | ||
1287 | { | ||
1288 | struct filter_control *fc = | ||
1289 | (struct filter_control *)kcontrol->private_value; | ||
1290 | |||
1291 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1292 | uinfo->count = fc->count; | ||
1293 | uinfo->value.integer.min = fc->min; | ||
1294 | uinfo->value.integer.max = fc->max; | ||
1295 | |||
1296 | return 0; | ||
1297 | } | ||
1298 | |||
1299 | static int filter_control_get(struct snd_kcontrol *kcontrol, | ||
1300 | struct snd_ctl_elem_value *ucontrol) | ||
1301 | { | ||
1302 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1303 | struct filter_control *fc = | ||
1304 | (struct filter_control *)kcontrol->private_value; | ||
1305 | unsigned int i; | ||
1306 | |||
1307 | mutex_lock(&codec->mutex); | ||
1308 | for (i = 0; i < fc->count; i++) | ||
1309 | ucontrol->value.integer.value[i] = fc->value[i]; | ||
1310 | mutex_unlock(&codec->mutex); | ||
1311 | |||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | static int filter_control_put(struct snd_kcontrol *kcontrol, | ||
1316 | struct snd_ctl_elem_value *ucontrol) | ||
1317 | { | ||
1318 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1319 | struct filter_control *fc = | ||
1320 | (struct filter_control *)kcontrol->private_value; | ||
1321 | unsigned int i; | ||
1322 | |||
1323 | mutex_lock(&codec->mutex); | ||
1324 | for (i = 0; i < fc->count; i++) | ||
1325 | fc->value[i] = ucontrol->value.integer.value[i]; | ||
1326 | mutex_unlock(&codec->mutex); | ||
1327 | |||
1328 | return 0; | ||
1329 | } | ||
1330 | |||
1331 | /* | ||
1332 | * Controls - Non-DAPM ASoC | ||
1333 | */ | ||
1334 | |||
1335 | static DECLARE_TLV_DB_SCALE(adx_dig_gain_tlv, -3200, 100, 1); | ||
1336 | /* -32dB = Mute */ | ||
1337 | |||
1338 | static DECLARE_TLV_DB_SCALE(dax_dig_gain_tlv, -6300, 100, 1); | ||
1339 | /* -63dB = Mute */ | ||
1340 | |||
1341 | static DECLARE_TLV_DB_SCALE(hs_ear_dig_gain_tlv, -100, 100, 1); | ||
1342 | /* -1dB = Mute */ | ||
1343 | |||
1344 | static const unsigned int hs_gain_tlv[] = { | ||
1345 | TLV_DB_RANGE_HEAD(2), | ||
1346 | 0, 3, TLV_DB_SCALE_ITEM(-3200, 400, 0), | ||
1347 | 4, 15, TLV_DB_SCALE_ITEM(-1800, 200, 0), | ||
1348 | }; | ||
1349 | |||
1350 | static DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0); | ||
1351 | |||
1352 | static DECLARE_TLV_DB_SCALE(lin_gain_tlv, -1000, 200, 0); | ||
1353 | |||
1354 | static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1); | ||
1355 | /* -38dB = Mute */ | ||
1356 | |||
1357 | static const char * const enum_hsfadspeed[] = {"2ms", "0.5ms", "10.6ms", | ||
1358 | "5ms"}; | ||
1359 | static SOC_ENUM_SINGLE_DECL(soc_enum_hsfadspeed, | ||
1360 | AB8500_DIGMICCONF, AB8500_DIGMICCONF_HSFADSPEED, enum_hsfadspeed); | ||
1361 | |||
1362 | static const char * const enum_envdetthre[] = { | ||
1363 | "250mV", "300mV", "350mV", "400mV", | ||
1364 | "450mV", "500mV", "550mV", "600mV", | ||
1365 | "650mV", "700mV", "750mV", "800mV", | ||
1366 | "850mV", "900mV", "950mV", "1.00V" }; | ||
1367 | static SOC_ENUM_SINGLE_DECL(soc_enum_envdeththre, | ||
1368 | AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETHTHRE, enum_envdetthre); | ||
1369 | static SOC_ENUM_SINGLE_DECL(soc_enum_envdetlthre, | ||
1370 | AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETLTHRE, enum_envdetthre); | ||
1371 | static const char * const enum_envdettime[] = { | ||
1372 | "26.6us", "53.2us", "106us", "213us", | ||
1373 | "426us", "851us", "1.70ms", "3.40ms", | ||
1374 | "6.81ms", "13.6ms", "27.2ms", "54.5ms", | ||
1375 | "109ms", "218ms", "436ms", "872ms" }; | ||
1376 | static SOC_ENUM_SINGLE_DECL(soc_enum_envdettime, | ||
1377 | AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETTIME, enum_envdettime); | ||
1378 | |||
1379 | static const char * const enum_sinc31[] = {"Sinc 3", "Sinc 1"}; | ||
1380 | static SOC_ENUM_SINGLE_DECL(soc_enum_hsesinc, AB8500_HSLEARDIGGAIN, | ||
1381 | AB8500_HSLEARDIGGAIN_HSSINC1, enum_sinc31); | ||
1382 | |||
1383 | static const char * const enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"}; | ||
1384 | static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed, AB8500_HSRDIGGAIN, | ||
1385 | AB8500_HSRDIGGAIN_FADESPEED, enum_fadespeed); | ||
1386 | |||
1387 | /* Earpiece */ | ||
1388 | |||
1389 | static const char * const enum_lowpow[] = {"Normal", "Low Power"}; | ||
1390 | static SOC_ENUM_SINGLE_DECL(soc_enum_eardaclowpow, AB8500_ANACONF1, | ||
1391 | AB8500_ANACONF1_EARDACLOWPOW, enum_lowpow); | ||
1392 | static SOC_ENUM_SINGLE_DECL(soc_enum_eardrvlowpow, AB8500_ANACONF1, | ||
1393 | AB8500_ANACONF1_EARDRVLOWPOW, enum_lowpow); | ||
1394 | |||
1395 | static const char * const enum_av_mode[] = {"Audio", "Voice"}; | ||
1396 | static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12voice, AB8500_ADFILTCONF, | ||
1397 | AB8500_ADFILTCONF_AD1VOICE, AB8500_ADFILTCONF_AD2VOICE, enum_av_mode); | ||
1398 | static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34voice, AB8500_ADFILTCONF, | ||
1399 | AB8500_ADFILTCONF_AD3VOICE, AB8500_ADFILTCONF_AD4VOICE, enum_av_mode); | ||
1400 | |||
1401 | /* DA */ | ||
1402 | |||
1403 | static SOC_ENUM_SINGLE_DECL(soc_enum_da12voice, | ||
1404 | AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DA12VOICE, | ||
1405 | enum_av_mode); | ||
1406 | static SOC_ENUM_SINGLE_DECL(soc_enum_da34voice, | ||
1407 | AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DA34VOICE, | ||
1408 | enum_av_mode); | ||
1409 | static SOC_ENUM_SINGLE_DECL(soc_enum_da56voice, | ||
1410 | AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DA56VOICE, | ||
1411 | enum_av_mode); | ||
1412 | |||
1413 | static const char * const enum_da2hslr[] = {"Sidetone", "Audio Path"}; | ||
1414 | static SOC_ENUM_DOUBLE_DECL(soc_enum_da2hslr, AB8500_DIGMULTCONF1, | ||
1415 | AB8500_DIGMULTCONF1_DATOHSLEN, | ||
1416 | AB8500_DIGMULTCONF1_DATOHSREN, enum_da2hslr); | ||
1417 | |||
1418 | static const char * const enum_sinc53[] = {"Sinc 5", "Sinc 3"}; | ||
1419 | static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic12sinc, AB8500_DMICFILTCONF, | ||
1420 | AB8500_DMICFILTCONF_DMIC1SINC3, | ||
1421 | AB8500_DMICFILTCONF_DMIC2SINC3, enum_sinc53); | ||
1422 | static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic34sinc, AB8500_DMICFILTCONF, | ||
1423 | AB8500_DMICFILTCONF_DMIC3SINC3, | ||
1424 | AB8500_DMICFILTCONF_DMIC4SINC3, enum_sinc53); | ||
1425 | static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic56sinc, AB8500_DMICFILTCONF, | ||
1426 | AB8500_DMICFILTCONF_DMIC5SINC3, | ||
1427 | AB8500_DMICFILTCONF_DMIC6SINC3, enum_sinc53); | ||
1428 | |||
1429 | /* Digital interface - DA from slot mapping */ | ||
1430 | static const char * const enum_da_from_slot_map[] = {"SLOT0", | ||
1431 | "SLOT1", | ||
1432 | "SLOT2", | ||
1433 | "SLOT3", | ||
1434 | "SLOT4", | ||
1435 | "SLOT5", | ||
1436 | "SLOT6", | ||
1437 | "SLOT7", | ||
1438 | "SLOT8", | ||
1439 | "SLOT9", | ||
1440 | "SLOT10", | ||
1441 | "SLOT11", | ||
1442 | "SLOT12", | ||
1443 | "SLOT13", | ||
1444 | "SLOT14", | ||
1445 | "SLOT15", | ||
1446 | "SLOT16", | ||
1447 | "SLOT17", | ||
1448 | "SLOT18", | ||
1449 | "SLOT19", | ||
1450 | "SLOT20", | ||
1451 | "SLOT21", | ||
1452 | "SLOT22", | ||
1453 | "SLOT23", | ||
1454 | "SLOT24", | ||
1455 | "SLOT25", | ||
1456 | "SLOT26", | ||
1457 | "SLOT27", | ||
1458 | "SLOT28", | ||
1459 | "SLOT29", | ||
1460 | "SLOT30", | ||
1461 | "SLOT31"}; | ||
1462 | static SOC_ENUM_SINGLE_DECL(soc_enum_da1slotmap, | ||
1463 | AB8500_DASLOTCONF1, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1464 | enum_da_from_slot_map); | ||
1465 | static SOC_ENUM_SINGLE_DECL(soc_enum_da2slotmap, | ||
1466 | AB8500_DASLOTCONF2, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1467 | enum_da_from_slot_map); | ||
1468 | static SOC_ENUM_SINGLE_DECL(soc_enum_da3slotmap, | ||
1469 | AB8500_DASLOTCONF3, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1470 | enum_da_from_slot_map); | ||
1471 | static SOC_ENUM_SINGLE_DECL(soc_enum_da4slotmap, | ||
1472 | AB8500_DASLOTCONF4, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1473 | enum_da_from_slot_map); | ||
1474 | static SOC_ENUM_SINGLE_DECL(soc_enum_da5slotmap, | ||
1475 | AB8500_DASLOTCONF5, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1476 | enum_da_from_slot_map); | ||
1477 | static SOC_ENUM_SINGLE_DECL(soc_enum_da6slotmap, | ||
1478 | AB8500_DASLOTCONF6, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1479 | enum_da_from_slot_map); | ||
1480 | static SOC_ENUM_SINGLE_DECL(soc_enum_da7slotmap, | ||
1481 | AB8500_DASLOTCONF7, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1482 | enum_da_from_slot_map); | ||
1483 | static SOC_ENUM_SINGLE_DECL(soc_enum_da8slotmap, | ||
1484 | AB8500_DASLOTCONF8, AB8500_DASLOTCONFX_SLTODAX_SHIFT, | ||
1485 | enum_da_from_slot_map); | ||
1486 | |||
1487 | /* Digital interface - AD to slot mapping */ | ||
1488 | static const char * const enum_ad_to_slot_map[] = {"AD_OUT1", | ||
1489 | "AD_OUT2", | ||
1490 | "AD_OUT3", | ||
1491 | "AD_OUT4", | ||
1492 | "AD_OUT5", | ||
1493 | "AD_OUT6", | ||
1494 | "AD_OUT7", | ||
1495 | "AD_OUT8", | ||
1496 | "zeroes", | ||
1497 | "tristate"}; | ||
1498 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map, | ||
1499 | AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1500 | enum_ad_to_slot_map); | ||
1501 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot1map, | ||
1502 | AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1503 | enum_ad_to_slot_map); | ||
1504 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot2map, | ||
1505 | AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1506 | enum_ad_to_slot_map); | ||
1507 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot3map, | ||
1508 | AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1509 | enum_ad_to_slot_map); | ||
1510 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot4map, | ||
1511 | AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1512 | enum_ad_to_slot_map); | ||
1513 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot5map, | ||
1514 | AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1515 | enum_ad_to_slot_map); | ||
1516 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot6map, | ||
1517 | AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1518 | enum_ad_to_slot_map); | ||
1519 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot7map, | ||
1520 | AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1521 | enum_ad_to_slot_map); | ||
1522 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot8map, | ||
1523 | AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1524 | enum_ad_to_slot_map); | ||
1525 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot9map, | ||
1526 | AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1527 | enum_ad_to_slot_map); | ||
1528 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot10map, | ||
1529 | AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1530 | enum_ad_to_slot_map); | ||
1531 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot11map, | ||
1532 | AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1533 | enum_ad_to_slot_map); | ||
1534 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot12map, | ||
1535 | AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1536 | enum_ad_to_slot_map); | ||
1537 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot13map, | ||
1538 | AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1539 | enum_ad_to_slot_map); | ||
1540 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot14map, | ||
1541 | AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1542 | enum_ad_to_slot_map); | ||
1543 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot15map, | ||
1544 | AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1545 | enum_ad_to_slot_map); | ||
1546 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot16map, | ||
1547 | AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1548 | enum_ad_to_slot_map); | ||
1549 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot17map, | ||
1550 | AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1551 | enum_ad_to_slot_map); | ||
1552 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot18map, | ||
1553 | AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1554 | enum_ad_to_slot_map); | ||
1555 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot19map, | ||
1556 | AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1557 | enum_ad_to_slot_map); | ||
1558 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot20map, | ||
1559 | AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1560 | enum_ad_to_slot_map); | ||
1561 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot21map, | ||
1562 | AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1563 | enum_ad_to_slot_map); | ||
1564 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot22map, | ||
1565 | AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1566 | enum_ad_to_slot_map); | ||
1567 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot23map, | ||
1568 | AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1569 | enum_ad_to_slot_map); | ||
1570 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot24map, | ||
1571 | AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1572 | enum_ad_to_slot_map); | ||
1573 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot25map, | ||
1574 | AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1575 | enum_ad_to_slot_map); | ||
1576 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot26map, | ||
1577 | AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1578 | enum_ad_to_slot_map); | ||
1579 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot27map, | ||
1580 | AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1581 | enum_ad_to_slot_map); | ||
1582 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot28map, | ||
1583 | AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1584 | enum_ad_to_slot_map); | ||
1585 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot29map, | ||
1586 | AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1587 | enum_ad_to_slot_map); | ||
1588 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot30map, | ||
1589 | AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_EVEN_SHIFT, | ||
1590 | enum_ad_to_slot_map); | ||
1591 | static SOC_ENUM_SINGLE_DECL(soc_enum_adslot31map, | ||
1592 | AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_ODD_SHIFT, | ||
1593 | enum_ad_to_slot_map); | ||
1594 | |||
1595 | /* Digital interface - Burst mode */ | ||
1596 | static const char * const enum_mask[] = {"Unmasked", "Masked"}; | ||
1597 | static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomask, | ||
1598 | AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOMASK, | ||
1599 | enum_mask); | ||
1600 | static const char * const enum_bitclk0[] = {"19_2_MHz", "38_4_MHz"}; | ||
1601 | static SOC_ENUM_SINGLE_DECL(soc_enum_bfifo19m2, | ||
1602 | AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFO19M2, | ||
1603 | enum_bitclk0); | ||
1604 | static const char * const enum_slavemaster[] = {"Slave", "Master"}; | ||
1605 | static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast, | ||
1606 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT, | ||
1607 | enum_slavemaster); | ||
1608 | |||
1609 | /* Sidetone */ | ||
1610 | static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state); | ||
1611 | |||
1612 | /* ANC */ | ||
1613 | static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_ancstate, enum_anc_state); | ||
1614 | |||
1615 | static struct snd_kcontrol_new ab8500_ctrls[] = { | ||
1616 | /* Charge pump */ | ||
1617 | SOC_ENUM("Charge Pump High Threshold For Low Voltage", | ||
1618 | soc_enum_envdeththre), | ||
1619 | SOC_ENUM("Charge Pump Low Threshold For Low Voltage", | ||
1620 | soc_enum_envdetlthre), | ||
1621 | SOC_SINGLE("Charge Pump Envelope Detection Switch", | ||
1622 | AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETCPEN, | ||
1623 | 1, 0), | ||
1624 | SOC_ENUM("Charge Pump Envelope Detection Decay Time", | ||
1625 | soc_enum_envdettime), | ||
1626 | |||
1627 | /* Headset */ | ||
1628 | SOC_ENUM("Headset Mode", soc_enum_da12voice), | ||
1629 | SOC_SINGLE("Headset High Pass Switch", | ||
1630 | AB8500_ANACONF1, AB8500_ANACONF1_HSHPEN, | ||
1631 | 1, 0), | ||
1632 | SOC_SINGLE("Headset Low Power Switch", | ||
1633 | AB8500_ANACONF1, AB8500_ANACONF1_HSLOWPOW, | ||
1634 | 1, 0), | ||
1635 | SOC_SINGLE("Headset DAC Low Power Switch", | ||
1636 | AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW1, | ||
1637 | 1, 0), | ||
1638 | SOC_SINGLE("Headset DAC Drv Low Power Switch", | ||
1639 | AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW0, | ||
1640 | 1, 0), | ||
1641 | SOC_ENUM("Headset Fade Speed", soc_enum_hsfadspeed), | ||
1642 | SOC_ENUM("Headset Source", soc_enum_da2hslr), | ||
1643 | SOC_ENUM("Headset Filter", soc_enum_hsesinc), | ||
1644 | SOC_DOUBLE_R_TLV("Headset Master Volume", | ||
1645 | AB8500_DADIGGAIN1, AB8500_DADIGGAIN2, | ||
1646 | 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1647 | SOC_DOUBLE_R_TLV("Headset Digital Volume", | ||
1648 | AB8500_HSLEARDIGGAIN, AB8500_HSRDIGGAIN, | ||
1649 | 0, AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX, 1, hs_ear_dig_gain_tlv), | ||
1650 | SOC_DOUBLE_TLV("Headset Volume", | ||
1651 | AB8500_ANAGAIN3, | ||
1652 | AB8500_ANAGAIN3_HSLGAIN, AB8500_ANAGAIN3_HSRGAIN, | ||
1653 | AB8500_ANAGAIN3_HSXGAIN_MAX, 1, hs_gain_tlv), | ||
1654 | |||
1655 | /* Earpiece */ | ||
1656 | SOC_ENUM("Earpiece DAC Mode", | ||
1657 | soc_enum_eardaclowpow), | ||
1658 | SOC_ENUM("Earpiece DAC Drv Mode", | ||
1659 | soc_enum_eardrvlowpow), | ||
1660 | |||
1661 | /* HandsFree */ | ||
1662 | SOC_ENUM("HF Mode", soc_enum_da34voice), | ||
1663 | SOC_SINGLE("HF and Headset Swap Switch", | ||
1664 | AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_SWAPDA12_34, | ||
1665 | 1, 0), | ||
1666 | SOC_DOUBLE("HF Low EMI Mode Switch", | ||
1667 | AB8500_CLASSDCONF1, | ||
1668 | AB8500_CLASSDCONF1_HFLSWAPEN, AB8500_CLASSDCONF1_HFRSWAPEN, | ||
1669 | 1, 0), | ||
1670 | SOC_DOUBLE("HF FIR Bypass Switch", | ||
1671 | AB8500_CLASSDCONF2, | ||
1672 | AB8500_CLASSDCONF2_FIRBYP0, AB8500_CLASSDCONF2_FIRBYP1, | ||
1673 | 1, 0), | ||
1674 | SOC_DOUBLE("HF High Volume Switch", | ||
1675 | AB8500_CLASSDCONF2, | ||
1676 | AB8500_CLASSDCONF2_HIGHVOLEN0, AB8500_CLASSDCONF2_HIGHVOLEN1, | ||
1677 | 1, 0), | ||
1678 | SOC_SINGLE("HF L and R Bridge Switch", | ||
1679 | AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLHF, | ||
1680 | 1, 0), | ||
1681 | SOC_DOUBLE_R_TLV("HF Master Volume", | ||
1682 | AB8500_DADIGGAIN3, AB8500_DADIGGAIN4, | ||
1683 | 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1684 | |||
1685 | /* Vibra */ | ||
1686 | SOC_DOUBLE("Vibra High Volume Switch", | ||
1687 | AB8500_CLASSDCONF2, | ||
1688 | AB8500_CLASSDCONF2_HIGHVOLEN2, AB8500_CLASSDCONF2_HIGHVOLEN3, | ||
1689 | 1, 0), | ||
1690 | SOC_DOUBLE("Vibra Low EMI Mode Switch", | ||
1691 | AB8500_CLASSDCONF1, | ||
1692 | AB8500_CLASSDCONF1_VIB1SWAPEN, AB8500_CLASSDCONF1_VIB2SWAPEN, | ||
1693 | 1, 0), | ||
1694 | SOC_DOUBLE("Vibra FIR Bypass Switch", | ||
1695 | AB8500_CLASSDCONF2, | ||
1696 | AB8500_CLASSDCONF2_FIRBYP2, AB8500_CLASSDCONF2_FIRBYP3, | ||
1697 | 1, 0), | ||
1698 | SOC_ENUM("Vibra Mode", soc_enum_da56voice), | ||
1699 | SOC_DOUBLE_R("Vibra PWM Duty Cycle N", | ||
1700 | AB8500_PWMGENCONF3, AB8500_PWMGENCONF5, | ||
1701 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC, | ||
1702 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0), | ||
1703 | SOC_DOUBLE_R("Vibra PWM Duty Cycle P", | ||
1704 | AB8500_PWMGENCONF2, AB8500_PWMGENCONF4, | ||
1705 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC, | ||
1706 | AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0), | ||
1707 | SOC_SINGLE("Vibra 1 and 2 Bridge Switch", | ||
1708 | AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLVIB, | ||
1709 | 1, 0), | ||
1710 | SOC_DOUBLE_R_TLV("Vibra Master Volume", | ||
1711 | AB8500_DADIGGAIN5, AB8500_DADIGGAIN6, | ||
1712 | 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1713 | |||
1714 | /* HandsFree, Vibra */ | ||
1715 | SOC_SINGLE("ClassD High Pass Volume", | ||
1716 | AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHHPGAIN, | ||
1717 | AB8500_CLASSDCONF3_DITHHPGAIN_MAX, 0), | ||
1718 | SOC_SINGLE("ClassD White Volume", | ||
1719 | AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHWGAIN, | ||
1720 | AB8500_CLASSDCONF3_DITHWGAIN_MAX, 0), | ||
1721 | |||
1722 | /* Mic 1, Mic 2, LineIn */ | ||
1723 | SOC_DOUBLE_R_TLV("Mic Master Volume", | ||
1724 | AB8500_ADDIGGAIN3, AB8500_ADDIGGAIN4, | ||
1725 | 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), | ||
1726 | |||
1727 | /* Mic 1 */ | ||
1728 | SOC_SINGLE_TLV("Mic 1", | ||
1729 | AB8500_ANAGAIN1, | ||
1730 | AB8500_ANAGAINX_MICXGAIN, | ||
1731 | AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv), | ||
1732 | SOC_SINGLE("Mic 1 Low Power Switch", | ||
1733 | AB8500_ANAGAIN1, AB8500_ANAGAINX_LOWPOWMICX, | ||
1734 | 1, 0), | ||
1735 | |||
1736 | /* Mic 2 */ | ||
1737 | SOC_DOUBLE("Mic High Pass Switch", | ||
1738 | AB8500_ADFILTCONF, | ||
1739 | AB8500_ADFILTCONF_AD3NH, AB8500_ADFILTCONF_AD4NH, | ||
1740 | 1, 1), | ||
1741 | SOC_ENUM("Mic Mode", soc_enum_ad34voice), | ||
1742 | SOC_ENUM("Mic Filter", soc_enum_dmic34sinc), | ||
1743 | SOC_SINGLE_TLV("Mic 2", | ||
1744 | AB8500_ANAGAIN2, | ||
1745 | AB8500_ANAGAINX_MICXGAIN, | ||
1746 | AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv), | ||
1747 | SOC_SINGLE("Mic 2 Low Power Switch", | ||
1748 | AB8500_ANAGAIN2, AB8500_ANAGAINX_LOWPOWMICX, | ||
1749 | 1, 0), | ||
1750 | |||
1751 | /* LineIn */ | ||
1752 | SOC_DOUBLE("LineIn High Pass Switch", | ||
1753 | AB8500_ADFILTCONF, | ||
1754 | AB8500_ADFILTCONF_AD1NH, AB8500_ADFILTCONF_AD2NH, | ||
1755 | 1, 1), | ||
1756 | SOC_ENUM("LineIn Filter", soc_enum_dmic12sinc), | ||
1757 | SOC_ENUM("LineIn Mode", soc_enum_ad12voice), | ||
1758 | SOC_DOUBLE_R_TLV("LineIn Master Volume", | ||
1759 | AB8500_ADDIGGAIN1, AB8500_ADDIGGAIN2, | ||
1760 | 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), | ||
1761 | SOC_DOUBLE_TLV("LineIn", | ||
1762 | AB8500_ANAGAIN4, | ||
1763 | AB8500_ANAGAIN4_LINLGAIN, AB8500_ANAGAIN4_LINRGAIN, | ||
1764 | AB8500_ANAGAIN4_LINXGAIN_MAX, 0, lin_gain_tlv), | ||
1765 | SOC_DOUBLE_R_TLV("LineIn to Headset Volume", | ||
1766 | AB8500_DIGLINHSLGAIN, AB8500_DIGLINHSRGAIN, | ||
1767 | AB8500_DIGLINHSXGAIN_LINTOHSXGAIN, | ||
1768 | AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX, | ||
1769 | 1, lin2hs_gain_tlv), | ||
1770 | |||
1771 | /* DMic */ | ||
1772 | SOC_ENUM("DMic Filter", soc_enum_dmic56sinc), | ||
1773 | SOC_DOUBLE_R_TLV("DMic Master Volume", | ||
1774 | AB8500_ADDIGGAIN5, AB8500_ADDIGGAIN6, | ||
1775 | 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv), | ||
1776 | |||
1777 | /* Digital gains */ | ||
1778 | SOC_ENUM("Digital Gain Fade Speed", soc_enum_fadespeed), | ||
1779 | |||
1780 | /* Analog loopback */ | ||
1781 | SOC_DOUBLE_R_TLV("Analog Loopback Volume", | ||
1782 | AB8500_ADDIGLOOPGAIN1, AB8500_ADDIGLOOPGAIN2, | ||
1783 | 0, AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX, 1, dax_dig_gain_tlv), | ||
1784 | |||
1785 | /* Digital interface - DA from slot mapping */ | ||
1786 | SOC_ENUM("Digital Interface DA 1 From Slot Map", soc_enum_da1slotmap), | ||
1787 | SOC_ENUM("Digital Interface DA 2 From Slot Map", soc_enum_da2slotmap), | ||
1788 | SOC_ENUM("Digital Interface DA 3 From Slot Map", soc_enum_da3slotmap), | ||
1789 | SOC_ENUM("Digital Interface DA 4 From Slot Map", soc_enum_da4slotmap), | ||
1790 | SOC_ENUM("Digital Interface DA 5 From Slot Map", soc_enum_da5slotmap), | ||
1791 | SOC_ENUM("Digital Interface DA 6 From Slot Map", soc_enum_da6slotmap), | ||
1792 | SOC_ENUM("Digital Interface DA 7 From Slot Map", soc_enum_da7slotmap), | ||
1793 | SOC_ENUM("Digital Interface DA 8 From Slot Map", soc_enum_da8slotmap), | ||
1794 | |||
1795 | /* Digital interface - AD to slot mapping */ | ||
1796 | SOC_ENUM("Digital Interface AD To Slot 0 Map", soc_enum_adslot0map), | ||
1797 | SOC_ENUM("Digital Interface AD To Slot 1 Map", soc_enum_adslot1map), | ||
1798 | SOC_ENUM("Digital Interface AD To Slot 2 Map", soc_enum_adslot2map), | ||
1799 | SOC_ENUM("Digital Interface AD To Slot 3 Map", soc_enum_adslot3map), | ||
1800 | SOC_ENUM("Digital Interface AD To Slot 4 Map", soc_enum_adslot4map), | ||
1801 | SOC_ENUM("Digital Interface AD To Slot 5 Map", soc_enum_adslot5map), | ||
1802 | SOC_ENUM("Digital Interface AD To Slot 6 Map", soc_enum_adslot6map), | ||
1803 | SOC_ENUM("Digital Interface AD To Slot 7 Map", soc_enum_adslot7map), | ||
1804 | SOC_ENUM("Digital Interface AD To Slot 8 Map", soc_enum_adslot8map), | ||
1805 | SOC_ENUM("Digital Interface AD To Slot 9 Map", soc_enum_adslot9map), | ||
1806 | SOC_ENUM("Digital Interface AD To Slot 10 Map", soc_enum_adslot10map), | ||
1807 | SOC_ENUM("Digital Interface AD To Slot 11 Map", soc_enum_adslot11map), | ||
1808 | SOC_ENUM("Digital Interface AD To Slot 12 Map", soc_enum_adslot12map), | ||
1809 | SOC_ENUM("Digital Interface AD To Slot 13 Map", soc_enum_adslot13map), | ||
1810 | SOC_ENUM("Digital Interface AD To Slot 14 Map", soc_enum_adslot14map), | ||
1811 | SOC_ENUM("Digital Interface AD To Slot 15 Map", soc_enum_adslot15map), | ||
1812 | SOC_ENUM("Digital Interface AD To Slot 16 Map", soc_enum_adslot16map), | ||
1813 | SOC_ENUM("Digital Interface AD To Slot 17 Map", soc_enum_adslot17map), | ||
1814 | SOC_ENUM("Digital Interface AD To Slot 18 Map", soc_enum_adslot18map), | ||
1815 | SOC_ENUM("Digital Interface AD To Slot 19 Map", soc_enum_adslot19map), | ||
1816 | SOC_ENUM("Digital Interface AD To Slot 20 Map", soc_enum_adslot20map), | ||
1817 | SOC_ENUM("Digital Interface AD To Slot 21 Map", soc_enum_adslot21map), | ||
1818 | SOC_ENUM("Digital Interface AD To Slot 22 Map", soc_enum_adslot22map), | ||
1819 | SOC_ENUM("Digital Interface AD To Slot 23 Map", soc_enum_adslot23map), | ||
1820 | SOC_ENUM("Digital Interface AD To Slot 24 Map", soc_enum_adslot24map), | ||
1821 | SOC_ENUM("Digital Interface AD To Slot 25 Map", soc_enum_adslot25map), | ||
1822 | SOC_ENUM("Digital Interface AD To Slot 26 Map", soc_enum_adslot26map), | ||
1823 | SOC_ENUM("Digital Interface AD To Slot 27 Map", soc_enum_adslot27map), | ||
1824 | SOC_ENUM("Digital Interface AD To Slot 28 Map", soc_enum_adslot28map), | ||
1825 | SOC_ENUM("Digital Interface AD To Slot 29 Map", soc_enum_adslot29map), | ||
1826 | SOC_ENUM("Digital Interface AD To Slot 30 Map", soc_enum_adslot30map), | ||
1827 | SOC_ENUM("Digital Interface AD To Slot 31 Map", soc_enum_adslot31map), | ||
1828 | |||
1829 | /* Digital interface - Loopback */ | ||
1830 | SOC_SINGLE("Digital Interface AD 1 Loopback Switch", | ||
1831 | AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DAI7TOADO1, | ||
1832 | 1, 0), | ||
1833 | SOC_SINGLE("Digital Interface AD 2 Loopback Switch", | ||
1834 | AB8500_DASLOTCONF2, AB8500_DASLOTCONF2_DAI8TOADO2, | ||
1835 | 1, 0), | ||
1836 | SOC_SINGLE("Digital Interface AD 3 Loopback Switch", | ||
1837 | AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DAI7TOADO3, | ||
1838 | 1, 0), | ||
1839 | SOC_SINGLE("Digital Interface AD 4 Loopback Switch", | ||
1840 | AB8500_DASLOTCONF4, AB8500_DASLOTCONF4_DAI8TOADO4, | ||
1841 | 1, 0), | ||
1842 | SOC_SINGLE("Digital Interface AD 5 Loopback Switch", | ||
1843 | AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DAI7TOADO5, | ||
1844 | 1, 0), | ||
1845 | SOC_SINGLE("Digital Interface AD 6 Loopback Switch", | ||
1846 | AB8500_DASLOTCONF6, AB8500_DASLOTCONF6_DAI8TOADO6, | ||
1847 | 1, 0), | ||
1848 | SOC_SINGLE("Digital Interface AD 7 Loopback Switch", | ||
1849 | AB8500_DASLOTCONF7, AB8500_DASLOTCONF7_DAI8TOADO7, | ||
1850 | 1, 0), | ||
1851 | SOC_SINGLE("Digital Interface AD 8 Loopback Switch", | ||
1852 | AB8500_DASLOTCONF8, AB8500_DASLOTCONF8_DAI7TOADO8, | ||
1853 | 1, 0), | ||
1854 | |||
1855 | /* Digital interface - Burst FIFO */ | ||
1856 | SOC_SINGLE("Digital Interface 0 FIFO Enable Switch", | ||
1857 | AB8500_DIGIFCONF3, AB8500_DIGIFCONF3_IF0BFIFOEN, | ||
1858 | 1, 0), | ||
1859 | SOC_ENUM("Burst FIFO Mask", soc_enum_bfifomask), | ||
1860 | SOC_ENUM("Burst FIFO Bit-clock Frequency", soc_enum_bfifo19m2), | ||
1861 | SOC_SINGLE("Burst FIFO Threshold", | ||
1862 | AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOINT_SHIFT, | ||
1863 | AB8500_FIFOCONF1_BFIFOINT_MAX, 0), | ||
1864 | SOC_SINGLE("Burst FIFO Length", | ||
1865 | AB8500_FIFOCONF2, AB8500_FIFOCONF2_BFIFOTX_SHIFT, | ||
1866 | AB8500_FIFOCONF2_BFIFOTX_MAX, 0), | ||
1867 | SOC_SINGLE("Burst FIFO EOS Extra Slots", | ||
1868 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOEXSL_SHIFT, | ||
1869 | AB8500_FIFOCONF3_BFIFOEXSL_MAX, 0), | ||
1870 | SOC_SINGLE("Burst FIFO FS Extra Bit-clocks", | ||
1871 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_PREBITCLK0_SHIFT, | ||
1872 | AB8500_FIFOCONF3_PREBITCLK0_MAX, 0), | ||
1873 | SOC_ENUM("Burst FIFO Interface Mode", soc_enum_bfifomast), | ||
1874 | |||
1875 | SOC_SINGLE("Burst FIFO Interface Switch", | ||
1876 | AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFORUN_SHIFT, | ||
1877 | 1, 0), | ||
1878 | SOC_SINGLE("Burst FIFO Switch Frame Number", | ||
1879 | AB8500_FIFOCONF4, AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT, | ||
1880 | AB8500_FIFOCONF4_BFIFOFRAMSW_MAX, 0), | ||
1881 | SOC_SINGLE("Burst FIFO Wake Up Delay", | ||
1882 | AB8500_FIFOCONF5, AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT, | ||
1883 | AB8500_FIFOCONF5_BFIFOWAKEUP_MAX, 0), | ||
1884 | SOC_SINGLE("Burst FIFO Samples In FIFO", | ||
1885 | AB8500_FIFOCONF6, AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT, | ||
1886 | AB8500_FIFOCONF6_BFIFOSAMPLE_MAX, 0), | ||
1887 | |||
1888 | /* ANC */ | ||
1889 | SOC_ENUM_EXT("ANC Status", soc_enum_ancstate, | ||
1890 | anc_status_control_get, anc_status_control_put), | ||
1891 | SOC_SINGLE_XR_SX("ANC Warp Delay Shift", | ||
1892 | AB8500_ANCCONF2, 1, AB8500_ANCCONF2_SHIFT, | ||
1893 | AB8500_ANCCONF2_MIN, AB8500_ANCCONF2_MAX, 0), | ||
1894 | SOC_SINGLE_XR_SX("ANC FIR Output Shift", | ||
1895 | AB8500_ANCCONF3, 1, AB8500_ANCCONF3_SHIFT, | ||
1896 | AB8500_ANCCONF3_MIN, AB8500_ANCCONF3_MAX, 0), | ||
1897 | SOC_SINGLE_XR_SX("ANC IIR Output Shift", | ||
1898 | AB8500_ANCCONF4, 1, AB8500_ANCCONF4_SHIFT, | ||
1899 | AB8500_ANCCONF4_MIN, AB8500_ANCCONF4_MAX, 0), | ||
1900 | SOC_SINGLE_XR_SX("ANC Warp Delay", | ||
1901 | AB8500_ANCCONF9, 2, AB8500_ANC_WARP_DELAY_SHIFT, | ||
1902 | AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0), | ||
1903 | |||
1904 | /* Sidetone */ | ||
1905 | SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate, | ||
1906 | sid_status_control_get, sid_status_control_put), | ||
1907 | SOC_SINGLE_STROBE("Sidetone Reset", | ||
1908 | AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0), | ||
1909 | }; | ||
1910 | |||
1911 | static struct snd_kcontrol_new ab8500_filter_controls[] = { | ||
1912 | AB8500_FILTER_CONTROL("ANC FIR Coefficients", AB8500_ANC_FIR_COEFFS, | ||
1913 | AB8500_ANC_FIR_COEFF_MIN, AB8500_ANC_FIR_COEFF_MAX), | ||
1914 | AB8500_FILTER_CONTROL("ANC IIR Coefficients", AB8500_ANC_IIR_COEFFS, | ||
1915 | AB8500_ANC_IIR_COEFF_MIN, AB8500_ANC_IIR_COEFF_MAX), | ||
1916 | AB8500_FILTER_CONTROL("Sidetone FIR Coefficients", | ||
1917 | AB8500_SID_FIR_COEFFS, AB8500_SID_FIR_COEFF_MIN, | ||
1918 | AB8500_SID_FIR_COEFF_MAX) | ||
1919 | }; | ||
1920 | enum ab8500_filter { | ||
1921 | AB8500_FILTER_ANC_FIR = 0, | ||
1922 | AB8500_FILTER_ANC_IIR = 1, | ||
1923 | AB8500_FILTER_SID_FIR = 2, | ||
1924 | }; | ||
1925 | |||
1926 | /* | ||
1927 | * Extended interface for codec-driver | ||
1928 | */ | ||
1929 | |||
1930 | static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec) | ||
1931 | { | ||
1932 | int status; | ||
1933 | |||
1934 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | ||
1935 | |||
1936 | /* Reset audio-registers and disable 32kHz-clock output 2 */ | ||
1937 | status = ab8500_sysctrl_write(AB8500_STW4500CTRL3, | ||
1938 | AB8500_STW4500CTRL3_CLK32KOUT2DIS | | ||
1939 | AB8500_STW4500CTRL3_RESETAUDN, | ||
1940 | AB8500_STW4500CTRL3_RESETAUDN); | ||
1941 | if (status < 0) | ||
1942 | return status; | ||
1943 | |||
1944 | return 0; | ||
1945 | } | ||
1946 | |||
1947 | static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, | ||
1948 | struct amic_settings *amics) | ||
1949 | { | ||
1950 | u8 value8; | ||
1951 | unsigned int value; | ||
1952 | int status; | ||
1953 | const struct snd_soc_dapm_route *route; | ||
1954 | |||
1955 | dev_dbg(codec->dev, "%s: Enter.\n", __func__); | ||
1956 | |||
1957 | /* Set DMic-clocks to outputs */ | ||
1958 | status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC, | ||
1959 | (u8)AB8500_GPIO_DIR4_REG, | ||
1960 | &value8); | ||
1961 | if (status < 0) | ||
1962 | return status; | ||
1963 | value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | | ||
1964 | GPIO31_DIR_OUTPUT; | ||
1965 | status = abx500_set_register_interruptible(codec->dev, | ||
1966 | (u8)AB8500_MISC, | ||
1967 | (u8)AB8500_GPIO_DIR4_REG, | ||
1968 | value); | ||
1969 | if (status < 0) | ||
1970 | return status; | ||
1971 | |||
1972 | /* Attach regulators to AMic DAPM-paths */ | ||
1973 | dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__, | ||
1974 | amic_micbias_str(amics->mic1a_micbias)); | ||
1975 | route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias]; | ||
1976 | status = snd_soc_dapm_add_routes(&codec->dapm, route, 1); | ||
1977 | dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__, | ||
1978 | amic_micbias_str(amics->mic1b_micbias)); | ||
1979 | route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias]; | ||
1980 | status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); | ||
1981 | dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__, | ||
1982 | amic_micbias_str(amics->mic2_micbias)); | ||
1983 | route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias]; | ||
1984 | status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); | ||
1985 | if (status < 0) { | ||
1986 | dev_err(codec->dev, | ||
1987 | "%s: Failed to add AMic-regulator DAPM-routes (%d).\n", | ||
1988 | __func__, status); | ||
1989 | return status; | ||
1990 | } | ||
1991 | |||
1992 | /* Set AMic-configuration */ | ||
1993 | dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__, | ||
1994 | amic_type_str(amics->mic1_type)); | ||
1995 | snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX, | ||
1996 | amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ? | ||
1997 | 0 : AB8500_ANAGAINX_ENSEMICX); | ||
1998 | dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__, | ||
1999 | amic_type_str(amics->mic2_type)); | ||
2000 | snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX, | ||
2001 | amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ? | ||
2002 | 0 : AB8500_ANAGAINX_ENSEMICX); | ||
2003 | |||
2004 | return 0; | ||
2005 | } | ||
2006 | EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics); | ||
2007 | |||
2008 | static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec, | ||
2009 | enum ear_cm_voltage ear_cmv) | ||
2010 | { | ||
2011 | char *cmv_str; | ||
2012 | |||
2013 | switch (ear_cmv) { | ||
2014 | case EAR_CMV_0_95V: | ||
2015 | cmv_str = "0.95V"; | ||
2016 | break; | ||
2017 | case EAR_CMV_1_10V: | ||
2018 | cmv_str = "1.10V"; | ||
2019 | break; | ||
2020 | case EAR_CMV_1_27V: | ||
2021 | cmv_str = "1.27V"; | ||
2022 | break; | ||
2023 | case EAR_CMV_1_58V: | ||
2024 | cmv_str = "1.58V"; | ||
2025 | break; | ||
2026 | default: | ||
2027 | dev_err(codec->dev, | ||
2028 | "%s: Unknown earpiece CM-voltage (%d)!\n", | ||
2029 | __func__, (int)ear_cmv); | ||
2030 | return -EINVAL; | ||
2031 | } | ||
2032 | dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__, | ||
2033 | cmv_str); | ||
2034 | snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM, | ||
2035 | ear_cmv); | ||
2036 | |||
2037 | return 0; | ||
2038 | } | ||
2039 | EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv); | ||
2040 | |||
2041 | static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, | ||
2042 | unsigned int delay) | ||
2043 | { | ||
2044 | unsigned int mask, val; | ||
2045 | struct snd_soc_codec *codec = dai->codec; | ||
2046 | |||
2047 | mask = BIT(AB8500_DIGIFCONF2_IF0DEL); | ||
2048 | val = 0; | ||
2049 | |||
2050 | switch (delay) { | ||
2051 | case 0: | ||
2052 | break; | ||
2053 | case 1: | ||
2054 | val |= BIT(AB8500_DIGIFCONF2_IF0DEL); | ||
2055 | break; | ||
2056 | default: | ||
2057 | dev_err(dai->codec->dev, | ||
2058 | "%s: ERROR: Unsupported bit-delay (0x%x)!\n", | ||
2059 | __func__, delay); | ||
2060 | return -EINVAL; | ||
2061 | } | ||
2062 | |||
2063 | dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n", | ||
2064 | __func__, delay); | ||
2065 | snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); | ||
2066 | |||
2067 | return 0; | ||
2068 | } | ||
2069 | |||
2070 | /* Gates clocking according format mask */ | ||
2071 | static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec, | ||
2072 | unsigned int fmt) | ||
2073 | { | ||
2074 | unsigned int mask; | ||
2075 | unsigned int val; | ||
2076 | |||
2077 | mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) | | ||
2078 | BIT(AB8500_DIGIFCONF1_ENFSBITCLK0); | ||
2079 | |||
2080 | val = BIT(AB8500_DIGIFCONF1_ENMASTGEN); | ||
2081 | |||
2082 | switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { | ||
2083 | case SND_SOC_DAIFMT_CONT: /* continuous clock */ | ||
2084 | dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n", | ||
2085 | __func__); | ||
2086 | val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0); | ||
2087 | break; | ||
2088 | case SND_SOC_DAIFMT_GATED: /* clock is gated */ | ||
2089 | dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n", | ||
2090 | __func__); | ||
2091 | break; | ||
2092 | default: | ||
2093 | dev_err(codec->dev, | ||
2094 | "%s: ERROR: Unsupported clock mask (0x%x)!\n", | ||
2095 | __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK); | ||
2096 | return -EINVAL; | ||
2097 | } | ||
2098 | |||
2099 | snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); | ||
2100 | |||
2101 | return 0; | ||
2102 | } | ||
2103 | |||
2104 | static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
2105 | { | ||
2106 | unsigned int mask; | ||
2107 | unsigned int val; | ||
2108 | struct snd_soc_codec *codec = dai->codec; | ||
2109 | int status; | ||
2110 | |||
2111 | dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt); | ||
2112 | |||
2113 | mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) | | ||
2114 | BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) | | ||
2115 | BIT(AB8500_DIGIFCONF3_IF0BFIFOEN) | | ||
2116 | BIT(AB8500_DIGIFCONF3_IF0MASTER); | ||
2117 | val = 0; | ||
2118 | |||
2119 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
2120 | case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */ | ||
2121 | dev_dbg(dai->codec->dev, | ||
2122 | "%s: IF0 Master-mode: AB8500 master.\n", __func__); | ||
2123 | val |= BIT(AB8500_DIGIFCONF3_IF0MASTER); | ||
2124 | break; | ||
2125 | case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */ | ||
2126 | dev_dbg(dai->codec->dev, | ||
2127 | "%s: IF0 Master-mode: AB8500 slave.\n", __func__); | ||
2128 | break; | ||
2129 | case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */ | ||
2130 | case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ | ||
2131 | dev_err(dai->codec->dev, | ||
2132 | "%s: ERROR: The device is either a master or a slave.\n", | ||
2133 | __func__); | ||
2134 | default: | ||
2135 | dev_err(dai->codec->dev, | ||
2136 | "%s: ERROR: Unsupporter master mask 0x%x\n", | ||
2137 | __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
2138 | return -EINVAL; | ||
2139 | break; | ||
2140 | } | ||
2141 | |||
2142 | snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val); | ||
2143 | |||
2144 | /* Set clock gating */ | ||
2145 | status = ab8500_codec_set_dai_clock_gate(codec, fmt); | ||
2146 | if (status) { | ||
2147 | dev_err(dai->codec->dev, | ||
2148 | "%s: ERRROR: Failed to set clock gate (%d).\n", | ||
2149 | __func__, status); | ||
2150 | return status; | ||
2151 | } | ||
2152 | |||
2153 | /* Setting data transfer format */ | ||
2154 | |||
2155 | mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) | | ||
2156 | BIT(AB8500_DIGIFCONF2_IF0FORMAT1) | | ||
2157 | BIT(AB8500_DIGIFCONF2_FSYNC0P) | | ||
2158 | BIT(AB8500_DIGIFCONF2_BITCLK0P); | ||
2159 | val = 0; | ||
2160 | |||
2161 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
2162 | case SND_SOC_DAIFMT_I2S: /* I2S mode */ | ||
2163 | dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__); | ||
2164 | val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1); | ||
2165 | ab8500_audio_set_bit_delay(dai, 0); | ||
2166 | break; | ||
2167 | |||
2168 | case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */ | ||
2169 | dev_dbg(dai->codec->dev, | ||
2170 | "%s: IF0 Protocol: DSP A (TDM)\n", __func__); | ||
2171 | val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0); | ||
2172 | ab8500_audio_set_bit_delay(dai, 1); | ||
2173 | break; | ||
2174 | |||
2175 | case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */ | ||
2176 | dev_dbg(dai->codec->dev, | ||
2177 | "%s: IF0 Protocol: DSP B (TDM)\n", __func__); | ||
2178 | val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0); | ||
2179 | ab8500_audio_set_bit_delay(dai, 0); | ||
2180 | break; | ||
2181 | |||
2182 | default: | ||
2183 | dev_err(dai->codec->dev, | ||
2184 | "%s: ERROR: Unsupported format (0x%x)!\n", | ||
2185 | __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
2186 | return -EINVAL; | ||
2187 | } | ||
2188 | |||
2189 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
2190 | case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ | ||
2191 | dev_dbg(dai->codec->dev, | ||
2192 | "%s: IF0: Normal bit clock, normal frame\n", | ||
2193 | __func__); | ||
2194 | break; | ||
2195 | case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */ | ||
2196 | dev_dbg(dai->codec->dev, | ||
2197 | "%s: IF0: Normal bit clock, inverted frame\n", | ||
2198 | __func__); | ||
2199 | val |= BIT(AB8500_DIGIFCONF2_FSYNC0P); | ||
2200 | break; | ||
2201 | case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */ | ||
2202 | dev_dbg(dai->codec->dev, | ||
2203 | "%s: IF0: Inverted bit clock, normal frame\n", | ||
2204 | __func__); | ||
2205 | val |= BIT(AB8500_DIGIFCONF2_BITCLK0P); | ||
2206 | break; | ||
2207 | case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */ | ||
2208 | dev_dbg(dai->codec->dev, | ||
2209 | "%s: IF0: Inverted bit clock, inverted frame\n", | ||
2210 | __func__); | ||
2211 | val |= BIT(AB8500_DIGIFCONF2_FSYNC0P); | ||
2212 | val |= BIT(AB8500_DIGIFCONF2_BITCLK0P); | ||
2213 | break; | ||
2214 | default: | ||
2215 | dev_err(dai->codec->dev, | ||
2216 | "%s: ERROR: Unsupported INV mask 0x%x\n", | ||
2217 | __func__, fmt & SND_SOC_DAIFMT_INV_MASK); | ||
2218 | return -EINVAL; | ||
2219 | } | ||
2220 | |||
2221 | snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); | ||
2222 | |||
2223 | return 0; | ||
2224 | } | ||
2225 | |||
2226 | static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | ||
2227 | unsigned int tx_mask, unsigned int rx_mask, | ||
2228 | int slots, int slot_width) | ||
2229 | { | ||
2230 | struct snd_soc_codec *codec = dai->codec; | ||
2231 | unsigned int val, mask, slots_active; | ||
2232 | |||
2233 | mask = BIT(AB8500_DIGIFCONF2_IF0WL0) | | ||
2234 | BIT(AB8500_DIGIFCONF2_IF0WL1); | ||
2235 | val = 0; | ||
2236 | |||
2237 | switch (slot_width) { | ||
2238 | case 16: | ||
2239 | break; | ||
2240 | case 20: | ||
2241 | val |= BIT(AB8500_DIGIFCONF2_IF0WL0); | ||
2242 | break; | ||
2243 | case 24: | ||
2244 | val |= BIT(AB8500_DIGIFCONF2_IF0WL1); | ||
2245 | break; | ||
2246 | case 32: | ||
2247 | val |= BIT(AB8500_DIGIFCONF2_IF0WL1) | | ||
2248 | BIT(AB8500_DIGIFCONF2_IF0WL0); | ||
2249 | break; | ||
2250 | default: | ||
2251 | dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n", | ||
2252 | __func__, slot_width); | ||
2253 | return -EINVAL; | ||
2254 | } | ||
2255 | |||
2256 | dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n", | ||
2257 | __func__, slot_width); | ||
2258 | snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val); | ||
2259 | |||
2260 | /* Setup TDM clocking according to slot count */ | ||
2261 | dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots); | ||
2262 | mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) | | ||
2263 | BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); | ||
2264 | switch (slots) { | ||
2265 | case 2: | ||
2266 | val = AB8500_MASK_NONE; | ||
2267 | break; | ||
2268 | case 4: | ||
2269 | val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0); | ||
2270 | break; | ||
2271 | case 8: | ||
2272 | val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); | ||
2273 | break; | ||
2274 | case 16: | ||
2275 | val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) | | ||
2276 | BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1); | ||
2277 | break; | ||
2278 | default: | ||
2279 | dev_err(dai->codec->dev, | ||
2280 | "%s: ERROR: Unsupported number of slots (%d)!\n", | ||
2281 | __func__, slots); | ||
2282 | return -EINVAL; | ||
2283 | } | ||
2284 | snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); | ||
2285 | |||
2286 | /* Setup TDM DA according to active tx slots */ | ||
2287 | mask = AB8500_DASLOTCONFX_SLTODAX_MASK; | ||
2288 | slots_active = hweight32(tx_mask); | ||
2289 | dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__, | ||
2290 | slots_active); | ||
2291 | switch (slots_active) { | ||
2292 | case 0: | ||
2293 | break; | ||
2294 | case 1: | ||
2295 | /* Slot 9 -> DA_IN1 & DA_IN3 */ | ||
2296 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11); | ||
2297 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11); | ||
2298 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); | ||
2299 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); | ||
2300 | break; | ||
2301 | case 2: | ||
2302 | /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */ | ||
2303 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9); | ||
2304 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9); | ||
2305 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); | ||
2306 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); | ||
2307 | |||
2308 | break; | ||
2309 | case 8: | ||
2310 | dev_dbg(dai->codec->dev, | ||
2311 | "%s: In 8-channel mode DA-from-slot mapping is set manually.", | ||
2312 | __func__); | ||
2313 | break; | ||
2314 | default: | ||
2315 | dev_err(dai->codec->dev, | ||
2316 | "%s: Unsupported number of active TX-slots (%d)!\n", | ||
2317 | __func__, slots_active); | ||
2318 | return -EINVAL; | ||
2319 | } | ||
2320 | |||
2321 | /* Setup TDM AD according to active RX-slots */ | ||
2322 | slots_active = hweight32(rx_mask); | ||
2323 | dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__, | ||
2324 | slots_active); | ||
2325 | switch (slots_active) { | ||
2326 | case 0: | ||
2327 | break; | ||
2328 | case 1: | ||
2329 | /* AD_OUT3 -> slot 0 & 1 */ | ||
2330 | snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL, | ||
2331 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | | ||
2332 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD); | ||
2333 | break; | ||
2334 | case 2: | ||
2335 | /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ | ||
2336 | snd_soc_update_bits(codec, | ||
2337 | AB8500_ADSLOTSEL1, | ||
2338 | AB8500_MASK_ALL, | ||
2339 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | | ||
2340 | AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD); | ||
2341 | break; | ||
2342 | case 8: | ||
2343 | dev_dbg(dai->codec->dev, | ||
2344 | "%s: In 8-channel mode AD-to-slot mapping is set manually.", | ||
2345 | __func__); | ||
2346 | break; | ||
2347 | default: | ||
2348 | dev_err(dai->codec->dev, | ||
2349 | "%s: Unsupported number of active RX-slots (%d)!\n", | ||
2350 | __func__, slots_active); | ||
2351 | return -EINVAL; | ||
2352 | } | ||
2353 | |||
2354 | return 0; | ||
2355 | } | ||
2356 | |||
2357 | struct snd_soc_dai_driver ab8500_codec_dai[] = { | ||
2358 | { | ||
2359 | .name = "ab8500-codec-dai.0", | ||
2360 | .id = 0, | ||
2361 | .playback = { | ||
2362 | .stream_name = "ab8500_0p", | ||
2363 | .channels_min = 1, | ||
2364 | .channels_max = 8, | ||
2365 | .rates = AB8500_SUPPORTED_RATE, | ||
2366 | .formats = AB8500_SUPPORTED_FMT, | ||
2367 | }, | ||
2368 | .ops = (struct snd_soc_dai_ops[]) { | ||
2369 | { | ||
2370 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2371 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2372 | } | ||
2373 | }, | ||
2374 | .symmetric_rates = 1 | ||
2375 | }, | ||
2376 | { | ||
2377 | .name = "ab8500-codec-dai.1", | ||
2378 | .id = 1, | ||
2379 | .capture = { | ||
2380 | .stream_name = "ab8500_0c", | ||
2381 | .channels_min = 1, | ||
2382 | .channels_max = 8, | ||
2383 | .rates = AB8500_SUPPORTED_RATE, | ||
2384 | .formats = AB8500_SUPPORTED_FMT, | ||
2385 | }, | ||
2386 | .ops = (struct snd_soc_dai_ops[]) { | ||
2387 | { | ||
2388 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2389 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2390 | } | ||
2391 | }, | ||
2392 | .symmetric_rates = 1 | ||
2393 | } | ||
2394 | }; | ||
2395 | |||
2396 | static int ab8500_codec_probe(struct snd_soc_codec *codec) | ||
2397 | { | ||
2398 | struct device *dev = codec->dev; | ||
2399 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); | ||
2400 | struct ab8500_platform_data *pdata; | ||
2401 | struct filter_control *fc; | ||
2402 | int status; | ||
2403 | |||
2404 | dev_dbg(dev, "%s: Enter.\n", __func__); | ||
2405 | |||
2406 | /* Setup AB8500 according to board-settings */ | ||
2407 | pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); | ||
2408 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); | ||
2409 | if (status < 0) { | ||
2410 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); | ||
2411 | return status; | ||
2412 | } | ||
2413 | status = ab8500_audio_set_ear_cmv(codec, pdata->codec->ear_cmv); | ||
2414 | if (status < 0) { | ||
2415 | pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n", | ||
2416 | __func__, status); | ||
2417 | return status; | ||
2418 | } | ||
2419 | |||
2420 | status = ab8500_audio_init_audioblock(codec); | ||
2421 | if (status < 0) { | ||
2422 | dev_err(dev, "%s: failed to init audio-block (%d)!\n", | ||
2423 | __func__, status); | ||
2424 | return status; | ||
2425 | } | ||
2426 | |||
2427 | /* Override HW-defaults */ | ||
2428 | ab8500_codec_write_reg(codec, | ||
2429 | AB8500_ANACONF5, | ||
2430 | BIT(AB8500_ANACONF5_HSAUTOEN)); | ||
2431 | ab8500_codec_write_reg(codec, | ||
2432 | AB8500_SHORTCIRCONF, | ||
2433 | BIT(AB8500_SHORTCIRCONF_HSZCDDIS)); | ||
2434 | |||
2435 | /* Add filter controls */ | ||
2436 | status = snd_soc_add_codec_controls(codec, ab8500_filter_controls, | ||
2437 | ARRAY_SIZE(ab8500_filter_controls)); | ||
2438 | if (status < 0) { | ||
2439 | dev_err(dev, | ||
2440 | "%s: failed to add ab8500 filter controls (%d).\n", | ||
2441 | __func__, status); | ||
2442 | return status; | ||
2443 | } | ||
2444 | fc = (struct filter_control *) | ||
2445 | &ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value; | ||
2446 | drvdata->anc_fir_values = (long *)fc->value; | ||
2447 | fc = (struct filter_control *) | ||
2448 | &ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value; | ||
2449 | drvdata->anc_iir_values = (long *)fc->value; | ||
2450 | fc = (struct filter_control *) | ||
2451 | &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value; | ||
2452 | drvdata->sid_fir_values = (long *)fc->value; | ||
2453 | |||
2454 | (void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); | ||
2455 | |||
2456 | mutex_init(&drvdata->anc_lock); | ||
2457 | |||
2458 | return status; | ||
2459 | } | ||
2460 | |||
2461 | static struct snd_soc_codec_driver ab8500_codec_driver = { | ||
2462 | .probe = ab8500_codec_probe, | ||
2463 | .read = ab8500_codec_read_reg, | ||
2464 | .write = ab8500_codec_write_reg, | ||
2465 | .reg_word_size = sizeof(u8), | ||
2466 | .controls = ab8500_ctrls, | ||
2467 | .num_controls = ARRAY_SIZE(ab8500_ctrls), | ||
2468 | .dapm_widgets = ab8500_dapm_widgets, | ||
2469 | .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets), | ||
2470 | .dapm_routes = ab8500_dapm_routes, | ||
2471 | .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes), | ||
2472 | }; | ||
2473 | |||
2474 | static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev) | ||
2475 | { | ||
2476 | int status; | ||
2477 | struct ab8500_codec_drvdata *drvdata; | ||
2478 | |||
2479 | dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); | ||
2480 | |||
2481 | /* Create driver private-data struct */ | ||
2482 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_codec_drvdata), | ||
2483 | GFP_KERNEL); | ||
2484 | drvdata->sid_status = SID_UNCONFIGURED; | ||
2485 | drvdata->anc_status = ANC_UNCONFIGURED; | ||
2486 | dev_set_drvdata(&pdev->dev, drvdata); | ||
2487 | |||
2488 | dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__); | ||
2489 | status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver, | ||
2490 | ab8500_codec_dai, | ||
2491 | ARRAY_SIZE(ab8500_codec_dai)); | ||
2492 | if (status < 0) | ||
2493 | dev_err(&pdev->dev, | ||
2494 | "%s: Error: Failed to register codec (%d).\n", | ||
2495 | __func__, status); | ||
2496 | |||
2497 | return status; | ||
2498 | } | ||
2499 | |||
2500 | static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev) | ||
2501 | { | ||
2502 | dev_info(&pdev->dev, "%s Enter.\n", __func__); | ||
2503 | |||
2504 | snd_soc_unregister_codec(&pdev->dev); | ||
2505 | |||
2506 | return 0; | ||
2507 | } | ||
2508 | |||
2509 | static struct platform_driver ab8500_codec_platform_driver = { | ||
2510 | .driver = { | ||
2511 | .name = "ab8500-codec", | ||
2512 | .owner = THIS_MODULE, | ||
2513 | }, | ||
2514 | .probe = ab8500_codec_driver_probe, | ||
2515 | .remove = __devexit_p(ab8500_codec_driver_remove), | ||
2516 | .suspend = NULL, | ||
2517 | .resume = NULL, | ||
2518 | }; | ||
2519 | module_platform_driver(ab8500_codec_platform_driver); | ||
2520 | |||
2521 | MODULE_LICENSE("GPLv2"); | ||
diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h new file mode 100644 index 000000000000..114f69a0c629 --- /dev/null +++ b/sound/soc/codecs/ab8500-codec.h | |||
@@ -0,0 +1,590 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2012 | ||
3 | * | ||
4 | * Author: Ola Lilja <ola.o.lilja@stericsson.com>, | ||
5 | * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>, | ||
6 | * Roger Nilsson <roger.xr.nilsson@stericsson.com>, | ||
7 | * for ST-Ericsson. | ||
8 | * | ||
9 | * Based on the early work done by: | ||
10 | * Mikko J. Lehto <mikko.lehto@symbio.com>, | ||
11 | * Mikko Sarmanne <mikko.sarmanne@symbio.com>, | ||
12 | * for ST-Ericsson. | ||
13 | * | ||
14 | * License terms: | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify it | ||
17 | * under the terms of the GNU General Public License version 2 as published | ||
18 | * by the Free Software Foundation. | ||
19 | */ | ||
20 | |||
21 | #ifndef AB8500_CODEC_REGISTERS_H | ||
22 | #define AB8500_CODEC_REGISTERS_H | ||
23 | |||
24 | #define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000) | ||
25 | #define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE) | ||
26 | |||
27 | /* AB8500 audio bank (0x0d) register definitions */ | ||
28 | |||
29 | #define AB8500_POWERUP 0x00 | ||
30 | #define AB8500_AUDSWRESET 0x01 | ||
31 | #define AB8500_ADPATHENA 0x02 | ||
32 | #define AB8500_DAPATHENA 0x03 | ||
33 | #define AB8500_ANACONF1 0x04 | ||
34 | #define AB8500_ANACONF2 0x05 | ||
35 | #define AB8500_DIGMICCONF 0x06 | ||
36 | #define AB8500_ANACONF3 0x07 | ||
37 | #define AB8500_ANACONF4 0x08 | ||
38 | #define AB8500_DAPATHCONF 0x09 | ||
39 | #define AB8500_MUTECONF 0x0A | ||
40 | #define AB8500_SHORTCIRCONF 0x0B | ||
41 | #define AB8500_ANACONF5 0x0C | ||
42 | #define AB8500_ENVCPCONF 0x0D | ||
43 | #define AB8500_SIGENVCONF 0x0E | ||
44 | #define AB8500_PWMGENCONF1 0x0F | ||
45 | #define AB8500_PWMGENCONF2 0x10 | ||
46 | #define AB8500_PWMGENCONF3 0x11 | ||
47 | #define AB8500_PWMGENCONF4 0x12 | ||
48 | #define AB8500_PWMGENCONF5 0x13 | ||
49 | #define AB8500_ANAGAIN1 0x14 | ||
50 | #define AB8500_ANAGAIN2 0x15 | ||
51 | #define AB8500_ANAGAIN3 0x16 | ||
52 | #define AB8500_ANAGAIN4 0x17 | ||
53 | #define AB8500_DIGLINHSLGAIN 0x18 | ||
54 | #define AB8500_DIGLINHSRGAIN 0x19 | ||
55 | #define AB8500_ADFILTCONF 0x1A | ||
56 | #define AB8500_DIGIFCONF1 0x1B | ||
57 | #define AB8500_DIGIFCONF2 0x1C | ||
58 | #define AB8500_DIGIFCONF3 0x1D | ||
59 | #define AB8500_DIGIFCONF4 0x1E | ||
60 | #define AB8500_ADSLOTSEL1 0x1F | ||
61 | #define AB8500_ADSLOTSEL2 0x20 | ||
62 | #define AB8500_ADSLOTSEL3 0x21 | ||
63 | #define AB8500_ADSLOTSEL4 0x22 | ||
64 | #define AB8500_ADSLOTSEL5 0x23 | ||
65 | #define AB8500_ADSLOTSEL6 0x24 | ||
66 | #define AB8500_ADSLOTSEL7 0x25 | ||
67 | #define AB8500_ADSLOTSEL8 0x26 | ||
68 | #define AB8500_ADSLOTSEL9 0x27 | ||
69 | #define AB8500_ADSLOTSEL10 0x28 | ||
70 | #define AB8500_ADSLOTSEL11 0x29 | ||
71 | #define AB8500_ADSLOTSEL12 0x2A | ||
72 | #define AB8500_ADSLOTSEL13 0x2B | ||
73 | #define AB8500_ADSLOTSEL14 0x2C | ||
74 | #define AB8500_ADSLOTSEL15 0x2D | ||
75 | #define AB8500_ADSLOTSEL16 0x2E | ||
76 | #define AB8500_ADSLOTHIZCTRL1 0x2F | ||
77 | #define AB8500_ADSLOTHIZCTRL2 0x30 | ||
78 | #define AB8500_ADSLOTHIZCTRL3 0x31 | ||
79 | #define AB8500_ADSLOTHIZCTRL4 0x32 | ||
80 | #define AB8500_DASLOTCONF1 0x33 | ||
81 | #define AB8500_DASLOTCONF2 0x34 | ||
82 | #define AB8500_DASLOTCONF3 0x35 | ||
83 | #define AB8500_DASLOTCONF4 0x36 | ||
84 | #define AB8500_DASLOTCONF5 0x37 | ||
85 | #define AB8500_DASLOTCONF6 0x38 | ||
86 | #define AB8500_DASLOTCONF7 0x39 | ||
87 | #define AB8500_DASLOTCONF8 0x3A | ||
88 | #define AB8500_CLASSDCONF1 0x3B | ||
89 | #define AB8500_CLASSDCONF2 0x3C | ||
90 | #define AB8500_CLASSDCONF3 0x3D | ||
91 | #define AB8500_DMICFILTCONF 0x3E | ||
92 | #define AB8500_DIGMULTCONF1 0x3F | ||
93 | #define AB8500_DIGMULTCONF2 0x40 | ||
94 | #define AB8500_ADDIGGAIN1 0x41 | ||
95 | #define AB8500_ADDIGGAIN2 0x42 | ||
96 | #define AB8500_ADDIGGAIN3 0x43 | ||
97 | #define AB8500_ADDIGGAIN4 0x44 | ||
98 | #define AB8500_ADDIGGAIN5 0x45 | ||
99 | #define AB8500_ADDIGGAIN6 0x46 | ||
100 | #define AB8500_DADIGGAIN1 0x47 | ||
101 | #define AB8500_DADIGGAIN2 0x48 | ||
102 | #define AB8500_DADIGGAIN3 0x49 | ||
103 | #define AB8500_DADIGGAIN4 0x4A | ||
104 | #define AB8500_DADIGGAIN5 0x4B | ||
105 | #define AB8500_DADIGGAIN6 0x4C | ||
106 | #define AB8500_ADDIGLOOPGAIN1 0x4D | ||
107 | #define AB8500_ADDIGLOOPGAIN2 0x4E | ||
108 | #define AB8500_HSLEARDIGGAIN 0x4F | ||
109 | #define AB8500_HSRDIGGAIN 0x50 | ||
110 | #define AB8500_SIDFIRGAIN1 0x51 | ||
111 | #define AB8500_SIDFIRGAIN2 0x52 | ||
112 | #define AB8500_ANCCONF1 0x53 | ||
113 | #define AB8500_ANCCONF2 0x54 | ||
114 | #define AB8500_ANCCONF3 0x55 | ||
115 | #define AB8500_ANCCONF4 0x56 | ||
116 | #define AB8500_ANCCONF5 0x57 | ||
117 | #define AB8500_ANCCONF6 0x58 | ||
118 | #define AB8500_ANCCONF7 0x59 | ||
119 | #define AB8500_ANCCONF8 0x5A | ||
120 | #define AB8500_ANCCONF9 0x5B | ||
121 | #define AB8500_ANCCONF10 0x5C | ||
122 | #define AB8500_ANCCONF11 0x5D | ||
123 | #define AB8500_ANCCONF12 0x5E | ||
124 | #define AB8500_ANCCONF13 0x5F | ||
125 | #define AB8500_ANCCONF14 0x60 | ||
126 | #define AB8500_SIDFIRADR 0x61 | ||
127 | #define AB8500_SIDFIRCOEF1 0x62 | ||
128 | #define AB8500_SIDFIRCOEF2 0x63 | ||
129 | #define AB8500_SIDFIRCONF 0x64 | ||
130 | #define AB8500_AUDINTMASK1 0x65 | ||
131 | #define AB8500_AUDINTSOURCE1 0x66 | ||
132 | #define AB8500_AUDINTMASK2 0x67 | ||
133 | #define AB8500_AUDINTSOURCE2 0x68 | ||
134 | #define AB8500_FIFOCONF1 0x69 | ||
135 | #define AB8500_FIFOCONF2 0x6A | ||
136 | #define AB8500_FIFOCONF3 0x6B | ||
137 | #define AB8500_FIFOCONF4 0x6C | ||
138 | #define AB8500_FIFOCONF5 0x6D | ||
139 | #define AB8500_FIFOCONF6 0x6E | ||
140 | #define AB8500_AUDREV 0x6F | ||
141 | |||
142 | #define AB8500_FIRST_REG AB8500_POWERUP | ||
143 | #define AB8500_LAST_REG AB8500_AUDREV | ||
144 | #define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1) | ||
145 | |||
146 | #define AB8500_MASK_ALL 0xFF | ||
147 | #define AB8500_MASK_NONE 0x00 | ||
148 | |||
149 | /* AB8500_POWERUP */ | ||
150 | #define AB8500_POWERUP_POWERUP 7 | ||
151 | #define AB8500_POWERUP_ENANA 3 | ||
152 | |||
153 | /* AB8500_AUDSWRESET */ | ||
154 | #define AB8500_AUDSWRESET_SWRESET 7 | ||
155 | |||
156 | /* AB8500_ADPATHENA */ | ||
157 | #define AB8500_ADPATHENA_ENAD12 7 | ||
158 | #define AB8500_ADPATHENA_ENAD34 5 | ||
159 | #define AB8500_ADPATHENA_ENAD5768 3 | ||
160 | |||
161 | /* AB8500_DAPATHENA */ | ||
162 | #define AB8500_DAPATHENA_ENDA1 7 | ||
163 | #define AB8500_DAPATHENA_ENDA2 6 | ||
164 | #define AB8500_DAPATHENA_ENDA3 5 | ||
165 | #define AB8500_DAPATHENA_ENDA4 4 | ||
166 | #define AB8500_DAPATHENA_ENDA5 3 | ||
167 | #define AB8500_DAPATHENA_ENDA6 2 | ||
168 | |||
169 | /* AB8500_ANACONF1 */ | ||
170 | #define AB8500_ANACONF1_HSLOWPOW 7 | ||
171 | #define AB8500_ANACONF1_DACLOWPOW1 6 | ||
172 | #define AB8500_ANACONF1_DACLOWPOW0 5 | ||
173 | #define AB8500_ANACONF1_EARDACLOWPOW 4 | ||
174 | #define AB8500_ANACONF1_EARSELCM 2 | ||
175 | #define AB8500_ANACONF1_HSHPEN 1 | ||
176 | #define AB8500_ANACONF1_EARDRVLOWPOW 0 | ||
177 | |||
178 | /* AB8500_ANACONF2 */ | ||
179 | #define AB8500_ANACONF2_ENMIC1 7 | ||
180 | #define AB8500_ANACONF2_ENMIC2 6 | ||
181 | #define AB8500_ANACONF2_ENLINL 5 | ||
182 | #define AB8500_ANACONF2_ENLINR 4 | ||
183 | #define AB8500_ANACONF2_MUTMIC1 3 | ||
184 | #define AB8500_ANACONF2_MUTMIC2 2 | ||
185 | #define AB8500_ANACONF2_MUTLINL 1 | ||
186 | #define AB8500_ANACONF2_MUTLINR 0 | ||
187 | |||
188 | /* AB8500_DIGMICCONF */ | ||
189 | #define AB8500_DIGMICCONF_ENDMIC1 7 | ||
190 | #define AB8500_DIGMICCONF_ENDMIC2 6 | ||
191 | #define AB8500_DIGMICCONF_ENDMIC3 5 | ||
192 | #define AB8500_DIGMICCONF_ENDMIC4 4 | ||
193 | #define AB8500_DIGMICCONF_ENDMIC5 3 | ||
194 | #define AB8500_DIGMICCONF_ENDMIC6 2 | ||
195 | #define AB8500_DIGMICCONF_HSFADSPEED 0 | ||
196 | |||
197 | /* AB8500_ANACONF3 */ | ||
198 | #define AB8500_ANACONF3_MIC1SEL 7 | ||
199 | #define AB8500_ANACONF3_LINRSEL 6 | ||
200 | #define AB8500_ANACONF3_ENDRVHSL 5 | ||
201 | #define AB8500_ANACONF3_ENDRVHSR 4 | ||
202 | #define AB8500_ANACONF3_ENADCMIC 2 | ||
203 | #define AB8500_ANACONF3_ENADCLINL 1 | ||
204 | #define AB8500_ANACONF3_ENADCLINR 0 | ||
205 | |||
206 | /* AB8500_ANACONF4 */ | ||
207 | #define AB8500_ANACONF4_DISPDVSS 7 | ||
208 | #define AB8500_ANACONF4_ENEAR 6 | ||
209 | #define AB8500_ANACONF4_ENHSL 5 | ||
210 | #define AB8500_ANACONF4_ENHSR 4 | ||
211 | #define AB8500_ANACONF4_ENHFL 3 | ||
212 | #define AB8500_ANACONF4_ENHFR 2 | ||
213 | #define AB8500_ANACONF4_ENVIB1 1 | ||
214 | #define AB8500_ANACONF4_ENVIB2 0 | ||
215 | |||
216 | /* AB8500_DAPATHCONF */ | ||
217 | #define AB8500_DAPATHCONF_ENDACEAR 6 | ||
218 | #define AB8500_DAPATHCONF_ENDACHSL 5 | ||
219 | #define AB8500_DAPATHCONF_ENDACHSR 4 | ||
220 | #define AB8500_DAPATHCONF_ENDACHFL 3 | ||
221 | #define AB8500_DAPATHCONF_ENDACHFR 2 | ||
222 | #define AB8500_DAPATHCONF_ENDACVIB1 1 | ||
223 | #define AB8500_DAPATHCONF_ENDACVIB2 0 | ||
224 | |||
225 | /* AB8500_MUTECONF */ | ||
226 | #define AB8500_MUTECONF_MUTEAR 6 | ||
227 | #define AB8500_MUTECONF_MUTHSL 5 | ||
228 | #define AB8500_MUTECONF_MUTHSR 4 | ||
229 | #define AB8500_MUTECONF_MUTDACEAR 2 | ||
230 | #define AB8500_MUTECONF_MUTDACHSL 1 | ||
231 | #define AB8500_MUTECONF_MUTDACHSR 0 | ||
232 | |||
233 | /* AB8500_SHORTCIRCONF */ | ||
234 | #define AB8500_SHORTCIRCONF_ENSHORTPWD 7 | ||
235 | #define AB8500_SHORTCIRCONF_EARSHORTDIS 6 | ||
236 | #define AB8500_SHORTCIRCONF_HSSHORTDIS 5 | ||
237 | #define AB8500_SHORTCIRCONF_HSPULLDEN 4 | ||
238 | #define AB8500_SHORTCIRCONF_HSOSCEN 2 | ||
239 | #define AB8500_SHORTCIRCONF_HSFADDIS 1 | ||
240 | #define AB8500_SHORTCIRCONF_HSZCDDIS 0 | ||
241 | /* Zero cross should be disabled */ | ||
242 | |||
243 | /* AB8500_ANACONF5 */ | ||
244 | #define AB8500_ANACONF5_ENCPHS 7 | ||
245 | #define AB8500_ANACONF5_HSLDACTOLOL 5 | ||
246 | #define AB8500_ANACONF5_HSRDACTOLOR 4 | ||
247 | #define AB8500_ANACONF5_ENLOL 3 | ||
248 | #define AB8500_ANACONF5_ENLOR 2 | ||
249 | #define AB8500_ANACONF5_HSAUTOEN 0 | ||
250 | |||
251 | /* AB8500_ENVCPCONF */ | ||
252 | #define AB8500_ENVCPCONF_ENVDETHTHRE 4 | ||
253 | #define AB8500_ENVCPCONF_ENVDETLTHRE 0 | ||
254 | #define AB8500_ENVCPCONF_ENVDETHTHRE_MAX 0x0F | ||
255 | #define AB8500_ENVCPCONF_ENVDETLTHRE_MAX 0x0F | ||
256 | |||
257 | /* AB8500_SIGENVCONF */ | ||
258 | #define AB8500_SIGENVCONF_CPLVEN 5 | ||
259 | #define AB8500_SIGENVCONF_ENVDETCPEN 4 | ||
260 | #define AB8500_SIGENVCONF_ENVDETTIME 0 | ||
261 | #define AB8500_SIGENVCONF_ENVDETTIME_MAX 0x0F | ||
262 | |||
263 | /* AB8500_PWMGENCONF1 */ | ||
264 | #define AB8500_PWMGENCONF1_PWMTOVIB1 7 | ||
265 | #define AB8500_PWMGENCONF1_PWMTOVIB2 6 | ||
266 | #define AB8500_PWMGENCONF1_PWM1CTRL 5 | ||
267 | #define AB8500_PWMGENCONF1_PWM2CTRL 4 | ||
268 | #define AB8500_PWMGENCONF1_PWM1NCTRL 3 | ||
269 | #define AB8500_PWMGENCONF1_PWM1PCTRL 2 | ||
270 | #define AB8500_PWMGENCONF1_PWM2NCTRL 1 | ||
271 | #define AB8500_PWMGENCONF1_PWM2PCTRL 0 | ||
272 | |||
273 | /* AB8500_PWMGENCONF2 */ | ||
274 | /* AB8500_PWMGENCONF3 */ | ||
275 | /* AB8500_PWMGENCONF4 */ | ||
276 | /* AB8500_PWMGENCONF5 */ | ||
277 | #define AB8500_PWMGENCONFX_PWMVIBXPOL 7 | ||
278 | #define AB8500_PWMGENCONFX_PWMVIBXDUTCYC 0 | ||
279 | #define AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX 0x64 | ||
280 | |||
281 | /* AB8500_ANAGAIN1 */ | ||
282 | /* AB8500_ANAGAIN2 */ | ||
283 | #define AB8500_ANAGAINX_ENSEMICX 7 | ||
284 | #define AB8500_ANAGAINX_LOWPOWMICX 6 | ||
285 | #define AB8500_ANAGAINX_MICXGAIN 0 | ||
286 | #define AB8500_ANAGAINX_MICXGAIN_MAX 0x1F | ||
287 | |||
288 | /* AB8500_ANAGAIN3 */ | ||
289 | #define AB8500_ANAGAIN3_HSLGAIN 4 | ||
290 | #define AB8500_ANAGAIN3_HSRGAIN 0 | ||
291 | #define AB8500_ANAGAIN3_HSXGAIN_MAX 0x0F | ||
292 | |||
293 | /* AB8500_ANAGAIN4 */ | ||
294 | #define AB8500_ANAGAIN4_LINLGAIN 4 | ||
295 | #define AB8500_ANAGAIN4_LINRGAIN 0 | ||
296 | #define AB8500_ANAGAIN4_LINXGAIN_MAX 0x0F | ||
297 | |||
298 | /* AB8500_DIGLINHSLGAIN */ | ||
299 | /* AB8500_DIGLINHSRGAIN */ | ||
300 | #define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN 0 | ||
301 | #define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX 0x13 | ||
302 | |||
303 | /* AB8500_ADFILTCONF */ | ||
304 | #define AB8500_ADFILTCONF_AD1NH 7 | ||
305 | #define AB8500_ADFILTCONF_AD2NH 6 | ||
306 | #define AB8500_ADFILTCONF_AD3NH 5 | ||
307 | #define AB8500_ADFILTCONF_AD4NH 4 | ||
308 | #define AB8500_ADFILTCONF_AD1VOICE 3 | ||
309 | #define AB8500_ADFILTCONF_AD2VOICE 2 | ||
310 | #define AB8500_ADFILTCONF_AD3VOICE 1 | ||
311 | #define AB8500_ADFILTCONF_AD4VOICE 0 | ||
312 | |||
313 | /* AB8500_DIGIFCONF1 */ | ||
314 | #define AB8500_DIGIFCONF1_ENMASTGEN 7 | ||
315 | #define AB8500_DIGIFCONF1_IF1BITCLKOS1 6 | ||
316 | #define AB8500_DIGIFCONF1_IF1BITCLKOS0 5 | ||
317 | #define AB8500_DIGIFCONF1_ENFSBITCLK1 4 | ||
318 | #define AB8500_DIGIFCONF1_IF0BITCLKOS1 2 | ||
319 | #define AB8500_DIGIFCONF1_IF0BITCLKOS0 1 | ||
320 | #define AB8500_DIGIFCONF1_ENFSBITCLK0 0 | ||
321 | |||
322 | /* AB8500_DIGIFCONF2 */ | ||
323 | #define AB8500_DIGIFCONF2_FSYNC0P 6 | ||
324 | #define AB8500_DIGIFCONF2_BITCLK0P 5 | ||
325 | #define AB8500_DIGIFCONF2_IF0DEL 4 | ||
326 | #define AB8500_DIGIFCONF2_IF0FORMAT1 3 | ||
327 | #define AB8500_DIGIFCONF2_IF0FORMAT0 2 | ||
328 | #define AB8500_DIGIFCONF2_IF0WL1 1 | ||
329 | #define AB8500_DIGIFCONF2_IF0WL0 0 | ||
330 | |||
331 | /* AB8500_DIGIFCONF3 */ | ||
332 | #define AB8500_DIGIFCONF3_IF0DATOIF1AD 7 | ||
333 | #define AB8500_DIGIFCONF3_IF0CLKTOIF1CLK 6 | ||
334 | #define AB8500_DIGIFCONF3_IF1MASTER 5 | ||
335 | #define AB8500_DIGIFCONF3_IF1DATOIF0AD 3 | ||
336 | #define AB8500_DIGIFCONF3_IF1CLKTOIF0CLK 2 | ||
337 | #define AB8500_DIGIFCONF3_IF0MASTER 1 | ||
338 | #define AB8500_DIGIFCONF3_IF0BFIFOEN 0 | ||
339 | |||
340 | /* AB8500_DIGIFCONF4 */ | ||
341 | #define AB8500_DIGIFCONF4_FSYNC1P 6 | ||
342 | #define AB8500_DIGIFCONF4_BITCLK1P 5 | ||
343 | #define AB8500_DIGIFCONF4_IF1DEL 4 | ||
344 | #define AB8500_DIGIFCONF4_IF1FORMAT1 3 | ||
345 | #define AB8500_DIGIFCONF4_IF1FORMAT0 2 | ||
346 | #define AB8500_DIGIFCONF4_IF1WL1 1 | ||
347 | #define AB8500_DIGIFCONF4_IF1WL0 0 | ||
348 | |||
349 | /* AB8500_ADSLOTSELX */ | ||
350 | #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00 | ||
351 | #define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x01 | ||
352 | #define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x02 | ||
353 | #define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x03 | ||
354 | #define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x04 | ||
355 | #define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x05 | ||
356 | #define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x06 | ||
357 | #define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x07 | ||
358 | #define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x08 | ||
359 | #define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F | ||
360 | #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00 | ||
361 | #define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10 | ||
362 | #define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20 | ||
363 | #define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30 | ||
364 | #define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40 | ||
365 | #define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50 | ||
366 | #define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60 | ||
367 | #define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70 | ||
368 | #define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x80 | ||
369 | #define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0xF0 | ||
370 | #define AB8500_ADSLOTSELX_EVEN_SHIFT 0 | ||
371 | #define AB8500_ADSLOTSELX_ODD_SHIFT 4 | ||
372 | |||
373 | /* AB8500_ADSLOTHIZCTRL1 */ | ||
374 | /* AB8500_ADSLOTHIZCTRL2 */ | ||
375 | /* AB8500_ADSLOTHIZCTRL3 */ | ||
376 | /* AB8500_ADSLOTHIZCTRL4 */ | ||
377 | /* AB8500_DASLOTCONF1 */ | ||
378 | #define AB8500_DASLOTCONF1_DA12VOICE 7 | ||
379 | #define AB8500_DASLOTCONF1_SWAPDA12_34 6 | ||
380 | #define AB8500_DASLOTCONF1_DAI7TOADO1 5 | ||
381 | |||
382 | /* AB8500_DASLOTCONF2 */ | ||
383 | #define AB8500_DASLOTCONF2_DAI8TOADO2 5 | ||
384 | |||
385 | /* AB8500_DASLOTCONF3 */ | ||
386 | #define AB8500_DASLOTCONF3_DA34VOICE 7 | ||
387 | #define AB8500_DASLOTCONF3_DAI7TOADO3 5 | ||
388 | |||
389 | /* AB8500_DASLOTCONF4 */ | ||
390 | #define AB8500_DASLOTCONF4_DAI8TOADO4 5 | ||
391 | |||
392 | /* AB8500_DASLOTCONF5 */ | ||
393 | #define AB8500_DASLOTCONF5_DA56VOICE 7 | ||
394 | #define AB8500_DASLOTCONF5_DAI7TOADO5 5 | ||
395 | |||
396 | /* AB8500_DASLOTCONF6 */ | ||
397 | #define AB8500_DASLOTCONF6_DAI8TOADO6 5 | ||
398 | |||
399 | /* AB8500_DASLOTCONF7 */ | ||
400 | #define AB8500_DASLOTCONF7_DAI8TOADO7 5 | ||
401 | |||
402 | /* AB8500_DASLOTCONF8 */ | ||
403 | #define AB8500_DASLOTCONF8_DAI7TOADO8 5 | ||
404 | |||
405 | #define AB8500_DASLOTCONFX_SLTODAX_SHIFT 0 | ||
406 | #define AB8500_DASLOTCONFX_SLTODAX_MASK 0x1F | ||
407 | |||
408 | /* AB8500_CLASSDCONF1 */ | ||
409 | #define AB8500_CLASSDCONF1_PARLHF 7 | ||
410 | #define AB8500_CLASSDCONF1_PARLVIB 6 | ||
411 | #define AB8500_CLASSDCONF1_VIB1SWAPEN 3 | ||
412 | #define AB8500_CLASSDCONF1_VIB2SWAPEN 2 | ||
413 | #define AB8500_CLASSDCONF1_HFLSWAPEN 1 | ||
414 | #define AB8500_CLASSDCONF1_HFRSWAPEN 0 | ||
415 | |||
416 | /* AB8500_CLASSDCONF2 */ | ||
417 | #define AB8500_CLASSDCONF2_FIRBYP3 7 | ||
418 | #define AB8500_CLASSDCONF2_FIRBYP2 6 | ||
419 | #define AB8500_CLASSDCONF2_FIRBYP1 5 | ||
420 | #define AB8500_CLASSDCONF2_FIRBYP0 4 | ||
421 | #define AB8500_CLASSDCONF2_HIGHVOLEN3 3 | ||
422 | #define AB8500_CLASSDCONF2_HIGHVOLEN2 2 | ||
423 | #define AB8500_CLASSDCONF2_HIGHVOLEN1 1 | ||
424 | #define AB8500_CLASSDCONF2_HIGHVOLEN0 0 | ||
425 | |||
426 | /* AB8500_CLASSDCONF3 */ | ||
427 | #define AB8500_CLASSDCONF3_DITHHPGAIN 4 | ||
428 | #define AB8500_CLASSDCONF3_DITHHPGAIN_MAX 0x0A | ||
429 | #define AB8500_CLASSDCONF3_DITHWGAIN 0 | ||
430 | #define AB8500_CLASSDCONF3_DITHWGAIN_MAX 0x0A | ||
431 | |||
432 | /* AB8500_DMICFILTCONF */ | ||
433 | #define AB8500_DMICFILTCONF_ANCINSEL 7 | ||
434 | #define AB8500_DMICFILTCONF_DA3TOEAR 6 | ||
435 | #define AB8500_DMICFILTCONF_DMIC1SINC3 5 | ||
436 | #define AB8500_DMICFILTCONF_DMIC2SINC3 4 | ||
437 | #define AB8500_DMICFILTCONF_DMIC3SINC3 3 | ||
438 | #define AB8500_DMICFILTCONF_DMIC4SINC3 2 | ||
439 | #define AB8500_DMICFILTCONF_DMIC5SINC3 1 | ||
440 | #define AB8500_DMICFILTCONF_DMIC6SINC3 0 | ||
441 | |||
442 | /* AB8500_DIGMULTCONF1 */ | ||
443 | #define AB8500_DIGMULTCONF1_DATOHSLEN 7 | ||
444 | #define AB8500_DIGMULTCONF1_DATOHSREN 6 | ||
445 | #define AB8500_DIGMULTCONF1_AD1SEL 5 | ||
446 | #define AB8500_DIGMULTCONF1_AD2SEL 4 | ||
447 | #define AB8500_DIGMULTCONF1_AD3SEL 3 | ||
448 | #define AB8500_DIGMULTCONF1_AD5SEL 2 | ||
449 | #define AB8500_DIGMULTCONF1_AD6SEL 1 | ||
450 | #define AB8500_DIGMULTCONF1_ANCSEL 0 | ||
451 | |||
452 | /* AB8500_DIGMULTCONF2 */ | ||
453 | #define AB8500_DIGMULTCONF2_DATOHFREN 7 | ||
454 | #define AB8500_DIGMULTCONF2_DATOHFLEN 6 | ||
455 | #define AB8500_DIGMULTCONF2_HFRSEL 5 | ||
456 | #define AB8500_DIGMULTCONF2_HFLSEL 4 | ||
457 | #define AB8500_DIGMULTCONF2_FIRSID1SEL 2 | ||
458 | #define AB8500_DIGMULTCONF2_FIRSID2SEL 0 | ||
459 | |||
460 | /* AB8500_ADDIGGAIN1 */ | ||
461 | /* AB8500_ADDIGGAIN2 */ | ||
462 | /* AB8500_ADDIGGAIN3 */ | ||
463 | /* AB8500_ADDIGGAIN4 */ | ||
464 | /* AB8500_ADDIGGAIN5 */ | ||
465 | /* AB8500_ADDIGGAIN6 */ | ||
466 | #define AB8500_ADDIGGAINX_FADEDISADX 6 | ||
467 | #define AB8500_ADDIGGAINX_ADXGAIN_MAX 0x3F | ||
468 | |||
469 | /* AB8500_DADIGGAIN1 */ | ||
470 | /* AB8500_DADIGGAIN2 */ | ||
471 | /* AB8500_DADIGGAIN3 */ | ||
472 | /* AB8500_DADIGGAIN4 */ | ||
473 | /* AB8500_DADIGGAIN5 */ | ||
474 | /* AB8500_DADIGGAIN6 */ | ||
475 | #define AB8500_DADIGGAINX_FADEDISDAX 6 | ||
476 | #define AB8500_DADIGGAINX_DAXGAIN_MAX 0x3F | ||
477 | |||
478 | /* AB8500_ADDIGLOOPGAIN1 */ | ||
479 | /* AB8500_ADDIGLOOPGAIN2 */ | ||
480 | #define AB8500_ADDIGLOOPGAINX_FADEDISADXL 6 | ||
481 | #define AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX 0x3F | ||
482 | |||
483 | /* AB8500_HSLEARDIGGAIN */ | ||
484 | #define AB8500_HSLEARDIGGAIN_HSSINC1 7 | ||
485 | #define AB8500_HSLEARDIGGAIN_FADEDISHSL 4 | ||
486 | #define AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX 0x09 | ||
487 | |||
488 | /* AB8500_HSRDIGGAIN */ | ||
489 | #define AB8500_HSRDIGGAIN_FADESPEED 6 | ||
490 | #define AB8500_HSRDIGGAIN_FADEDISHSR 4 | ||
491 | #define AB8500_HSRDIGGAIN_HSRDGAIN_MAX 0x09 | ||
492 | |||
493 | /* AB8500_SIDFIRGAIN1 */ | ||
494 | /* AB8500_SIDFIRGAIN2 */ | ||
495 | #define AB8500_SIDFIRGAINX_FIRSIDXGAIN_MAX 0x1F | ||
496 | |||
497 | /* AB8500_ANCCONF1 */ | ||
498 | #define AB8500_ANCCONF1_ANCIIRUPDATE 3 | ||
499 | #define AB8500_ANCCONF1_ENANC 2 | ||
500 | #define AB8500_ANCCONF1_ANCIIRINIT 1 | ||
501 | #define AB8500_ANCCONF1_ANCFIRUPDATE 0 | ||
502 | |||
503 | /* AB8500_ANCCONF2 */ | ||
504 | #define AB8500_ANCCONF2_SHIFT 5 | ||
505 | #define AB8500_ANCCONF2_MIN -0x10 | ||
506 | #define AB8500_ANCCONF2_MAX 0xF | ||
507 | |||
508 | /* AB8500_ANCCONF3 */ | ||
509 | #define AB8500_ANCCONF3_SHIFT 5 | ||
510 | #define AB8500_ANCCONF3_MIN -0x10 | ||
511 | #define AB8500_ANCCONF3_MAX 0xF | ||
512 | |||
513 | /* AB8500_ANCCONF4 */ | ||
514 | #define AB8500_ANCCONF4_SHIFT 5 | ||
515 | #define AB8500_ANCCONF4_MIN -0x10 | ||
516 | #define AB8500_ANCCONF4_MAX 0xF | ||
517 | |||
518 | /* AB8500_ANC_FIR_COEFFS */ | ||
519 | #define AB8500_ANC_FIR_COEFF_MIN -0x8000 | ||
520 | #define AB8500_ANC_FIR_COEFF_MAX 0x7FFF | ||
521 | #define AB8500_ANC_FIR_COEFFS 15 | ||
522 | |||
523 | /* AB8500_ANC_IIR_COEFFS */ | ||
524 | #define AB8500_ANC_IIR_COEFF_MIN -0x800000 | ||
525 | #define AB8500_ANC_IIR_COEFF_MAX 0x7FFFFF | ||
526 | #define AB8500_ANC_IIR_COEFFS 24 | ||
527 | /* AB8500_ANC_WARP_DELAY */ | ||
528 | #define AB8500_ANC_WARP_DELAY_SHIFT 16 | ||
529 | #define AB8500_ANC_WARP_DELAY_MIN 0x0000 | ||
530 | #define AB8500_ANC_WARP_DELAY_MAX 0xFFFF | ||
531 | |||
532 | /* AB8500_ANCCONF11 */ | ||
533 | /* AB8500_ANCCONF12 */ | ||
534 | /* AB8500_ANCCONF13 */ | ||
535 | /* AB8500_ANCCONF14 */ | ||
536 | |||
537 | /* AB8500_SIDFIRADR */ | ||
538 | #define AB8500_SIDFIRADR_FIRSIDSET 7 | ||
539 | #define AB8500_SIDFIRADR_ADDRESS_SHIFT 0 | ||
540 | #define AB8500_SIDFIRADR_ADDRESS_MAX 0x7F | ||
541 | |||
542 | /* AB8500_SIDFIRCOEF1 */ | ||
543 | /* AB8500_SIDFIRCOEF2 */ | ||
544 | #define AB8500_SID_FIR_COEFF_MIN 0 | ||
545 | #define AB8500_SID_FIR_COEFF_MAX 0xFFFF | ||
546 | #define AB8500_SID_FIR_COEFFS 128 | ||
547 | |||
548 | /* AB8500_SIDFIRCONF */ | ||
549 | #define AB8500_SIDFIRCONF_ENFIRSIDS 2 | ||
550 | #define AB8500_SIDFIRCONF_FIRSIDSTOIF1 1 | ||
551 | #define AB8500_SIDFIRCONF_FIRSIDBUSY 0 | ||
552 | |||
553 | /* AB8500_AUDINTMASK1 */ | ||
554 | /* AB8500_AUDINTSOURCE1 */ | ||
555 | /* AB8500_AUDINTMASK2 */ | ||
556 | /* AB8500_AUDINTSOURCE2 */ | ||
557 | |||
558 | /* AB8500_FIFOCONF1 */ | ||
559 | #define AB8500_FIFOCONF1_BFIFOMASK 0x80 | ||
560 | #define AB8500_FIFOCONF1_BFIFO19M2 0x40 | ||
561 | #define AB8500_FIFOCONF1_BFIFOINT_SHIFT 0 | ||
562 | #define AB8500_FIFOCONF1_BFIFOINT_MAX 0x3F | ||
563 | |||
564 | /* AB8500_FIFOCONF2 */ | ||
565 | #define AB8500_FIFOCONF2_BFIFOTX_SHIFT 0 | ||
566 | #define AB8500_FIFOCONF2_BFIFOTX_MAX 0xFF | ||
567 | |||
568 | /* AB8500_FIFOCONF3 */ | ||
569 | #define AB8500_FIFOCONF3_BFIFOEXSL_SHIFT 5 | ||
570 | #define AB8500_FIFOCONF3_BFIFOEXSL_MAX 0x5 | ||
571 | #define AB8500_FIFOCONF3_PREBITCLK0_SHIFT 2 | ||
572 | #define AB8500_FIFOCONF3_PREBITCLK0_MAX 0x7 | ||
573 | #define AB8500_FIFOCONF3_BFIFOMAST_SHIFT 1 | ||
574 | #define AB8500_FIFOCONF3_BFIFORUN_SHIFT 0 | ||
575 | |||
576 | /* AB8500_FIFOCONF4 */ | ||
577 | #define AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT 0 | ||
578 | #define AB8500_FIFOCONF4_BFIFOFRAMSW_MAX 0xFF | ||
579 | |||
580 | /* AB8500_FIFOCONF5 */ | ||
581 | #define AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT 0 | ||
582 | #define AB8500_FIFOCONF5_BFIFOWAKEUP_MAX 0xFF | ||
583 | |||
584 | /* AB8500_FIFOCONF6 */ | ||
585 | #define AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT 0 | ||
586 | #define AB8500_FIFOCONF6_BFIFOSAMPLE_MAX 0xFF | ||
587 | |||
588 | /* AB8500_AUDREV */ | ||
589 | |||
590 | #endif | ||
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 2023c749f232..ea06b834a7de 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -91,11 +91,6 @@ static int ac97_soc_probe(struct snd_soc_codec *codec) | |||
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | static int ac97_soc_remove(struct snd_soc_codec *codec) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | #ifdef CONFIG_PM | 94 | #ifdef CONFIG_PM |
100 | static int ac97_soc_suspend(struct snd_soc_codec *codec) | 95 | static int ac97_soc_suspend(struct snd_soc_codec *codec) |
101 | { | 96 | { |
@@ -119,7 +114,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = { | |||
119 | .write = ac97_write, | 114 | .write = ac97_write, |
120 | .read = ac97_read, | 115 | .read = ac97_read, |
121 | .probe = ac97_soc_probe, | 116 | .probe = ac97_soc_probe, |
122 | .remove = ac97_soc_remove, | ||
123 | .suspend = ac97_soc_suspend, | 117 | .suspend = ac97_soc_suspend, |
124 | .resume = ac97_soc_resume, | 118 | .resume = ac97_soc_resume, |
125 | }; | 119 | }; |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index a7109413aef1..628daf6a1d97 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/moduleparam.h> | 16 | #include <linux/moduleparam.h> |
17 | #include <linux/version.h> | ||
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 18 | #include <linux/init.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
@@ -1217,11 +1216,11 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | |||
1217 | return -ENOMEM; | 1216 | return -ENOMEM; |
1218 | cs42l52->dev = &i2c_client->dev; | 1217 | cs42l52->dev = &i2c_client->dev; |
1219 | 1218 | ||
1220 | cs42l52->regmap = regmap_init_i2c(i2c_client, &cs42l52_regmap); | 1219 | cs42l52->regmap = devm_regmap_init_i2c(i2c_client, &cs42l52_regmap); |
1221 | if (IS_ERR(cs42l52->regmap)) { | 1220 | if (IS_ERR(cs42l52->regmap)) { |
1222 | ret = PTR_ERR(cs42l52->regmap); | 1221 | ret = PTR_ERR(cs42l52->regmap); |
1223 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); | 1222 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); |
1224 | goto err; | 1223 | return ret; |
1225 | } | 1224 | } |
1226 | 1225 | ||
1227 | i2c_set_clientdata(i2c_client, cs42l52); | 1226 | i2c_set_clientdata(i2c_client, cs42l52); |
@@ -1243,7 +1242,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | |||
1243 | dev_err(&i2c_client->dev, | 1242 | dev_err(&i2c_client->dev, |
1244 | "CS42L52 Device ID (%X). Expected %X\n", | 1243 | "CS42L52 Device ID (%X). Expected %X\n", |
1245 | devid, CS42L52_CHIP_ID); | 1244 | devid, CS42L52_CHIP_ID); |
1246 | goto err_regmap; | 1245 | return ret; |
1247 | } | 1246 | } |
1248 | 1247 | ||
1249 | regcache_cache_only(cs42l52->regmap, true); | 1248 | regcache_cache_only(cs42l52->regmap, true); |
@@ -1251,23 +1250,13 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | |||
1251 | ret = snd_soc_register_codec(&i2c_client->dev, | 1250 | ret = snd_soc_register_codec(&i2c_client->dev, |
1252 | &soc_codec_dev_cs42l52, &cs42l52_dai, 1); | 1251 | &soc_codec_dev_cs42l52, &cs42l52_dai, 1); |
1253 | if (ret < 0) | 1252 | if (ret < 0) |
1254 | goto err_regmap; | 1253 | return ret; |
1255 | return 0; | 1254 | return 0; |
1256 | |||
1257 | err_regmap: | ||
1258 | regmap_exit(cs42l52->regmap); | ||
1259 | |||
1260 | err: | ||
1261 | return ret; | ||
1262 | } | 1255 | } |
1263 | 1256 | ||
1264 | static int cs42l52_i2c_remove(struct i2c_client *client) | 1257 | static int cs42l52_i2c_remove(struct i2c_client *client) |
1265 | { | 1258 | { |
1266 | struct cs42l52_private *cs42l52 = i2c_get_clientdata(client); | ||
1267 | |||
1268 | snd_soc_unregister_codec(&client->dev); | 1259 | snd_soc_unregister_codec(&client->dev); |
1269 | regmap_exit(cs42l52->regmap); | ||
1270 | |||
1271 | return 0; | 1260 | return 0; |
1272 | } | 1261 | } |
1273 | 1262 | ||
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index e0d45fdaa750..2c08c4cb465a 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1362,11 +1362,11 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1362 | 1362 | ||
1363 | i2c_set_clientdata(i2c_client, cs42l73); | 1363 | i2c_set_clientdata(i2c_client, cs42l73); |
1364 | 1364 | ||
1365 | cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap); | 1365 | cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); |
1366 | if (IS_ERR(cs42l73->regmap)) { | 1366 | if (IS_ERR(cs42l73->regmap)) { |
1367 | ret = PTR_ERR(cs42l73->regmap); | 1367 | ret = PTR_ERR(cs42l73->regmap); |
1368 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); | 1368 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); |
1369 | goto err; | 1369 | return ret; |
1370 | } | 1370 | } |
1371 | /* initialize codec */ | 1371 | /* initialize codec */ |
1372 | ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); | 1372 | ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); |
@@ -1384,13 +1384,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1384 | dev_err(&i2c_client->dev, | 1384 | dev_err(&i2c_client->dev, |
1385 | "CS42L73 Device ID (%X). Expected %X\n", | 1385 | "CS42L73 Device ID (%X). Expected %X\n", |
1386 | devid, CS42L73_DEVID); | 1386 | devid, CS42L73_DEVID); |
1387 | goto err_regmap; | 1387 | return ret; |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); | 1390 | ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); |
1391 | if (ret < 0) { | 1391 | if (ret < 0) { |
1392 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); | 1392 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); |
1393 | goto err_regmap; | 1393 | return ret;; |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | dev_info(&i2c_client->dev, | 1396 | dev_info(&i2c_client->dev, |
@@ -1402,23 +1402,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1402 | &soc_codec_dev_cs42l73, cs42l73_dai, | 1402 | &soc_codec_dev_cs42l73, cs42l73_dai, |
1403 | ARRAY_SIZE(cs42l73_dai)); | 1403 | ARRAY_SIZE(cs42l73_dai)); |
1404 | if (ret < 0) | 1404 | if (ret < 0) |
1405 | goto err_regmap; | 1405 | return ret; |
1406 | return 0; | 1406 | return 0; |
1407 | |||
1408 | err_regmap: | ||
1409 | regmap_exit(cs42l73->regmap); | ||
1410 | |||
1411 | err: | ||
1412 | return ret; | ||
1413 | } | 1407 | } |
1414 | 1408 | ||
1415 | static __devexit int cs42l73_i2c_remove(struct i2c_client *client) | 1409 | static __devexit int cs42l73_i2c_remove(struct i2c_client *client) |
1416 | { | 1410 | { |
1417 | struct cs42l73_private *cs42l73 = i2c_get_clientdata(client); | ||
1418 | |||
1419 | snd_soc_unregister_codec(&client->dev); | 1411 | snd_soc_unregister_codec(&client->dev); |
1420 | regmap_exit(cs42l73->regmap); | ||
1421 | |||
1422 | return 0; | 1412 | return 0; |
1423 | } | 1413 | } |
1424 | 1414 | ||
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c new file mode 100644 index 000000000000..04af369f228c --- /dev/null +++ b/sound/soc/codecs/da732x.c | |||
@@ -0,0 +1,1627 @@ | |||
1 | /* | ||
2 | * da732x.c --- Dialog DA732X ALSA SoC Audio Driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Dialog Semiconductor GmbH | ||
5 | * | ||
6 | * Author: Michal Hajduk <Michal.Hajduk@diasemi.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/regmap.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/sysfs.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/pcm_params.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/soc-dapm.h> | ||
28 | #include <sound/initval.h> | ||
29 | #include <sound/tlv.h> | ||
30 | #include <asm/div64.h> | ||
31 | |||
32 | #include "da732x.h" | ||
33 | #include "da732x_reg.h" | ||
34 | |||
35 | |||
36 | struct da732x_priv { | ||
37 | struct regmap *regmap; | ||
38 | struct snd_soc_codec *codec; | ||
39 | |||
40 | unsigned int sysclk; | ||
41 | bool pll_en; | ||
42 | }; | ||
43 | |||
44 | /* | ||
45 | * da732x register cache - default settings | ||
46 | */ | ||
47 | static struct reg_default da732x_reg_cache[] = { | ||
48 | { DA732X_REG_REF1 , 0x02 }, | ||
49 | { DA732X_REG_BIAS_EN , 0x80 }, | ||
50 | { DA732X_REG_BIAS1 , 0x00 }, | ||
51 | { DA732X_REG_BIAS2 , 0x00 }, | ||
52 | { DA732X_REG_BIAS3 , 0x00 }, | ||
53 | { DA732X_REG_BIAS4 , 0x00 }, | ||
54 | { DA732X_REG_MICBIAS2 , 0x00 }, | ||
55 | { DA732X_REG_MICBIAS1 , 0x00 }, | ||
56 | { DA732X_REG_MICDET , 0x00 }, | ||
57 | { DA732X_REG_MIC1_PRE , 0x01 }, | ||
58 | { DA732X_REG_MIC1 , 0x40 }, | ||
59 | { DA732X_REG_MIC2_PRE , 0x01 }, | ||
60 | { DA732X_REG_MIC2 , 0x40 }, | ||
61 | { DA732X_REG_AUX1L , 0x75 }, | ||
62 | { DA732X_REG_AUX1R , 0x75 }, | ||
63 | { DA732X_REG_MIC3_PRE , 0x01 }, | ||
64 | { DA732X_REG_MIC3 , 0x40 }, | ||
65 | { DA732X_REG_INP_PINBIAS , 0x00 }, | ||
66 | { DA732X_REG_INP_ZC_EN , 0x00 }, | ||
67 | { DA732X_REG_INP_MUX , 0x50 }, | ||
68 | { DA732X_REG_HP_DET , 0x00 }, | ||
69 | { DA732X_REG_HPL_DAC_OFFSET , 0x00 }, | ||
70 | { DA732X_REG_HPL_DAC_OFF_CNTL , 0x00 }, | ||
71 | { DA732X_REG_HPL_OUT_OFFSET , 0x00 }, | ||
72 | { DA732X_REG_HPL , 0x40 }, | ||
73 | { DA732X_REG_HPL_VOL , 0x0F }, | ||
74 | { DA732X_REG_HPR_DAC_OFFSET , 0x00 }, | ||
75 | { DA732X_REG_HPR_DAC_OFF_CNTL , 0x00 }, | ||
76 | { DA732X_REG_HPR_OUT_OFFSET , 0x00 }, | ||
77 | { DA732X_REG_HPR , 0x40 }, | ||
78 | { DA732X_REG_HPR_VOL , 0x0F }, | ||
79 | { DA732X_REG_LIN2 , 0x4F }, | ||
80 | { DA732X_REG_LIN3 , 0x4F }, | ||
81 | { DA732X_REG_LIN4 , 0x4F }, | ||
82 | { DA732X_REG_OUT_ZC_EN , 0x00 }, | ||
83 | { DA732X_REG_HP_LIN1_GNDSEL , 0x00 }, | ||
84 | { DA732X_REG_CP_HP1 , 0x0C }, | ||
85 | { DA732X_REG_CP_HP2 , 0x03 }, | ||
86 | { DA732X_REG_CP_CTRL1 , 0x00 }, | ||
87 | { DA732X_REG_CP_CTRL2 , 0x99 }, | ||
88 | { DA732X_REG_CP_CTRL3 , 0x25 }, | ||
89 | { DA732X_REG_CP_LEVEL_MASK , 0x3F }, | ||
90 | { DA732X_REG_CP_DET , 0x00 }, | ||
91 | { DA732X_REG_CP_STATUS , 0x00 }, | ||
92 | { DA732X_REG_CP_THRESH1 , 0x00 }, | ||
93 | { DA732X_REG_CP_THRESH2 , 0x00 }, | ||
94 | { DA732X_REG_CP_THRESH3 , 0x00 }, | ||
95 | { DA732X_REG_CP_THRESH4 , 0x00 }, | ||
96 | { DA732X_REG_CP_THRESH5 , 0x00 }, | ||
97 | { DA732X_REG_CP_THRESH6 , 0x00 }, | ||
98 | { DA732X_REG_CP_THRESH7 , 0x00 }, | ||
99 | { DA732X_REG_CP_THRESH8 , 0x00 }, | ||
100 | { DA732X_REG_PLL_DIV_LO , 0x00 }, | ||
101 | { DA732X_REG_PLL_DIV_MID , 0x00 }, | ||
102 | { DA732X_REG_PLL_DIV_HI , 0x00 }, | ||
103 | { DA732X_REG_PLL_CTRL , 0x02 }, | ||
104 | { DA732X_REG_CLK_CTRL , 0xaa }, | ||
105 | { DA732X_REG_CLK_DSP , 0x07 }, | ||
106 | { DA732X_REG_CLK_EN1 , 0x00 }, | ||
107 | { DA732X_REG_CLK_EN2 , 0x00 }, | ||
108 | { DA732X_REG_CLK_EN3 , 0x00 }, | ||
109 | { DA732X_REG_CLK_EN4 , 0x00 }, | ||
110 | { DA732X_REG_CLK_EN5 , 0x00 }, | ||
111 | { DA732X_REG_AIF_MCLK , 0x00 }, | ||
112 | { DA732X_REG_AIFA1 , 0x02 }, | ||
113 | { DA732X_REG_AIFA2 , 0x00 }, | ||
114 | { DA732X_REG_AIFA3 , 0x08 }, | ||
115 | { DA732X_REG_AIFB1 , 0x02 }, | ||
116 | { DA732X_REG_AIFB2 , 0x00 }, | ||
117 | { DA732X_REG_AIFB3 , 0x08 }, | ||
118 | { DA732X_REG_PC_CTRL , 0xC0 }, | ||
119 | { DA732X_REG_DATA_ROUTE , 0x00 }, | ||
120 | { DA732X_REG_DSP_CTRL , 0x00 }, | ||
121 | { DA732X_REG_CIF_CTRL2 , 0x00 }, | ||
122 | { DA732X_REG_HANDSHAKE , 0x00 }, | ||
123 | { DA732X_REG_SPARE1_OUT , 0x00 }, | ||
124 | { DA732X_REG_SPARE2_OUT , 0x00 }, | ||
125 | { DA732X_REG_SPARE1_IN , 0x00 }, | ||
126 | { DA732X_REG_ADC1_PD , 0x00 }, | ||
127 | { DA732X_REG_ADC1_HPF , 0x00 }, | ||
128 | { DA732X_REG_ADC1_SEL , 0x00 }, | ||
129 | { DA732X_REG_ADC1_EQ12 , 0x00 }, | ||
130 | { DA732X_REG_ADC1_EQ34 , 0x00 }, | ||
131 | { DA732X_REG_ADC1_EQ5 , 0x00 }, | ||
132 | { DA732X_REG_ADC2_PD , 0x00 }, | ||
133 | { DA732X_REG_ADC2_HPF , 0x00 }, | ||
134 | { DA732X_REG_ADC2_SEL , 0x00 }, | ||
135 | { DA732X_REG_ADC2_EQ12 , 0x00 }, | ||
136 | { DA732X_REG_ADC2_EQ34 , 0x00 }, | ||
137 | { DA732X_REG_ADC2_EQ5 , 0x00 }, | ||
138 | { DA732X_REG_DAC1_HPF , 0x00 }, | ||
139 | { DA732X_REG_DAC1_L_VOL , 0x00 }, | ||
140 | { DA732X_REG_DAC1_R_VOL , 0x00 }, | ||
141 | { DA732X_REG_DAC1_SEL , 0x00 }, | ||
142 | { DA732X_REG_DAC1_SOFTMUTE , 0x00 }, | ||
143 | { DA732X_REG_DAC1_EQ12 , 0x00 }, | ||
144 | { DA732X_REG_DAC1_EQ34 , 0x00 }, | ||
145 | { DA732X_REG_DAC1_EQ5 , 0x00 }, | ||
146 | { DA732X_REG_DAC2_HPF , 0x00 }, | ||
147 | { DA732X_REG_DAC2_L_VOL , 0x00 }, | ||
148 | { DA732X_REG_DAC2_R_VOL , 0x00 }, | ||
149 | { DA732X_REG_DAC2_SEL , 0x00 }, | ||
150 | { DA732X_REG_DAC2_SOFTMUTE , 0x00 }, | ||
151 | { DA732X_REG_DAC2_EQ12 , 0x00 }, | ||
152 | { DA732X_REG_DAC2_EQ34 , 0x00 }, | ||
153 | { DA732X_REG_DAC2_EQ5 , 0x00 }, | ||
154 | { DA732X_REG_DAC3_HPF , 0x00 }, | ||
155 | { DA732X_REG_DAC3_VOL , 0x00 }, | ||
156 | { DA732X_REG_DAC3_SEL , 0x00 }, | ||
157 | { DA732X_REG_DAC3_SOFTMUTE , 0x00 }, | ||
158 | { DA732X_REG_DAC3_EQ12 , 0x00 }, | ||
159 | { DA732X_REG_DAC3_EQ34 , 0x00 }, | ||
160 | { DA732X_REG_DAC3_EQ5 , 0x00 }, | ||
161 | { DA732X_REG_BIQ_BYP , 0x00 }, | ||
162 | { DA732X_REG_DMA_CMD , 0x00 }, | ||
163 | { DA732X_REG_DMA_ADDR0 , 0x00 }, | ||
164 | { DA732X_REG_DMA_ADDR1 , 0x00 }, | ||
165 | { DA732X_REG_DMA_DATA0 , 0x00 }, | ||
166 | { DA732X_REG_DMA_DATA1 , 0x00 }, | ||
167 | { DA732X_REG_DMA_DATA2 , 0x00 }, | ||
168 | { DA732X_REG_DMA_DATA3 , 0x00 }, | ||
169 | { DA732X_REG_UNLOCK , 0x00 }, | ||
170 | }; | ||
171 | |||
172 | static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk) | ||
173 | { | ||
174 | int val; | ||
175 | int ret; | ||
176 | |||
177 | if (sysclk < DA732X_MCLK_10MHZ) { | ||
178 | val = DA732X_MCLK_RET_0_10MHZ; | ||
179 | ret = DA732X_MCLK_VAL_0_10MHZ; | ||
180 | } else if ((sysclk >= DA732X_MCLK_10MHZ) && | ||
181 | (sysclk < DA732X_MCLK_20MHZ)) { | ||
182 | val = DA732X_MCLK_RET_10_20MHZ; | ||
183 | ret = DA732X_MCLK_VAL_10_20MHZ; | ||
184 | } else if ((sysclk >= DA732X_MCLK_20MHZ) && | ||
185 | (sysclk < DA732X_MCLK_40MHZ)) { | ||
186 | val = DA732X_MCLK_RET_20_40MHZ; | ||
187 | ret = DA732X_MCLK_VAL_20_40MHZ; | ||
188 | } else if ((sysclk >= DA732X_MCLK_40MHZ) && | ||
189 | (sysclk <= DA732X_MCLK_54MHZ)) { | ||
190 | val = DA732X_MCLK_RET_40_54MHZ; | ||
191 | ret = DA732X_MCLK_VAL_40_54MHZ; | ||
192 | } else { | ||
193 | return -EINVAL; | ||
194 | } | ||
195 | |||
196 | snd_soc_write(codec, DA732X_REG_PLL_CTRL, val); | ||
197 | |||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state) | ||
202 | { | ||
203 | switch (state) { | ||
204 | case DA732X_ENABLE_CP: | ||
205 | snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN); | ||
206 | snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN | | ||
207 | DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP); | ||
208 | snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN | | ||
209 | DA732X_CP_CTRL_CPVDD1); | ||
210 | snd_soc_write(codec, DA732X_REG_CP_CTRL2, | ||
211 | DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST); | ||
212 | snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ); | ||
213 | break; | ||
214 | case DA732X_DISABLE_CP: | ||
215 | snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS); | ||
216 | snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS); | ||
217 | snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS); | ||
218 | break; | ||
219 | default: | ||
220 | pr_err(KERN_ERR "Wrong charge pump state\n"); | ||
221 | break; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN, | ||
226 | DA732X_MIC_PRE_VOL_DB_INC, 0); | ||
227 | |||
228 | static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN, | ||
229 | DA732X_MIC_VOL_DB_INC, 0); | ||
230 | |||
231 | static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN, | ||
232 | DA732X_AUX_VOL_DB_INC, 0); | ||
233 | |||
234 | static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN, | ||
235 | DA732X_AUX_VOL_DB_INC, 0); | ||
236 | |||
237 | static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN, | ||
238 | DA732X_LIN2_VOL_DB_INC, 0); | ||
239 | |||
240 | static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN, | ||
241 | DA732X_LIN3_VOL_DB_INC, 0); | ||
242 | |||
243 | static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN, | ||
244 | DA732X_LIN4_VOL_DB_INC, 0); | ||
245 | |||
246 | static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN, | ||
247 | DA732X_ADC_VOL_DB_INC, 0); | ||
248 | |||
249 | static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN, | ||
250 | DA732X_DAC_VOL_DB_INC, 0); | ||
251 | |||
252 | static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN, | ||
253 | DA732X_EQ_BAND_VOL_DB_INC, 0); | ||
254 | |||
255 | static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN, | ||
256 | DA732X_EQ_OVERALL_VOL_DB_INC, 0); | ||
257 | |||
258 | /* High Pass Filter */ | ||
259 | static const char *da732x_hpf_mode[] = { | ||
260 | "Disable", "Music", "Voice", | ||
261 | }; | ||
262 | |||
263 | static const char *da732x_hpf_music[] = { | ||
264 | "1.8Hz", "3.75Hz", "7.5Hz", "15Hz", | ||
265 | }; | ||
266 | |||
267 | static const char *da732x_hpf_voice[] = { | ||
268 | "2.5Hz", "25Hz", "50Hz", "100Hz", | ||
269 | "150Hz", "200Hz", "300Hz", "400Hz" | ||
270 | }; | ||
271 | |||
272 | static const struct soc_enum da732x_dac1_hpf_mode_enum[] = { | ||
273 | SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT, | ||
274 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | ||
275 | }; | ||
276 | |||
277 | static const struct soc_enum da732x_dac2_hpf_mode_enum[] = { | ||
278 | SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT, | ||
279 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | ||
280 | }; | ||
281 | |||
282 | static const struct soc_enum da732x_dac3_hpf_mode_enum[] = { | ||
283 | SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT, | ||
284 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | ||
285 | }; | ||
286 | |||
287 | static const struct soc_enum da732x_adc1_hpf_mode_enum[] = { | ||
288 | SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT, | ||
289 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | ||
290 | }; | ||
291 | |||
292 | static const struct soc_enum da732x_adc2_hpf_mode_enum[] = { | ||
293 | SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT, | ||
294 | DA732X_HPF_MODE_MAX, da732x_hpf_mode) | ||
295 | }; | ||
296 | |||
297 | static const struct soc_enum da732x_dac1_hp_filter_enum[] = { | ||
298 | SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT, | ||
299 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | ||
300 | }; | ||
301 | |||
302 | static const struct soc_enum da732x_dac2_hp_filter_enum[] = { | ||
303 | SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT, | ||
304 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | ||
305 | }; | ||
306 | |||
307 | static const struct soc_enum da732x_dac3_hp_filter_enum[] = { | ||
308 | SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT, | ||
309 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | ||
310 | }; | ||
311 | |||
312 | static const struct soc_enum da732x_adc1_hp_filter_enum[] = { | ||
313 | SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT, | ||
314 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | ||
315 | }; | ||
316 | |||
317 | static const struct soc_enum da732x_adc2_hp_filter_enum[] = { | ||
318 | SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT, | ||
319 | DA732X_HPF_MUSIC_MAX, da732x_hpf_music) | ||
320 | }; | ||
321 | |||
322 | static const struct soc_enum da732x_dac1_voice_filter_enum[] = { | ||
323 | SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT, | ||
324 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | ||
325 | }; | ||
326 | |||
327 | static const struct soc_enum da732x_dac2_voice_filter_enum[] = { | ||
328 | SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT, | ||
329 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | ||
330 | }; | ||
331 | |||
332 | static const struct soc_enum da732x_dac3_voice_filter_enum[] = { | ||
333 | SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT, | ||
334 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | ||
335 | }; | ||
336 | |||
337 | static const struct soc_enum da732x_adc1_voice_filter_enum[] = { | ||
338 | SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT, | ||
339 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | ||
340 | }; | ||
341 | |||
342 | static const struct soc_enum da732x_adc2_voice_filter_enum[] = { | ||
343 | SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT, | ||
344 | DA732X_HPF_VOICE_MAX, da732x_hpf_voice) | ||
345 | }; | ||
346 | |||
347 | |||
348 | static int da732x_hpf_set(struct snd_kcontrol *kcontrol, | ||
349 | struct snd_ctl_elem_value *ucontrol) | ||
350 | { | ||
351 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
352 | struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; | ||
353 | unsigned int reg = enum_ctrl->reg; | ||
354 | unsigned int sel = ucontrol->value.integer.value[0]; | ||
355 | unsigned int bits; | ||
356 | |||
357 | switch (sel) { | ||
358 | case DA732X_HPF_DISABLED: | ||
359 | bits = DA732X_HPF_DIS; | ||
360 | break; | ||
361 | case DA732X_HPF_VOICE: | ||
362 | bits = DA732X_HPF_VOICE_EN; | ||
363 | break; | ||
364 | case DA732X_HPF_MUSIC: | ||
365 | bits = DA732X_HPF_MUSIC_EN; | ||
366 | break; | ||
367 | default: | ||
368 | return -EINVAL; | ||
369 | } | ||
370 | |||
371 | snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int da732x_hpf_get(struct snd_kcontrol *kcontrol, | ||
377 | struct snd_ctl_elem_value *ucontrol) | ||
378 | { | ||
379 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
380 | struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; | ||
381 | unsigned int reg = enum_ctrl->reg; | ||
382 | int val; | ||
383 | |||
384 | val = snd_soc_read(codec, reg) & DA732X_HPF_MASK; | ||
385 | |||
386 | switch (val) { | ||
387 | case DA732X_HPF_VOICE_EN: | ||
388 | ucontrol->value.integer.value[0] = DA732X_HPF_VOICE; | ||
389 | break; | ||
390 | case DA732X_HPF_MUSIC_EN: | ||
391 | ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC; | ||
392 | break; | ||
393 | default: | ||
394 | ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED; | ||
395 | break; | ||
396 | } | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static const struct snd_kcontrol_new da732x_snd_controls[] = { | ||
402 | /* Input PGAs */ | ||
403 | SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE, | ||
404 | DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, | ||
405 | DA732X_MICBOOST_MAX, 0, mic_boost_tlv), | ||
406 | SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE, | ||
407 | DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, | ||
408 | DA732X_MICBOOST_MAX, 0, mic_boost_tlv), | ||
409 | SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE, | ||
410 | DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN, | ||
411 | DA732X_MICBOOST_MAX, 0, mic_boost_tlv), | ||
412 | |||
413 | /* MICs */ | ||
414 | SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT, | ||
415 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
416 | SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1, | ||
417 | DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, | ||
418 | DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), | ||
419 | SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT, | ||
420 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
421 | SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2, | ||
422 | DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, | ||
423 | DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), | ||
424 | SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT, | ||
425 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
426 | SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3, | ||
427 | DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN, | ||
428 | DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv), | ||
429 | |||
430 | /* AUXs */ | ||
431 | SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT, | ||
432 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
433 | SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L, | ||
434 | DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, | ||
435 | DA732X_NO_INVERT, aux_pga_tlv), | ||
436 | SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT, | ||
437 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
438 | SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R, | ||
439 | DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX, | ||
440 | DA732X_NO_INVERT, aux_pga_tlv), | ||
441 | |||
442 | /* ADCs */ | ||
443 | SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL, | ||
444 | DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, | ||
445 | DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), | ||
446 | |||
447 | SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL, | ||
448 | DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT, | ||
449 | DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv), | ||
450 | |||
451 | /* DACs */ | ||
452 | SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL, | ||
453 | DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT, | ||
454 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
455 | SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL, | ||
456 | DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT, | ||
457 | DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv), | ||
458 | SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL, | ||
459 | DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), | ||
460 | SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL, | ||
461 | DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, | ||
462 | DA732X_INVERT, dac_pga_tlv), | ||
463 | SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL, | ||
464 | DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), | ||
465 | SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL, | ||
466 | DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, | ||
467 | DA732X_INVERT, dac_pga_tlv), | ||
468 | SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL, | ||
469 | DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), | ||
470 | SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL, | ||
471 | DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX, | ||
472 | DA732X_INVERT, dac_pga_tlv), | ||
473 | |||
474 | /* High Pass Filters */ | ||
475 | SOC_ENUM_EXT("DAC1 High Pass Filter Mode", | ||
476 | da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), | ||
477 | SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum), | ||
478 | SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum), | ||
479 | |||
480 | SOC_ENUM_EXT("DAC2 High Pass Filter Mode", | ||
481 | da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), | ||
482 | SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum), | ||
483 | SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum), | ||
484 | |||
485 | SOC_ENUM_EXT("DAC3 High Pass Filter Mode", | ||
486 | da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), | ||
487 | SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum), | ||
488 | SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum), | ||
489 | |||
490 | SOC_ENUM_EXT("ADC1 High Pass Filter Mode", | ||
491 | da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), | ||
492 | SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum), | ||
493 | SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum), | ||
494 | |||
495 | SOC_ENUM_EXT("ADC2 High Pass Filter Mode", | ||
496 | da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set), | ||
497 | SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum), | ||
498 | SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum), | ||
499 | |||
500 | /* Equalizers */ | ||
501 | SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5, | ||
502 | DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), | ||
503 | SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12, | ||
504 | DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
505 | DA732X_INVERT, eq_band_pga_tlv), | ||
506 | SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12, | ||
507 | DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
508 | DA732X_INVERT, eq_band_pga_tlv), | ||
509 | SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34, | ||
510 | DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
511 | DA732X_INVERT, eq_band_pga_tlv), | ||
512 | SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34, | ||
513 | DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
514 | DA732X_INVERT, eq_band_pga_tlv), | ||
515 | SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5, | ||
516 | DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
517 | DA732X_INVERT, eq_band_pga_tlv), | ||
518 | SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5, | ||
519 | DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, | ||
520 | DA732X_INVERT, eq_overall_tlv), | ||
521 | |||
522 | SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5, | ||
523 | DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), | ||
524 | SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12, | ||
525 | DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
526 | DA732X_INVERT, eq_band_pga_tlv), | ||
527 | SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12, | ||
528 | DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
529 | DA732X_INVERT, eq_band_pga_tlv), | ||
530 | SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34, | ||
531 | DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
532 | DA732X_INVERT, eq_band_pga_tlv), | ||
533 | SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34, | ||
534 | DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
535 | DA732X_INVERT, eq_band_pga_tlv), | ||
536 | SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5, | ||
537 | DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
538 | DA732X_INVERT, eq_band_pga_tlv), | ||
539 | SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5, | ||
540 | DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX, | ||
541 | DA732X_INVERT, eq_overall_tlv), | ||
542 | |||
543 | SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5, | ||
544 | DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), | ||
545 | SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12, | ||
546 | DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
547 | DA732X_INVERT, eq_band_pga_tlv), | ||
548 | SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12, | ||
549 | DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
550 | DA732X_INVERT, eq_band_pga_tlv), | ||
551 | SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34, | ||
552 | DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
553 | DA732X_INVERT, eq_band_pga_tlv), | ||
554 | SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34, | ||
555 | DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
556 | DA732X_INVERT, eq_band_pga_tlv), | ||
557 | SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5, | ||
558 | DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
559 | DA732X_INVERT, eq_band_pga_tlv), | ||
560 | |||
561 | SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5, | ||
562 | DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), | ||
563 | SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12, | ||
564 | DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
565 | DA732X_INVERT, eq_band_pga_tlv), | ||
566 | SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12, | ||
567 | DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
568 | DA732X_INVERT, eq_band_pga_tlv), | ||
569 | SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34, | ||
570 | DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
571 | DA732X_INVERT, eq_band_pga_tlv), | ||
572 | SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34, | ||
573 | DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
574 | DA732X_INVERT, eq_band_pga_tlv), | ||
575 | SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5, | ||
576 | DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
577 | DA732X_INVERT, eq_band_pga_tlv), | ||
578 | |||
579 | SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5, | ||
580 | DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT), | ||
581 | SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12, | ||
582 | DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
583 | DA732X_INVERT, eq_band_pga_tlv), | ||
584 | SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12, | ||
585 | DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
586 | DA732X_INVERT, eq_band_pga_tlv), | ||
587 | SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34, | ||
588 | DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
589 | DA732X_INVERT, eq_band_pga_tlv), | ||
590 | SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34, | ||
591 | DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
592 | DA732X_INVERT, eq_band_pga_tlv), | ||
593 | SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5, | ||
594 | DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX, | ||
595 | DA732X_INVERT, eq_band_pga_tlv), | ||
596 | |||
597 | /* Lineout 2 Reciever*/ | ||
598 | SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT, | ||
599 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
600 | SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2, | ||
601 | DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, | ||
602 | DA732X_NO_INVERT, lin2_pga_tlv), | ||
603 | |||
604 | /* Lineout 3 SPEAKER*/ | ||
605 | SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT, | ||
606 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
607 | SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3, | ||
608 | DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, | ||
609 | DA732X_NO_INVERT, lin3_pga_tlv), | ||
610 | |||
611 | /* Lineout 4 */ | ||
612 | SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT, | ||
613 | DA732X_SWITCH_MAX, DA732X_INVERT), | ||
614 | SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4, | ||
615 | DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX, | ||
616 | DA732X_NO_INVERT, lin4_pga_tlv), | ||
617 | |||
618 | /* Headphones */ | ||
619 | SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL, | ||
620 | DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT), | ||
621 | SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL, | ||
622 | DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT, | ||
623 | DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv), | ||
624 | }; | ||
625 | |||
626 | static int da732x_adc_event(struct snd_soc_dapm_widget *w, | ||
627 | struct snd_kcontrol *kcontrol, int event) | ||
628 | { | ||
629 | struct snd_soc_codec *codec = w->codec; | ||
630 | |||
631 | switch (event) { | ||
632 | case SND_SOC_DAPM_POST_PMU: | ||
633 | switch (w->reg) { | ||
634 | case DA732X_REG_ADC1_PD: | ||
635 | snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, | ||
636 | DA732X_ADCA_BB_CLK_EN, | ||
637 | DA732X_ADCA_BB_CLK_EN); | ||
638 | break; | ||
639 | case DA732X_REG_ADC2_PD: | ||
640 | snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, | ||
641 | DA732X_ADCC_BB_CLK_EN, | ||
642 | DA732X_ADCC_BB_CLK_EN); | ||
643 | break; | ||
644 | default: | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | |||
648 | snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, | ||
649 | DA732X_ADC_SET_ACT); | ||
650 | snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, | ||
651 | DA732X_ADC_ON); | ||
652 | break; | ||
653 | case SND_SOC_DAPM_POST_PMD: | ||
654 | snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK, | ||
655 | DA732X_ADC_OFF); | ||
656 | snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK, | ||
657 | DA732X_ADC_SET_RST); | ||
658 | |||
659 | switch (w->reg) { | ||
660 | case DA732X_REG_ADC1_PD: | ||
661 | snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, | ||
662 | DA732X_ADCA_BB_CLK_EN, 0); | ||
663 | break; | ||
664 | case DA732X_REG_ADC2_PD: | ||
665 | snd_soc_update_bits(codec, DA732X_REG_CLK_EN3, | ||
666 | DA732X_ADCC_BB_CLK_EN, 0); | ||
667 | break; | ||
668 | default: | ||
669 | return -EINVAL; | ||
670 | } | ||
671 | |||
672 | break; | ||
673 | default: | ||
674 | return -EINVAL; | ||
675 | } | ||
676 | |||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | static int da732x_out_pga_event(struct snd_soc_dapm_widget *w, | ||
681 | struct snd_kcontrol *kcontrol, int event) | ||
682 | { | ||
683 | struct snd_soc_codec *codec = w->codec; | ||
684 | |||
685 | switch (event) { | ||
686 | case SND_SOC_DAPM_POST_PMU: | ||
687 | snd_soc_update_bits(codec, w->reg, | ||
688 | (1 << w->shift) | DA732X_OUT_HIZ_EN, | ||
689 | (1 << w->shift) | DA732X_OUT_HIZ_EN); | ||
690 | break; | ||
691 | case SND_SOC_DAPM_POST_PMD: | ||
692 | snd_soc_update_bits(codec, w->reg, | ||
693 | (1 << w->shift) | DA732X_OUT_HIZ_EN, | ||
694 | (1 << w->shift) | DA732X_OUT_HIZ_DIS); | ||
695 | break; | ||
696 | default: | ||
697 | return -EINVAL; | ||
698 | } | ||
699 | |||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static const char *adcl_text[] = { | ||
704 | "AUX1L", "MIC1" | ||
705 | }; | ||
706 | |||
707 | static const char *adcr_text[] = { | ||
708 | "AUX1R", "MIC2", "MIC3" | ||
709 | }; | ||
710 | |||
711 | static const char *enable_text[] = { | ||
712 | "Disabled", | ||
713 | "Enabled" | ||
714 | }; | ||
715 | |||
716 | /* ADC1LMUX */ | ||
717 | static const struct soc_enum adc1l_enum = | ||
718 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT, | ||
719 | DA732X_ADCL_MUX_MAX, adcl_text); | ||
720 | static const struct snd_kcontrol_new adc1l_mux = | ||
721 | SOC_DAPM_ENUM("ADC Route", adc1l_enum); | ||
722 | |||
723 | /* ADC1RMUX */ | ||
724 | static const struct soc_enum adc1r_enum = | ||
725 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT, | ||
726 | DA732X_ADCR_MUX_MAX, adcr_text); | ||
727 | static const struct snd_kcontrol_new adc1r_mux = | ||
728 | SOC_DAPM_ENUM("ADC Route", adc1r_enum); | ||
729 | |||
730 | /* ADC2LMUX */ | ||
731 | static const struct soc_enum adc2l_enum = | ||
732 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT, | ||
733 | DA732X_ADCL_MUX_MAX, adcl_text); | ||
734 | static const struct snd_kcontrol_new adc2l_mux = | ||
735 | SOC_DAPM_ENUM("ADC Route", adc2l_enum); | ||
736 | |||
737 | /* ADC2RMUX */ | ||
738 | static const struct soc_enum adc2r_enum = | ||
739 | SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT, | ||
740 | DA732X_ADCR_MUX_MAX, adcr_text); | ||
741 | |||
742 | static const struct snd_kcontrol_new adc2r_mux = | ||
743 | SOC_DAPM_ENUM("ADC Route", adc2r_enum); | ||
744 | |||
745 | static const struct soc_enum da732x_hp_left_output = | ||
746 | SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT, | ||
747 | DA732X_DAC_EN_MAX, enable_text); | ||
748 | |||
749 | static const struct snd_kcontrol_new hpl_mux = | ||
750 | SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output); | ||
751 | |||
752 | static const struct soc_enum da732x_hp_right_output = | ||
753 | SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT, | ||
754 | DA732X_DAC_EN_MAX, enable_text); | ||
755 | |||
756 | static const struct snd_kcontrol_new hpr_mux = | ||
757 | SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output); | ||
758 | |||
759 | static const struct soc_enum da732x_speaker_output = | ||
760 | SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT, | ||
761 | DA732X_DAC_EN_MAX, enable_text); | ||
762 | |||
763 | static const struct snd_kcontrol_new spk_mux = | ||
764 | SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output); | ||
765 | |||
766 | static const struct soc_enum da732x_lout4_output = | ||
767 | SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT, | ||
768 | DA732X_DAC_EN_MAX, enable_text); | ||
769 | |||
770 | static const struct snd_kcontrol_new lout4_mux = | ||
771 | SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output); | ||
772 | |||
773 | static const struct soc_enum da732x_lout2_output = | ||
774 | SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT, | ||
775 | DA732X_DAC_EN_MAX, enable_text); | ||
776 | |||
777 | static const struct snd_kcontrol_new lout2_mux = | ||
778 | SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output); | ||
779 | |||
780 | static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = { | ||
781 | /* Supplies */ | ||
782 | SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0, | ||
783 | DA732X_NO_INVERT, da732x_adc_event, | ||
784 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
785 | SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0, | ||
786 | DA732X_NO_INVERT, da732x_adc_event, | ||
787 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
788 | SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4, | ||
789 | DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT, | ||
790 | NULL, 0), | ||
791 | SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4, | ||
792 | DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT, | ||
793 | NULL, 0), | ||
794 | SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5, | ||
795 | DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT, | ||
796 | NULL, 0), | ||
797 | |||
798 | /* Micbias */ | ||
799 | SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1, | ||
800 | DA732X_MICBIAS_EN_SHIFT, | ||
801 | DA732X_NO_INVERT, NULL, 0), | ||
802 | SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2, | ||
803 | DA732X_MICBIAS_EN_SHIFT, | ||
804 | DA732X_NO_INVERT, NULL, 0), | ||
805 | |||
806 | /* Inputs */ | ||
807 | SND_SOC_DAPM_INPUT("MIC1"), | ||
808 | SND_SOC_DAPM_INPUT("MIC2"), | ||
809 | SND_SOC_DAPM_INPUT("MIC3"), | ||
810 | SND_SOC_DAPM_INPUT("AUX1L"), | ||
811 | SND_SOC_DAPM_INPUT("AUX1R"), | ||
812 | |||
813 | /* Outputs */ | ||
814 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
815 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
816 | SND_SOC_DAPM_OUTPUT("LOUTL"), | ||
817 | SND_SOC_DAPM_OUTPUT("LOUTR"), | ||
818 | SND_SOC_DAPM_OUTPUT("ClassD"), | ||
819 | |||
820 | /* ADCs */ | ||
821 | SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL, | ||
822 | DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), | ||
823 | SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL, | ||
824 | DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), | ||
825 | SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL, | ||
826 | DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT), | ||
827 | SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL, | ||
828 | DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT), | ||
829 | |||
830 | /* DACs */ | ||
831 | SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL, | ||
832 | DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), | ||
833 | SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL, | ||
834 | DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), | ||
835 | SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL, | ||
836 | DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), | ||
837 | SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL, | ||
838 | DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT), | ||
839 | SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL, | ||
840 | DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT), | ||
841 | |||
842 | /* Input Pgas */ | ||
843 | SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT, | ||
844 | 0, NULL, 0), | ||
845 | SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT, | ||
846 | 0, NULL, 0), | ||
847 | SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT, | ||
848 | 0, NULL, 0), | ||
849 | SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT, | ||
850 | 0, NULL, 0), | ||
851 | SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT, | ||
852 | 0, NULL, 0), | ||
853 | |||
854 | SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT, | ||
855 | 0, NULL, 0, da732x_out_pga_event, | ||
856 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
857 | SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT, | ||
858 | 0, NULL, 0, da732x_out_pga_event, | ||
859 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
860 | SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT, | ||
861 | 0, NULL, 0, da732x_out_pga_event, | ||
862 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
863 | SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT, | ||
864 | 0, NULL, 0, da732x_out_pga_event, | ||
865 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
866 | SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT, | ||
867 | 0, NULL, 0, da732x_out_pga_event, | ||
868 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
869 | |||
870 | /* MUXs */ | ||
871 | SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux), | ||
872 | SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux), | ||
873 | SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux), | ||
874 | SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux), | ||
875 | |||
876 | SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux), | ||
877 | SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux), | ||
878 | SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux), | ||
879 | SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux), | ||
880 | SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux), | ||
881 | |||
882 | /* AIF interfaces */ | ||
883 | SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3, | ||
884 | DA732X_AIF_EN_SHIFT, 0), | ||
885 | SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3, | ||
886 | DA732X_AIF_EN_SHIFT, 0), | ||
887 | |||
888 | SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3, | ||
889 | DA732X_AIF_EN_SHIFT, 0), | ||
890 | SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3, | ||
891 | DA732X_AIF_EN_SHIFT, 0), | ||
892 | }; | ||
893 | |||
894 | static const struct snd_soc_dapm_route da732x_dapm_routes[] = { | ||
895 | /* Inputs */ | ||
896 | {"AUX1L PGA", "NULL", "AUX1L"}, | ||
897 | {"AUX1R PGA", "NULL", "AUX1R"}, | ||
898 | {"MIC1 PGA", NULL, "MIC1"}, | ||
899 | {"MIC2 PGA", "NULL", "MIC2"}, | ||
900 | {"MIC3 PGA", "NULL", "MIC3"}, | ||
901 | |||
902 | /* Capture Path */ | ||
903 | {"ADC1 Left MUX", "MIC1", "MIC1 PGA"}, | ||
904 | {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"}, | ||
905 | |||
906 | {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"}, | ||
907 | {"ADC1 Right MUX", "MIC2", "MIC2 PGA"}, | ||
908 | {"ADC1 Right MUX", "MIC3", "MIC3 PGA"}, | ||
909 | |||
910 | {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"}, | ||
911 | {"ADC2 Left MUX", "MIC1", "MIC1 PGA"}, | ||
912 | |||
913 | {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"}, | ||
914 | {"ADC2 Right MUX", "MIC2", "MIC2 PGA"}, | ||
915 | {"ADC2 Right MUX", "MIC3", "MIC3 PGA"}, | ||
916 | |||
917 | {"ADC1L", NULL, "ADC1 Supply"}, | ||
918 | {"ADC1R", NULL, "ADC1 Supply"}, | ||
919 | {"ADC2L", NULL, "ADC2 Supply"}, | ||
920 | {"ADC2R", NULL, "ADC2 Supply"}, | ||
921 | |||
922 | {"ADC1L", NULL, "ADC1 Left MUX"}, | ||
923 | {"ADC1R", NULL, "ADC1 Right MUX"}, | ||
924 | {"ADC2L", NULL, "ADC2 Left MUX"}, | ||
925 | {"ADC2R", NULL, "ADC2 Right MUX"}, | ||
926 | |||
927 | {"AIFA Output", NULL, "ADC1L"}, | ||
928 | {"AIFA Output", NULL, "ADC1R"}, | ||
929 | {"AIFB Output", NULL, "ADC2L"}, | ||
930 | {"AIFB Output", NULL, "ADC2R"}, | ||
931 | |||
932 | {"HP Left MUX", "Enabled", "AIFA Input"}, | ||
933 | {"HP Right MUX", "Enabled", "AIFA Input"}, | ||
934 | {"Speaker MUX", "Enabled", "AIFB Input"}, | ||
935 | {"LOUT2 MUX", "Enabled", "AIFB Input"}, | ||
936 | {"LOUT4 MUX", "Enabled", "AIFB Input"}, | ||
937 | |||
938 | {"DAC1L", NULL, "DAC1 CLK"}, | ||
939 | {"DAC1R", NULL, "DAC1 CLK"}, | ||
940 | {"DAC2L", NULL, "DAC2 CLK"}, | ||
941 | {"DAC2R", NULL, "DAC2 CLK"}, | ||
942 | {"DAC3", NULL, "DAC3 CLK"}, | ||
943 | |||
944 | {"DAC1L", NULL, "HP Left MUX"}, | ||
945 | {"DAC1R", NULL, "HP Right MUX"}, | ||
946 | {"DAC2L", NULL, "Speaker MUX"}, | ||
947 | {"DAC2R", NULL, "LOUT4 MUX"}, | ||
948 | {"DAC3", NULL, "LOUT2 MUX"}, | ||
949 | |||
950 | /* Output Pgas */ | ||
951 | {"HP Left", NULL, "DAC1L"}, | ||
952 | {"HP Right", NULL, "DAC1R"}, | ||
953 | {"LIN3", NULL, "DAC2L"}, | ||
954 | {"LIN4", NULL, "DAC2R"}, | ||
955 | {"LIN2", NULL, "DAC3"}, | ||
956 | |||
957 | /* Outputs */ | ||
958 | {"ClassD", NULL, "LIN3"}, | ||
959 | {"LOUTL", NULL, "LIN2"}, | ||
960 | {"LOUTR", NULL, "LIN4"}, | ||
961 | {"HPL", NULL, "HP Left"}, | ||
962 | {"HPR", NULL, "HP Right"}, | ||
963 | }; | ||
964 | |||
965 | static int da732x_hw_params(struct snd_pcm_substream *substream, | ||
966 | struct snd_pcm_hw_params *params, | ||
967 | struct snd_soc_dai *dai) | ||
968 | { | ||
969 | struct snd_soc_codec *codec = dai->codec; | ||
970 | u32 aif = 0; | ||
971 | u32 reg_aif; | ||
972 | u32 fs; | ||
973 | |||
974 | reg_aif = dai->driver->base; | ||
975 | |||
976 | switch (params_format(params)) { | ||
977 | case SNDRV_PCM_FORMAT_S16_LE: | ||
978 | aif |= DA732X_AIF_WORD_16; | ||
979 | break; | ||
980 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
981 | aif |= DA732X_AIF_WORD_20; | ||
982 | break; | ||
983 | case SNDRV_PCM_FORMAT_S24_LE: | ||
984 | aif |= DA732X_AIF_WORD_24; | ||
985 | break; | ||
986 | case SNDRV_PCM_FORMAT_S32_LE: | ||
987 | aif |= DA732X_AIF_WORD_32; | ||
988 | break; | ||
989 | default: | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | |||
993 | switch (params_rate(params)) { | ||
994 | case 8000: | ||
995 | fs = DA732X_SR_8KHZ; | ||
996 | break; | ||
997 | case 11025: | ||
998 | fs = DA732X_SR_11_025KHZ; | ||
999 | break; | ||
1000 | case 12000: | ||
1001 | fs = DA732X_SR_12KHZ; | ||
1002 | break; | ||
1003 | case 16000: | ||
1004 | fs = DA732X_SR_16KHZ; | ||
1005 | break; | ||
1006 | case 22050: | ||
1007 | fs = DA732X_SR_22_05KHZ; | ||
1008 | break; | ||
1009 | case 24000: | ||
1010 | fs = DA732X_SR_24KHZ; | ||
1011 | break; | ||
1012 | case 32000: | ||
1013 | fs = DA732X_SR_32KHZ; | ||
1014 | break; | ||
1015 | case 44100: | ||
1016 | fs = DA732X_SR_44_1KHZ; | ||
1017 | break; | ||
1018 | case 48000: | ||
1019 | fs = DA732X_SR_48KHZ; | ||
1020 | break; | ||
1021 | case 88100: | ||
1022 | fs = DA732X_SR_88_1KHZ; | ||
1023 | break; | ||
1024 | case 96000: | ||
1025 | fs = DA732X_SR_96KHZ; | ||
1026 | break; | ||
1027 | default: | ||
1028 | return -EINVAL; | ||
1029 | } | ||
1030 | |||
1031 | snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif); | ||
1032 | snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs); | ||
1033 | |||
1034 | return 0; | ||
1035 | } | ||
1036 | |||
1037 | static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt) | ||
1038 | { | ||
1039 | struct snd_soc_codec *codec = dai->codec; | ||
1040 | u32 aif_mclk, pc_count; | ||
1041 | u32 reg_aif1, aif1; | ||
1042 | u32 reg_aif3, aif3; | ||
1043 | |||
1044 | switch (dai->id) { | ||
1045 | case DA732X_DAI_ID1: | ||
1046 | reg_aif1 = DA732X_REG_AIFA1; | ||
1047 | reg_aif3 = DA732X_REG_AIFA3; | ||
1048 | pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT | | ||
1049 | DA732X_PC_SAME; | ||
1050 | break; | ||
1051 | case DA732X_DAI_ID2: | ||
1052 | reg_aif1 = DA732X_REG_AIFB1; | ||
1053 | reg_aif3 = DA732X_REG_AIFB3; | ||
1054 | pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT | | ||
1055 | DA732X_PC_SAME; | ||
1056 | break; | ||
1057 | default: | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1060 | |||
1061 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1062 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1063 | aif1 = DA732X_AIF_SLAVE; | ||
1064 | aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA; | ||
1065 | break; | ||
1066 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1067 | aif1 = DA732X_AIF_CLK_FROM_SRC; | ||
1068 | aif_mclk = DA732X_CLK_GENERATION_AIF_A; | ||
1069 | break; | ||
1070 | default: | ||
1071 | return -EINVAL; | ||
1072 | } | ||
1073 | |||
1074 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1075 | case SND_SOC_DAIFMT_I2S: | ||
1076 | aif3 = DA732X_AIF_I2S_MODE; | ||
1077 | break; | ||
1078 | case SND_SOC_DAIFMT_RIGHT_J: | ||
1079 | aif3 = DA732X_AIF_RIGHT_J_MODE; | ||
1080 | break; | ||
1081 | case SND_SOC_DAIFMT_LEFT_J: | ||
1082 | aif3 = DA732X_AIF_LEFT_J_MODE; | ||
1083 | break; | ||
1084 | case SND_SOC_DAIFMT_DSP_B: | ||
1085 | aif3 = DA732X_AIF_DSP_MODE; | ||
1086 | break; | ||
1087 | default: | ||
1088 | return -EINVAL; | ||
1089 | } | ||
1090 | |||
1091 | /* Clock inversion */ | ||
1092 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1093 | case SND_SOC_DAIFMT_DSP_B: | ||
1094 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1095 | case SND_SOC_DAIFMT_NB_NF: | ||
1096 | break; | ||
1097 | case SND_SOC_DAIFMT_IB_NF: | ||
1098 | aif3 |= DA732X_AIF_BCLK_INV; | ||
1099 | break; | ||
1100 | default: | ||
1101 | return -EINVAL; | ||
1102 | } | ||
1103 | break; | ||
1104 | case SND_SOC_DAIFMT_I2S: | ||
1105 | case SND_SOC_DAIFMT_RIGHT_J: | ||
1106 | case SND_SOC_DAIFMT_LEFT_J: | ||
1107 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1108 | case SND_SOC_DAIFMT_NB_NF: | ||
1109 | break; | ||
1110 | case SND_SOC_DAIFMT_IB_IF: | ||
1111 | aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV; | ||
1112 | break; | ||
1113 | case SND_SOC_DAIFMT_IB_NF: | ||
1114 | aif3 |= DA732X_AIF_BCLK_INV; | ||
1115 | break; | ||
1116 | case SND_SOC_DAIFMT_NB_IF: | ||
1117 | aif3 |= DA732X_AIF_WCLK_INV; | ||
1118 | break; | ||
1119 | default: | ||
1120 | return -EINVAL; | ||
1121 | } | ||
1122 | break; | ||
1123 | default: | ||
1124 | return -EINVAL; | ||
1125 | } | ||
1126 | |||
1127 | snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk); | ||
1128 | snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1); | ||
1129 | snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV | | ||
1130 | DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3); | ||
1131 | snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count); | ||
1132 | |||
1133 | return 0; | ||
1134 | } | ||
1135 | |||
1136 | |||
1137 | |||
1138 | static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id, | ||
1139 | int source, unsigned int freq_in, | ||
1140 | unsigned int freq_out) | ||
1141 | { | ||
1142 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); | ||
1143 | int fref, indiv; | ||
1144 | u8 div_lo, div_mid, div_hi; | ||
1145 | u64 frac_div; | ||
1146 | |||
1147 | /* Disable PLL */ | ||
1148 | if (freq_out == 0) { | ||
1149 | snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, | ||
1150 | DA732X_PLL_EN, 0); | ||
1151 | da732x->pll_en = false; | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | if (da732x->pll_en) | ||
1156 | return -EBUSY; | ||
1157 | |||
1158 | if (source == DA732X_SRCCLK_MCLK) { | ||
1159 | /* Validate Sysclk rate */ | ||
1160 | switch (da732x->sysclk) { | ||
1161 | case 11290000: | ||
1162 | case 12288000: | ||
1163 | case 22580000: | ||
1164 | case 24576000: | ||
1165 | case 45160000: | ||
1166 | case 49152000: | ||
1167 | snd_soc_write(codec, DA732X_REG_PLL_CTRL, | ||
1168 | DA732X_PLL_BYPASS); | ||
1169 | return 0; | ||
1170 | default: | ||
1171 | dev_err(codec->dev, | ||
1172 | "Cannot use PLL Bypass, invalid SYSCLK rate\n"); | ||
1173 | return -EINVAL; | ||
1174 | } | ||
1175 | } | ||
1176 | |||
1177 | indiv = da732x_get_input_div(codec, da732x->sysclk); | ||
1178 | if (indiv < 0) | ||
1179 | return indiv; | ||
1180 | |||
1181 | fref = (da732x->sysclk / indiv); | ||
1182 | div_hi = freq_out / fref; | ||
1183 | frac_div = (u64)(freq_out % fref) * 8192ULL; | ||
1184 | do_div(frac_div, fref); | ||
1185 | div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK; | ||
1186 | div_lo = (frac_div) & DA732X_U8_MASK; | ||
1187 | |||
1188 | snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo); | ||
1189 | snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid); | ||
1190 | snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi); | ||
1191 | |||
1192 | snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN, | ||
1193 | DA732X_PLL_EN); | ||
1194 | |||
1195 | da732x->pll_en = true; | ||
1196 | |||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
1201 | unsigned int freq, int dir) | ||
1202 | { | ||
1203 | struct snd_soc_codec *codec = dai->codec; | ||
1204 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); | ||
1205 | |||
1206 | da732x->sysclk = freq; | ||
1207 | |||
1208 | return 0; | ||
1209 | } | ||
1210 | |||
1211 | #define DA732X_RATES SNDRV_PCM_RATE_8000_96000 | ||
1212 | |||
1213 | #define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
1214 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
1215 | |||
1216 | static struct snd_soc_dai_ops da732x_dai1_ops = { | ||
1217 | .hw_params = da732x_hw_params, | ||
1218 | .set_fmt = da732x_set_dai_fmt, | ||
1219 | .set_sysclk = da732x_set_dai_sysclk, | ||
1220 | }; | ||
1221 | |||
1222 | static struct snd_soc_dai_ops da732x_dai2_ops = { | ||
1223 | .hw_params = da732x_hw_params, | ||
1224 | .set_fmt = da732x_set_dai_fmt, | ||
1225 | .set_sysclk = da732x_set_dai_sysclk, | ||
1226 | }; | ||
1227 | |||
1228 | static struct snd_soc_dai_driver da732x_dai[] = { | ||
1229 | { | ||
1230 | .name = "DA732X_AIFA", | ||
1231 | .id = DA732X_DAI_ID1, | ||
1232 | .base = DA732X_REG_AIFA1, | ||
1233 | .playback = { | ||
1234 | .stream_name = "AIFA Playback", | ||
1235 | .channels_min = 1, | ||
1236 | .channels_max = 2, | ||
1237 | .rates = DA732X_RATES, | ||
1238 | .formats = DA732X_FORMATS, | ||
1239 | }, | ||
1240 | .capture = { | ||
1241 | .stream_name = "AIFA Capture", | ||
1242 | .channels_min = 1, | ||
1243 | .channels_max = 2, | ||
1244 | .rates = DA732X_RATES, | ||
1245 | .formats = DA732X_FORMATS, | ||
1246 | }, | ||
1247 | .ops = &da732x_dai1_ops, | ||
1248 | }, | ||
1249 | { | ||
1250 | .name = "DA732X_AIFB", | ||
1251 | .id = DA732X_DAI_ID2, | ||
1252 | .base = DA732X_REG_AIFB1, | ||
1253 | .playback = { | ||
1254 | .stream_name = "AIFB Playback", | ||
1255 | .channels_min = 1, | ||
1256 | .channels_max = 2, | ||
1257 | .rates = DA732X_RATES, | ||
1258 | .formats = DA732X_FORMATS, | ||
1259 | }, | ||
1260 | .capture = { | ||
1261 | .stream_name = "AIFB Capture", | ||
1262 | .channels_min = 1, | ||
1263 | .channels_max = 2, | ||
1264 | .rates = DA732X_RATES, | ||
1265 | .formats = DA732X_FORMATS, | ||
1266 | }, | ||
1267 | .ops = &da732x_dai2_ops, | ||
1268 | }, | ||
1269 | }; | ||
1270 | |||
1271 | static const struct regmap_config da732x_regmap = { | ||
1272 | .reg_bits = 8, | ||
1273 | .val_bits = 8, | ||
1274 | |||
1275 | .max_register = DA732X_MAX_REG, | ||
1276 | .reg_defaults = da732x_reg_cache, | ||
1277 | .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache), | ||
1278 | .cache_type = REGCACHE_RBTREE, | ||
1279 | }; | ||
1280 | |||
1281 | |||
1282 | static void da732x_dac_offset_adjust(struct snd_soc_codec *codec) | ||
1283 | { | ||
1284 | u8 offset[DA732X_HP_DACS]; | ||
1285 | u8 sign[DA732X_HP_DACS]; | ||
1286 | u8 step = DA732X_DAC_OFFSET_STEP; | ||
1287 | |||
1288 | /* Initialize DAC offset calibration circuits and registers */ | ||
1289 | snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, | ||
1290 | DA732X_HP_DAC_OFFSET_TRIM_VAL); | ||
1291 | snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, | ||
1292 | DA732X_HP_DAC_OFFSET_TRIM_VAL); | ||
1293 | snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, | ||
1294 | DA732X_HP_DAC_OFF_CALIBRATION | | ||
1295 | DA732X_HP_DAC_OFF_SCALE_STEPS); | ||
1296 | snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, | ||
1297 | DA732X_HP_DAC_OFF_CALIBRATION | | ||
1298 | DA732X_HP_DAC_OFF_SCALE_STEPS); | ||
1299 | |||
1300 | /* Wait for voltage stabilization */ | ||
1301 | msleep(DA732X_WAIT_FOR_STABILIZATION); | ||
1302 | |||
1303 | /* Check DAC offset sign */ | ||
1304 | sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & | ||
1305 | DA732X_HP_DAC_OFF_CNTL_COMPO); | ||
1306 | sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & | ||
1307 | DA732X_HP_DAC_OFF_CNTL_COMPO); | ||
1308 | |||
1309 | /* Binary search DAC offset values (both channels at once) */ | ||
1310 | offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT; | ||
1311 | offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT; | ||
1312 | |||
1313 | do { | ||
1314 | offset[DA732X_HPL_DAC] |= step; | ||
1315 | offset[DA732X_HPR_DAC] |= step; | ||
1316 | snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, | ||
1317 | ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); | ||
1318 | snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, | ||
1319 | ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); | ||
1320 | |||
1321 | msleep(DA732X_WAIT_FOR_STABILIZATION); | ||
1322 | |||
1323 | if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) & | ||
1324 | DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC]) | ||
1325 | offset[DA732X_HPL_DAC] &= ~step; | ||
1326 | if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) & | ||
1327 | DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC]) | ||
1328 | offset[DA732X_HPR_DAC] &= ~step; | ||
1329 | |||
1330 | step >>= 1; | ||
1331 | } while (step); | ||
1332 | |||
1333 | /* Write final DAC offsets to registers */ | ||
1334 | snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET, | ||
1335 | ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK); | ||
1336 | snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET, | ||
1337 | ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK); | ||
1338 | |||
1339 | /* End DAC calibration mode */ | ||
1340 | snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL, | ||
1341 | DA732X_HP_DAC_OFF_SCALE_STEPS); | ||
1342 | snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL, | ||
1343 | DA732X_HP_DAC_OFF_SCALE_STEPS); | ||
1344 | } | ||
1345 | |||
1346 | static void da732x_output_offset_adjust(struct snd_soc_codec *codec) | ||
1347 | { | ||
1348 | u8 offset[DA732X_HP_AMPS]; | ||
1349 | u8 sign[DA732X_HP_AMPS]; | ||
1350 | u8 step = DA732X_OUTPUT_OFFSET_STEP; | ||
1351 | |||
1352 | offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL; | ||
1353 | offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL; | ||
1354 | |||
1355 | /* Initialize output offset calibration circuits and registers */ | ||
1356 | snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); | ||
1357 | snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL); | ||
1358 | snd_soc_write(codec, DA732X_REG_HPL, | ||
1359 | DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); | ||
1360 | snd_soc_write(codec, DA732X_REG_HPR, | ||
1361 | DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN); | ||
1362 | |||
1363 | /* Wait for voltage stabilization */ | ||
1364 | msleep(DA732X_WAIT_FOR_STABILIZATION); | ||
1365 | |||
1366 | /* Check output offset sign */ | ||
1367 | sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) & | ||
1368 | DA732X_HP_OUT_COMPO; | ||
1369 | sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) & | ||
1370 | DA732X_HP_OUT_COMPO; | ||
1371 | |||
1372 | snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP | | ||
1373 | (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | | ||
1374 | DA732X_HP_OUT_EN); | ||
1375 | snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP | | ||
1376 | (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) | | ||
1377 | DA732X_HP_OUT_EN); | ||
1378 | |||
1379 | /* Binary search output offset values (both channels at once) */ | ||
1380 | do { | ||
1381 | offset[DA732X_HPL_AMP] |= step; | ||
1382 | offset[DA732X_HPR_AMP] |= step; | ||
1383 | snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, | ||
1384 | offset[DA732X_HPL_AMP]); | ||
1385 | snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, | ||
1386 | offset[DA732X_HPR_AMP]); | ||
1387 | |||
1388 | msleep(DA732X_WAIT_FOR_STABILIZATION); | ||
1389 | |||
1390 | if ((codec->hw_read(codec, DA732X_REG_HPL) & | ||
1391 | DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP]) | ||
1392 | offset[DA732X_HPL_AMP] &= ~step; | ||
1393 | if ((codec->hw_read(codec, DA732X_REG_HPR) & | ||
1394 | DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP]) | ||
1395 | offset[DA732X_HPR_AMP] &= ~step; | ||
1396 | |||
1397 | step >>= 1; | ||
1398 | } while (step); | ||
1399 | |||
1400 | /* Write final DAC offsets to registers */ | ||
1401 | snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]); | ||
1402 | snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]); | ||
1403 | } | ||
1404 | |||
1405 | static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec) | ||
1406 | { | ||
1407 | /* Make sure that we have Soft Mute enabled */ | ||
1408 | snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN | | ||
1409 | DA732X_GAIN_RAMPED | DA732X_16_SAMPLES); | ||
1410 | snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN | | ||
1411 | DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM | | ||
1412 | DA732X_DACL_MUTE | DA732X_DACR_MUTE); | ||
1413 | snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN | | ||
1414 | DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN); | ||
1415 | snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN | | ||
1416 | DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN); | ||
1417 | |||
1418 | da732x_dac_offset_adjust(codec); | ||
1419 | da732x_output_offset_adjust(codec); | ||
1420 | |||
1421 | snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS); | ||
1422 | snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS); | ||
1423 | snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS); | ||
1424 | } | ||
1425 | |||
1426 | static int da732x_set_bias_level(struct snd_soc_codec *codec, | ||
1427 | enum snd_soc_bias_level level) | ||
1428 | { | ||
1429 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); | ||
1430 | |||
1431 | switch (level) { | ||
1432 | case SND_SOC_BIAS_ON: | ||
1433 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, | ||
1434 | DA732X_BIAS_BOOST_MASK, | ||
1435 | DA732X_BIAS_BOOST_100PC); | ||
1436 | break; | ||
1437 | case SND_SOC_BIAS_PREPARE: | ||
1438 | break; | ||
1439 | case SND_SOC_BIAS_STANDBY: | ||
1440 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1441 | /* Init Codec */ | ||
1442 | snd_soc_write(codec, DA732X_REG_REF1, | ||
1443 | DA732X_VMID_FASTCHG); | ||
1444 | snd_soc_write(codec, DA732X_REG_BIAS_EN, | ||
1445 | DA732X_BIAS_EN); | ||
1446 | |||
1447 | mdelay(DA732X_STARTUP_DELAY); | ||
1448 | |||
1449 | /* Disable Fast Charge and enable DAC ref voltage */ | ||
1450 | snd_soc_write(codec, DA732X_REG_REF1, | ||
1451 | DA732X_REFBUFX2_EN); | ||
1452 | |||
1453 | /* Enable bypass DSP routing */ | ||
1454 | snd_soc_write(codec, DA732X_REG_DATA_ROUTE, | ||
1455 | DA732X_BYPASS_DSP); | ||
1456 | |||
1457 | /* Enable Digital subsystem */ | ||
1458 | snd_soc_write(codec, DA732X_REG_DSP_CTRL, | ||
1459 | DA732X_DIGITAL_EN); | ||
1460 | |||
1461 | snd_soc_write(codec, DA732X_REG_SPARE1_OUT, | ||
1462 | DA732X_HP_DRIVER_EN | | ||
1463 | DA732X_HP_GATE_LOW | | ||
1464 | DA732X_HP_LOOP_GAIN_CTRL); | ||
1465 | snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL, | ||
1466 | DA732X_HP_OUT_GNDSEL); | ||
1467 | |||
1468 | da732x_set_charge_pump(codec, DA732X_ENABLE_CP); | ||
1469 | |||
1470 | snd_soc_write(codec, DA732X_REG_CLK_EN1, | ||
1471 | DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN); | ||
1472 | |||
1473 | /* Enable Zero Crossing */ | ||
1474 | snd_soc_write(codec, DA732X_REG_INP_ZC_EN, | ||
1475 | DA732X_MIC1_PRE_ZC_EN | | ||
1476 | DA732X_MIC1_ZC_EN | | ||
1477 | DA732X_MIC2_PRE_ZC_EN | | ||
1478 | DA732X_MIC2_ZC_EN | | ||
1479 | DA732X_AUXL_ZC_EN | | ||
1480 | DA732X_AUXR_ZC_EN | | ||
1481 | DA732X_MIC3_PRE_ZC_EN | | ||
1482 | DA732X_MIC3_ZC_EN); | ||
1483 | snd_soc_write(codec, DA732X_REG_OUT_ZC_EN, | ||
1484 | DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN | | ||
1485 | DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN | | ||
1486 | DA732X_LIN4_ZC_EN); | ||
1487 | |||
1488 | da732x_hp_dc_offset_cancellation(codec); | ||
1489 | |||
1490 | regcache_cache_only(codec->control_data, false); | ||
1491 | regcache_sync(codec->control_data); | ||
1492 | } else { | ||
1493 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, | ||
1494 | DA732X_BIAS_BOOST_MASK, | ||
1495 | DA732X_BIAS_BOOST_50PC); | ||
1496 | snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, | ||
1497 | DA732X_PLL_EN, 0); | ||
1498 | da732x->pll_en = false; | ||
1499 | } | ||
1500 | break; | ||
1501 | case SND_SOC_BIAS_OFF: | ||
1502 | regcache_cache_only(codec->control_data, true); | ||
1503 | da732x_set_charge_pump(codec, DA732X_DISABLE_CP); | ||
1504 | snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN, | ||
1505 | DA732X_BIAS_DIS); | ||
1506 | da732x->pll_en = false; | ||
1507 | break; | ||
1508 | } | ||
1509 | |||
1510 | codec->dapm.bias_level = level; | ||
1511 | |||
1512 | return 0; | ||
1513 | } | ||
1514 | |||
1515 | static int da732x_probe(struct snd_soc_codec *codec) | ||
1516 | { | ||
1517 | struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec); | ||
1518 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
1519 | int ret = 0; | ||
1520 | |||
1521 | da732x->codec = codec; | ||
1522 | |||
1523 | dapm->idle_bias_off = false; | ||
1524 | |||
1525 | codec->control_data = da732x->regmap; | ||
1526 | |||
1527 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1528 | if (ret != 0) { | ||
1529 | dev_err(codec->dev, "Failed to register codec.\n"); | ||
1530 | goto err; | ||
1531 | } | ||
1532 | |||
1533 | da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1534 | err: | ||
1535 | return ret; | ||
1536 | } | ||
1537 | |||
1538 | static int da732x_remove(struct snd_soc_codec *codec) | ||
1539 | { | ||
1540 | |||
1541 | da732x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1542 | |||
1543 | return 0; | ||
1544 | } | ||
1545 | |||
1546 | struct snd_soc_codec_driver soc_codec_dev_da732x = { | ||
1547 | .probe = da732x_probe, | ||
1548 | .remove = da732x_remove, | ||
1549 | .set_bias_level = da732x_set_bias_level, | ||
1550 | .controls = da732x_snd_controls, | ||
1551 | .num_controls = ARRAY_SIZE(da732x_snd_controls), | ||
1552 | .dapm_widgets = da732x_dapm_widgets, | ||
1553 | .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets), | ||
1554 | .dapm_routes = da732x_dapm_routes, | ||
1555 | .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes), | ||
1556 | .set_pll = da732x_set_dai_pll, | ||
1557 | .reg_cache_size = ARRAY_SIZE(da732x_reg_cache), | ||
1558 | }; | ||
1559 | |||
1560 | static __devinit int da732x_i2c_probe(struct i2c_client *i2c, | ||
1561 | const struct i2c_device_id *id) | ||
1562 | { | ||
1563 | struct da732x_priv *da732x; | ||
1564 | unsigned int reg; | ||
1565 | int ret; | ||
1566 | |||
1567 | da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv), | ||
1568 | GFP_KERNEL); | ||
1569 | if (!da732x) | ||
1570 | return -ENOMEM; | ||
1571 | |||
1572 | i2c_set_clientdata(i2c, da732x); | ||
1573 | |||
1574 | da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap); | ||
1575 | if (IS_ERR(da732x->regmap)) { | ||
1576 | ret = PTR_ERR(da732x->regmap); | ||
1577 | dev_err(&i2c->dev, "Failed to initialize regmap\n"); | ||
1578 | goto err; | ||
1579 | } | ||
1580 | |||
1581 | ret = regmap_read(da732x->regmap, DA732X_REG_ID, ®); | ||
1582 | if (ret < 0) { | ||
1583 | dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); | ||
1584 | goto err; | ||
1585 | } | ||
1586 | |||
1587 | dev_info(&i2c->dev, "Revision: %d.%d\n", | ||
1588 | (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK)); | ||
1589 | |||
1590 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x, | ||
1591 | da732x_dai, ARRAY_SIZE(da732x_dai)); | ||
1592 | if (ret != 0) | ||
1593 | dev_err(&i2c->dev, "Failed to register codec.\n"); | ||
1594 | |||
1595 | err: | ||
1596 | return ret; | ||
1597 | } | ||
1598 | |||
1599 | static __devexit int da732x_i2c_remove(struct i2c_client *client) | ||
1600 | { | ||
1601 | snd_soc_unregister_codec(&client->dev); | ||
1602 | |||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static const struct i2c_device_id da732x_i2c_id[] = { | ||
1607 | { "da7320", 0}, | ||
1608 | { } | ||
1609 | }; | ||
1610 | MODULE_DEVICE_TABLE(i2c, da732x_i2c_id); | ||
1611 | |||
1612 | static struct i2c_driver da732x_i2c_driver = { | ||
1613 | .driver = { | ||
1614 | .name = "da7320", | ||
1615 | .owner = THIS_MODULE, | ||
1616 | }, | ||
1617 | .probe = da732x_i2c_probe, | ||
1618 | .remove = __devexit_p(da732x_i2c_remove), | ||
1619 | .id_table = da732x_i2c_id, | ||
1620 | }; | ||
1621 | |||
1622 | module_i2c_driver(da732x_i2c_driver); | ||
1623 | |||
1624 | |||
1625 | MODULE_DESCRIPTION("ASoC DA732X driver"); | ||
1626 | MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>"); | ||
1627 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h new file mode 100644 index 000000000000..c8ce5475de22 --- /dev/null +++ b/sound/soc/codecs/da732x.h | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * da732x.h -- Dialog DA732X ALSA SoC Audio Driver Header File | ||
3 | * | ||
4 | * Copyright (C) 2012 Dialog Semiconductor GmbH | ||
5 | * | ||
6 | * Author: Michal Hajduk <Michal.Hajduk@diasemi.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 | #ifndef __DA732X_H_ | ||
14 | #define __DA732X_H | ||
15 | |||
16 | #include <sound/soc.h> | ||
17 | |||
18 | /* General */ | ||
19 | #define DA732X_U8_MASK 0xFF | ||
20 | #define DA732X_4BYTES 4 | ||
21 | #define DA732X_3BYTES 3 | ||
22 | #define DA732X_2BYTES 2 | ||
23 | #define DA732X_1BYTE 1 | ||
24 | #define DA732X_1BYTE_SHIFT 8 | ||
25 | #define DA732X_2BYTES_SHIFT 16 | ||
26 | #define DA732X_3BYTES_SHIFT 24 | ||
27 | #define DA732X_4BYTES_SHIFT 32 | ||
28 | |||
29 | #define DA732X_DACS_DIS 0x0 | ||
30 | #define DA732X_HP_DIS 0x0 | ||
31 | #define DA732X_CLEAR_REG 0x0 | ||
32 | |||
33 | /* Calibration */ | ||
34 | #define DA732X_DAC_OFFSET_STEP 0x20 | ||
35 | #define DA732X_OUTPUT_OFFSET_STEP 0x80 | ||
36 | #define DA732X_HP_OUT_TRIM_VAL 0x0 | ||
37 | #define DA732X_WAIT_FOR_STABILIZATION 1 | ||
38 | #define DA732X_HPL_DAC 0 | ||
39 | #define DA732X_HPR_DAC 1 | ||
40 | #define DA732X_HP_DACS 2 | ||
41 | #define DA732X_HPL_AMP 0 | ||
42 | #define DA732X_HPR_AMP 1 | ||
43 | #define DA732X_HP_AMPS 2 | ||
44 | |||
45 | /* Clock settings */ | ||
46 | #define DA732X_STARTUP_DELAY 100 | ||
47 | #define DA732X_PLL_OUT_196608 196608000 | ||
48 | #define DA732X_PLL_OUT_180634 180633600 | ||
49 | #define DA732X_PLL_OUT_SRM 188620800 | ||
50 | #define DA732X_MCLK_10MHZ 10000000 | ||
51 | #define DA732X_MCLK_20MHZ 20000000 | ||
52 | #define DA732X_MCLK_40MHZ 40000000 | ||
53 | #define DA732X_MCLK_54MHZ 54000000 | ||
54 | #define DA732X_MCLK_RET_0_10MHZ 0 | ||
55 | #define DA732X_MCLK_VAL_0_10MHZ 1 | ||
56 | #define DA732X_MCLK_RET_10_20MHZ 1 | ||
57 | #define DA732X_MCLK_VAL_10_20MHZ 2 | ||
58 | #define DA732X_MCLK_RET_20_40MHZ 2 | ||
59 | #define DA732X_MCLK_VAL_20_40MHZ 4 | ||
60 | #define DA732X_MCLK_RET_40_54MHZ 3 | ||
61 | #define DA732X_MCLK_VAL_40_54MHZ 8 | ||
62 | #define DA732X_DAI_ID1 0 | ||
63 | #define DA732X_DAI_ID2 1 | ||
64 | #define DA732X_SRCCLK_PLL 0 | ||
65 | #define DA732X_SRCCLK_MCLK 1 | ||
66 | |||
67 | #define DA732X_LIN_LP_VOL 0x4F | ||
68 | #define DA732X_LP_VOL 0x40 | ||
69 | |||
70 | /* Kcontrols */ | ||
71 | #define DA732X_DAC_EN_MAX 2 | ||
72 | #define DA732X_ADCL_MUX_MAX 2 | ||
73 | #define DA732X_ADCR_MUX_MAX 3 | ||
74 | #define DA732X_HPF_MODE_MAX 3 | ||
75 | #define DA732X_HPF_MODE_SHIFT 4 | ||
76 | #define DA732X_HPF_MUSIC_SHIFT 0 | ||
77 | #define DA732X_HPF_MUSIC_MAX 4 | ||
78 | #define DA732X_HPF_VOICE_SHIFT 4 | ||
79 | #define DA732X_HPF_VOICE_MAX 8 | ||
80 | #define DA732X_EQ_EN_MAX 1 | ||
81 | #define DA732X_HPF_VOICE 1 | ||
82 | #define DA732X_HPF_MUSIC 2 | ||
83 | #define DA732X_HPF_DISABLED 0 | ||
84 | #define DA732X_NO_INVERT 0 | ||
85 | #define DA732X_INVERT 1 | ||
86 | #define DA732X_SWITCH_MAX 1 | ||
87 | #define DA732X_ENABLE_CP 1 | ||
88 | #define DA732X_DISABLE_CP 0 | ||
89 | #define DA732X_DISABLE_ALL_CLKS 0 | ||
90 | #define DA732X_RESET_ADCS 0 | ||
91 | |||
92 | /* dB values */ | ||
93 | #define DA732X_MIC_VOL_DB_MIN 0 | ||
94 | #define DA732X_MIC_VOL_DB_INC 50 | ||
95 | #define DA732X_MIC_PRE_VOL_DB_MIN 0 | ||
96 | #define DA732X_MIC_PRE_VOL_DB_INC 600 | ||
97 | #define DA732X_AUX_VOL_DB_MIN -6000 | ||
98 | #define DA732X_AUX_VOL_DB_INC 150 | ||
99 | #define DA732X_HP_VOL_DB_MIN -2250 | ||
100 | #define DA732X_HP_VOL_DB_INC 150 | ||
101 | #define DA732X_LIN2_VOL_DB_MIN -1650 | ||
102 | #define DA732X_LIN2_VOL_DB_INC 150 | ||
103 | #define DA732X_LIN3_VOL_DB_MIN -1650 | ||
104 | #define DA732X_LIN3_VOL_DB_INC 150 | ||
105 | #define DA732X_LIN4_VOL_DB_MIN -2250 | ||
106 | #define DA732X_LIN4_VOL_DB_INC 150 | ||
107 | #define DA732X_EQ_BAND_VOL_DB_MIN -1050 | ||
108 | #define DA732X_EQ_BAND_VOL_DB_INC 150 | ||
109 | #define DA732X_DAC_VOL_DB_MIN -7725 | ||
110 | #define DA732X_DAC_VOL_DB_INC 75 | ||
111 | #define DA732X_ADC_VOL_DB_MIN 0 | ||
112 | #define DA732X_ADC_VOL_DB_INC -1 | ||
113 | #define DA732X_EQ_OVERALL_VOL_DB_MIN -1800 | ||
114 | #define DA732X_EQ_OVERALL_VOL_DB_INC 600 | ||
115 | |||
116 | #define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \ | ||
117 | {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext} | ||
118 | |||
119 | enum da732x_sysctl { | ||
120 | DA732X_SR_8KHZ = 0x1, | ||
121 | DA732X_SR_11_025KHZ = 0x2, | ||
122 | DA732X_SR_12KHZ = 0x3, | ||
123 | DA732X_SR_16KHZ = 0x5, | ||
124 | DA732X_SR_22_05KHZ = 0x6, | ||
125 | DA732X_SR_24KHZ = 0x7, | ||
126 | DA732X_SR_32KHZ = 0x9, | ||
127 | DA732X_SR_44_1KHZ = 0xA, | ||
128 | DA732X_SR_48KHZ = 0xB, | ||
129 | DA732X_SR_88_1KHZ = 0xE, | ||
130 | DA732X_SR_96KHZ = 0xF, | ||
131 | }; | ||
132 | |||
133 | #endif /* __DA732X_H_ */ | ||
diff --git a/sound/soc/codecs/da732x_reg.h b/sound/soc/codecs/da732x_reg.h new file mode 100644 index 000000000000..bdd03ca4b2de --- /dev/null +++ b/sound/soc/codecs/da732x_reg.h | |||
@@ -0,0 +1,654 @@ | |||
1 | /* | ||
2 | * da732x_reg.h --- Dialog DA732X ALSA SoC Audio Registers Header File | ||
3 | * | ||
4 | * Copyright (C) 2012 Dialog Semiconductor GmbH | ||
5 | * | ||
6 | * Author: Michal Hajduk <Michal.Hajduk@diasemi.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 | #ifndef __DA732X_REG_H_ | ||
14 | #define __DA732X_REG_H_ | ||
15 | |||
16 | /* DA732X registers */ | ||
17 | #define DA732X_REG_STATUS_EXT 0x00 | ||
18 | #define DA732X_REG_STATUS 0x01 | ||
19 | #define DA732X_REG_REF1 0x02 | ||
20 | #define DA732X_REG_BIAS_EN 0x03 | ||
21 | #define DA732X_REG_BIAS1 0x04 | ||
22 | #define DA732X_REG_BIAS2 0x05 | ||
23 | #define DA732X_REG_BIAS3 0x06 | ||
24 | #define DA732X_REG_BIAS4 0x07 | ||
25 | #define DA732X_REG_MICBIAS2 0x0F | ||
26 | #define DA732X_REG_MICBIAS1 0x10 | ||
27 | #define DA732X_REG_MICDET 0x11 | ||
28 | #define DA732X_REG_MIC1_PRE 0x12 | ||
29 | #define DA732X_REG_MIC1 0x13 | ||
30 | #define DA732X_REG_MIC2_PRE 0x14 | ||
31 | #define DA732X_REG_MIC2 0x15 | ||
32 | #define DA732X_REG_AUX1L 0x16 | ||
33 | #define DA732X_REG_AUX1R 0x17 | ||
34 | #define DA732X_REG_MIC3_PRE 0x18 | ||
35 | #define DA732X_REG_MIC3 0x19 | ||
36 | #define DA732X_REG_INP_PINBIAS 0x1A | ||
37 | #define DA732X_REG_INP_ZC_EN 0x1B | ||
38 | #define DA732X_REG_INP_MUX 0x1D | ||
39 | #define DA732X_REG_HP_DET 0x20 | ||
40 | #define DA732X_REG_HPL_DAC_OFFSET 0x21 | ||
41 | #define DA732X_REG_HPL_DAC_OFF_CNTL 0x22 | ||
42 | #define DA732X_REG_HPL_OUT_OFFSET 0x23 | ||
43 | #define DA732X_REG_HPL 0x24 | ||
44 | #define DA732X_REG_HPL_VOL 0x25 | ||
45 | #define DA732X_REG_HPR_DAC_OFFSET 0x26 | ||
46 | #define DA732X_REG_HPR_DAC_OFF_CNTL 0x27 | ||
47 | #define DA732X_REG_HPR_OUT_OFFSET 0x28 | ||
48 | #define DA732X_REG_HPR 0x29 | ||
49 | #define DA732X_REG_HPR_VOL 0x2A | ||
50 | #define DA732X_REG_LIN2 0x2B | ||
51 | #define DA732X_REG_LIN3 0x2C | ||
52 | #define DA732X_REG_LIN4 0x2D | ||
53 | #define DA732X_REG_OUT_ZC_EN 0x2E | ||
54 | #define DA732X_REG_HP_LIN1_GNDSEL 0x37 | ||
55 | #define DA732X_REG_CP_HP1 0x3A | ||
56 | #define DA732X_REG_CP_HP2 0x3B | ||
57 | #define DA732X_REG_CP_CTRL1 0x40 | ||
58 | #define DA732X_REG_CP_CTRL2 0x41 | ||
59 | #define DA732X_REG_CP_CTRL3 0x42 | ||
60 | #define DA732X_REG_CP_LEVEL_MASK 0x43 | ||
61 | #define DA732X_REG_CP_DET 0x44 | ||
62 | #define DA732X_REG_CP_STATUS 0x45 | ||
63 | #define DA732X_REG_CP_THRESH1 0x46 | ||
64 | #define DA732X_REG_CP_THRESH2 0x47 | ||
65 | #define DA732X_REG_CP_THRESH3 0x48 | ||
66 | #define DA732X_REG_CP_THRESH4 0x49 | ||
67 | #define DA732X_REG_CP_THRESH5 0x4A | ||
68 | #define DA732X_REG_CP_THRESH6 0x4B | ||
69 | #define DA732X_REG_CP_THRESH7 0x4C | ||
70 | #define DA732X_REG_CP_THRESH8 0x4D | ||
71 | #define DA732X_REG_PLL_DIV_LO 0x50 | ||
72 | #define DA732X_REG_PLL_DIV_MID 0x51 | ||
73 | #define DA732X_REG_PLL_DIV_HI 0x52 | ||
74 | #define DA732X_REG_PLL_CTRL 0x53 | ||
75 | #define DA732X_REG_CLK_CTRL 0x54 | ||
76 | #define DA732X_REG_CLK_DSP 0x5A | ||
77 | #define DA732X_REG_CLK_EN1 0x5B | ||
78 | #define DA732X_REG_CLK_EN2 0x5C | ||
79 | #define DA732X_REG_CLK_EN3 0x5D | ||
80 | #define DA732X_REG_CLK_EN4 0x5E | ||
81 | #define DA732X_REG_CLK_EN5 0x5F | ||
82 | #define DA732X_REG_AIF_MCLK 0x60 | ||
83 | #define DA732X_REG_AIFA1 0x61 | ||
84 | #define DA732X_REG_AIFA2 0x62 | ||
85 | #define DA732X_REG_AIFA3 0x63 | ||
86 | #define DA732X_REG_AIFB1 0x64 | ||
87 | #define DA732X_REG_AIFB2 0x65 | ||
88 | #define DA732X_REG_AIFB3 0x66 | ||
89 | #define DA732X_REG_PC_CTRL 0x6A | ||
90 | #define DA732X_REG_DATA_ROUTE 0x70 | ||
91 | #define DA732X_REG_DSP_CTRL 0x71 | ||
92 | #define DA732X_REG_CIF_CTRL2 0x74 | ||
93 | #define DA732X_REG_HANDSHAKE 0x75 | ||
94 | #define DA732X_REG_MBOX0 0x76 | ||
95 | #define DA732X_REG_MBOX1 0x77 | ||
96 | #define DA732X_REG_MBOX2 0x78 | ||
97 | #define DA732X_REG_MBOX_STATUS 0x79 | ||
98 | #define DA732X_REG_SPARE1_OUT 0x7D | ||
99 | #define DA732X_REG_SPARE2_OUT 0x7E | ||
100 | #define DA732X_REG_SPARE1_IN 0x7F | ||
101 | #define DA732X_REG_ID 0x81 | ||
102 | #define DA732X_REG_ADC1_PD 0x90 | ||
103 | #define DA732X_REG_ADC1_HPF 0x93 | ||
104 | #define DA732X_REG_ADC1_SEL 0x94 | ||
105 | #define DA732X_REG_ADC1_EQ12 0x95 | ||
106 | #define DA732X_REG_ADC1_EQ34 0x96 | ||
107 | #define DA732X_REG_ADC1_EQ5 0x97 | ||
108 | #define DA732X_REG_ADC2_PD 0x98 | ||
109 | #define DA732X_REG_ADC2_HPF 0x9B | ||
110 | #define DA732X_REG_ADC2_SEL 0x9C | ||
111 | #define DA732X_REG_ADC2_EQ12 0x9D | ||
112 | #define DA732X_REG_ADC2_EQ34 0x9E | ||
113 | #define DA732X_REG_ADC2_EQ5 0x9F | ||
114 | #define DA732X_REG_DAC1_HPF 0xA0 | ||
115 | #define DA732X_REG_DAC1_L_VOL 0xA1 | ||
116 | #define DA732X_REG_DAC1_R_VOL 0xA2 | ||
117 | #define DA732X_REG_DAC1_SEL 0xA3 | ||
118 | #define DA732X_REG_DAC1_SOFTMUTE 0xA4 | ||
119 | #define DA732X_REG_DAC1_EQ12 0xA5 | ||
120 | #define DA732X_REG_DAC1_EQ34 0xA6 | ||
121 | #define DA732X_REG_DAC1_EQ5 0xA7 | ||
122 | #define DA732X_REG_DAC2_HPF 0xB0 | ||
123 | #define DA732X_REG_DAC2_L_VOL 0xB1 | ||
124 | #define DA732X_REG_DAC2_R_VOL 0xB2 | ||
125 | #define DA732X_REG_DAC2_SEL 0xB3 | ||
126 | #define DA732X_REG_DAC2_SOFTMUTE 0xB4 | ||
127 | #define DA732X_REG_DAC2_EQ12 0xB5 | ||
128 | #define DA732X_REG_DAC2_EQ34 0xB6 | ||
129 | #define DA732X_REG_DAC2_EQ5 0xB7 | ||
130 | #define DA732X_REG_DAC3_HPF 0xC0 | ||
131 | #define DA732X_REG_DAC3_VOL 0xC1 | ||
132 | #define DA732X_REG_DAC3_SEL 0xC3 | ||
133 | #define DA732X_REG_DAC3_SOFTMUTE 0xC4 | ||
134 | #define DA732X_REG_DAC3_EQ12 0xC5 | ||
135 | #define DA732X_REG_DAC3_EQ34 0xC6 | ||
136 | #define DA732X_REG_DAC3_EQ5 0xC7 | ||
137 | #define DA732X_REG_BIQ_BYP 0xD2 | ||
138 | #define DA732X_REG_DMA_CMD 0xD3 | ||
139 | #define DA732X_REG_DMA_ADDR0 0xD4 | ||
140 | #define DA732X_REG_DMA_ADDR1 0xD5 | ||
141 | #define DA732X_REG_DMA_DATA0 0xD6 | ||
142 | #define DA732X_REG_DMA_DATA1 0xD7 | ||
143 | #define DA732X_REG_DMA_DATA2 0xD8 | ||
144 | #define DA732X_REG_DMA_DATA3 0xD9 | ||
145 | #define DA732X_REG_DMA_STATUS 0xDA | ||
146 | #define DA732X_REG_BROWNOUT 0xDF | ||
147 | #define DA732X_REG_UNLOCK 0xE0 | ||
148 | |||
149 | #define DA732X_MAX_REG DA732X_REG_UNLOCK | ||
150 | /* | ||
151 | * Bits | ||
152 | */ | ||
153 | |||
154 | /* DA732X_REG_STATUS_EXT (addr=0x00) */ | ||
155 | #define DA732X_STATUS_EXT_DSP (1 << 4) | ||
156 | #define DA732X_STATUS_EXT_CLEAR (0 << 0) | ||
157 | |||
158 | /* DA732X_REG_STATUS (addr=0x01) */ | ||
159 | #define DA732X_STATUS_PLL_LOCK (1 << 0) | ||
160 | #define DA732X_STATUS_PLL_MCLK_DET (1 << 1) | ||
161 | #define DA732X_STATUS_HPDET_OUT (1 << 2) | ||
162 | #define DA732X_STATUS_INP_MIXDET_1 (1 << 3) | ||
163 | #define DA732X_STATUS_INP_MIXDET_2 (1 << 4) | ||
164 | #define DA732X_STATUS_BO_STATUS (1 << 5) | ||
165 | |||
166 | /* DA732X_REG_REF1 (addr=0x02) */ | ||
167 | #define DA732X_VMID_FASTCHG (1 << 1) | ||
168 | #define DA732X_VMID_FASTDISCHG (1 << 2) | ||
169 | #define DA732X_REFBUFX2_EN (1 << 6) | ||
170 | #define DA732X_REFBUFX2_DIS (0 << 6) | ||
171 | |||
172 | /* DA732X_REG_BIAS_EN (addr=0x03) */ | ||
173 | #define DA732X_BIAS_BOOST_MASK (3 << 0) | ||
174 | #define DA732X_BIAS_BOOST_100PC (0 << 0) | ||
175 | #define DA732X_BIAS_BOOST_133PC (1 << 0) | ||
176 | #define DA732X_BIAS_BOOST_88PC (2 << 0) | ||
177 | #define DA732X_BIAS_BOOST_50PC (3 << 0) | ||
178 | #define DA732X_BIAS_EN (1 << 7) | ||
179 | #define DA732X_BIAS_DIS (0 << 7) | ||
180 | |||
181 | /* DA732X_REG_BIAS1 (addr=0x04) */ | ||
182 | #define DA732X_BIAS1_HP_DAC_BIAS_MASK (3 << 0) | ||
183 | #define DA732X_BIAS1_HP_DAC_BIAS_100PC (0 << 0) | ||
184 | #define DA732X_BIAS1_HP_DAC_BIAS_150PC (1 << 0) | ||
185 | #define DA732X_BIAS1_HP_DAC_BIAS_50PC (2 << 0) | ||
186 | #define DA732X_BIAS1_HP_DAC_BIAS_75PC (3 << 0) | ||
187 | #define DA732X_BIAS1_HP_OUT_BIAS_MASK (7 << 4) | ||
188 | #define DA732X_BIAS1_HP_OUT_BIAS_100PC (0 << 4) | ||
189 | #define DA732X_BIAS1_HP_OUT_BIAS_125PC (1 << 4) | ||
190 | #define DA732X_BIAS1_HP_OUT_BIAS_150PC (2 << 4) | ||
191 | #define DA732X_BIAS1_HP_OUT_BIAS_175PC (3 << 4) | ||
192 | #define DA732X_BIAS1_HP_OUT_BIAS_200PC (4 << 4) | ||
193 | #define DA732X_BIAS1_HP_OUT_BIAS_250PC (5 << 4) | ||
194 | #define DA732X_BIAS1_HP_OUT_BIAS_300PC (6 << 4) | ||
195 | #define DA732X_BIAS1_HP_OUT_BIAS_350PC (7 << 4) | ||
196 | |||
197 | /* DA732X_REG_BIAS2 (addr=0x05) */ | ||
198 | #define DA732X_BIAS2_LINE2_DAC_BIAS_MASK (3 << 0) | ||
199 | #define DA732X_BIAS2_LINE2_DAC_BIAS_100PC (0 << 0) | ||
200 | #define DA732X_BIAS2_LINE2_DAC_BIAS_150PC (1 << 0) | ||
201 | #define DA732X_BIAS2_LINE2_DAC_BIAS_50PC (2 << 0) | ||
202 | #define DA732X_BIAS2_LINE2_DAC_BIAS_75PC (3 << 0) | ||
203 | #define DA732X_BIAS2_LINE2_OUT_BIAS_MASK (7 << 4) | ||
204 | #define DA732X_BIAS2_LINE2_OUT_BIAS_100PC (0 << 4) | ||
205 | #define DA732X_BIAS2_LINE2_OUT_BIAS_125PC (1 << 4) | ||
206 | #define DA732X_BIAS2_LINE2_OUT_BIAS_150PC (2 << 4) | ||
207 | #define DA732X_BIAS2_LINE2_OUT_BIAS_175PC (3 << 4) | ||
208 | #define DA732X_BIAS2_LINE2_OUT_BIAS_200PC (4 << 4) | ||
209 | #define DA732X_BIAS2_LINE2_OUT_BIAS_250PC (5 << 4) | ||
210 | #define DA732X_BIAS2_LINE2_OUT_BIAS_300PC (6 << 4) | ||
211 | #define DA732X_BIAS2_LINE2_OUT_BIAS_350PC (7 << 4) | ||
212 | |||
213 | /* DA732X_REG_BIAS3 (addr=0x06) */ | ||
214 | #define DA732X_BIAS3_LINE3_DAC_BIAS_MASK (3 << 0) | ||
215 | #define DA732X_BIAS3_LINE3_DAC_BIAS_100PC (0 << 0) | ||
216 | #define DA732X_BIAS3_LINE3_DAC_BIAS_150PC (1 << 0) | ||
217 | #define DA732X_BIAS3_LINE3_DAC_BIAS_50PC (2 << 0) | ||
218 | #define DA732X_BIAS3_LINE3_DAC_BIAS_75PC (3 << 0) | ||
219 | #define DA732X_BIAS3_LINE3_OUT_BIAS_MASK (7 << 4) | ||
220 | #define DA732X_BIAS3_LINE3_OUT_BIAS_100PC (0 << 4) | ||
221 | #define DA732X_BIAS3_LINE3_OUT_BIAS_125PC (1 << 4) | ||
222 | #define DA732X_BIAS3_LINE3_OUT_BIAS_150PC (2 << 4) | ||
223 | #define DA732X_BIAS3_LINE3_OUT_BIAS_175PC (3 << 4) | ||
224 | #define DA732X_BIAS3_LINE3_OUT_BIAS_200PC (4 << 4) | ||
225 | #define DA732X_BIAS3_LINE3_OUT_BIAS_250PC (5 << 4) | ||
226 | #define DA732X_BIAS3_LINE3_OUT_BIAS_300PC (6 << 4) | ||
227 | #define DA732X_BIAS3_LINE3_OUT_BIAS_350PC (7 << 4) | ||
228 | |||
229 | /* DA732X_REG_BIAS4 (addr=0x07) */ | ||
230 | #define DA732X_BIAS4_LINE4_DAC_BIAS_MASK (3 << 0) | ||
231 | #define DA732X_BIAS4_LINE4_DAC_BIAS_100PC (0 << 0) | ||
232 | #define DA732X_BIAS4_LINE4_DAC_BIAS_150PC (1 << 0) | ||
233 | #define DA732X_BIAS4_LINE4_DAC_BIAS_50PC (2 << 0) | ||
234 | #define DA732X_BIAS4_LINE4_DAC_BIAS_75PC (3 << 0) | ||
235 | #define DA732X_BIAS4_LINE4_OUT_BIAS_MASK (7 << 4) | ||
236 | #define DA732X_BIAS4_LINE4_OUT_BIAS_100PC (0 << 4) | ||
237 | #define DA732X_BIAS4_LINE4_OUT_BIAS_125PC (1 << 4) | ||
238 | #define DA732X_BIAS4_LINE4_OUT_BIAS_150PC (2 << 4) | ||
239 | #define DA732X_BIAS4_LINE4_OUT_BIAS_175PC (3 << 4) | ||
240 | #define DA732X_BIAS4_LINE4_OUT_BIAS_200PC (4 << 4) | ||
241 | #define DA732X_BIAS4_LINE4_OUT_BIAS_250PC (5 << 4) | ||
242 | #define DA732X_BIAS4_LINE4_OUT_BIAS_300PC (6 << 4) | ||
243 | #define DA732X_BIAS4_LINE4_OUT_BIAS_350PC (7 << 4) | ||
244 | |||
245 | /* DA732X_REG_SIF_VDD_SEL (addr=0x08) */ | ||
246 | #define DA732X_SIF_VDD_SEL_AIFA_VDD2 (1 << 0) | ||
247 | #define DA732X_SIF_VDD_SEL_AIFB_VDD2 (1 << 1) | ||
248 | #define DA732X_SIF_VDD_SEL_CIFA_VDD2 (1 << 4) | ||
249 | |||
250 | /* DA732X_REG_MICBIAS2/1 (addr=0x0F/0x10) */ | ||
251 | #define DA732X_MICBIAS_VOLTAGE_MASK (0x0F << 0) | ||
252 | #define DA732X_MICBIAS_VOLTAGE_2V (0x00 << 0) | ||
253 | #define DA732X_MICBIAS_VOLTAGE_2V05 (0x01 << 0) | ||
254 | #define DA732X_MICBIAS_VOLTAGE_2V1 (0x02 << 0) | ||
255 | #define DA732X_MICBIAS_VOLTAGE_2V15 (0x03 << 0) | ||
256 | #define DA732X_MICBIAS_VOLTAGE_2V2 (0x04 << 0) | ||
257 | #define DA732X_MICBIAS_VOLTAGE_2V25 (0x05 << 0) | ||
258 | #define DA732X_MICBIAS_VOLTAGE_2V3 (0x06 << 0) | ||
259 | #define DA732X_MICBIAS_VOLTAGE_2V35 (0x07 << 0) | ||
260 | #define DA732X_MICBIAS_VOLTAGE_2V4 (0x08 << 0) | ||
261 | #define DA732X_MICBIAS_VOLTAGE_2V45 (0x09 << 0) | ||
262 | #define DA732X_MICBIAS_VOLTAGE_2V5 (0x0A << 0) | ||
263 | #define DA732X_MICBIAS_EN (1 << 7) | ||
264 | #define DA732X_MICBIAS_EN_SHIFT 7 | ||
265 | #define DA732X_MICBIAS_VOLTAGE_SHIFT 0 | ||
266 | #define DA732X_MICBIAS_VOLTAGE_MAX 0x0B | ||
267 | |||
268 | /* DA732X_REG_MICDET (addr=0x11) */ | ||
269 | #define DA732X_MICDET_INP_MICRES (1 << 0) | ||
270 | #define DA732X_MICDET_INP_MICHOOK (1 << 1) | ||
271 | #define DA732X_MICDET_INP_DEBOUNCE_PRD_8MS (0 << 0) | ||
272 | #define DA732X_MICDET_INP_DEBOUNCE_PRD_16MS (1 << 0) | ||
273 | #define DA732X_MICDET_INP_DEBOUNCE_PRD_32MS (2 << 0) | ||
274 | #define DA732X_MICDET_INP_DEBOUNCE_PRD_64MS (3 << 0) | ||
275 | #define DA732X_MICDET_INP_MICDET_EN (1 << 7) | ||
276 | |||
277 | /* DA732X_REG_MIC1/2/3_PRE (addr=0x11/0x14/0x18) */ | ||
278 | #define DA732X_MICBOOST_MASK 0x7 | ||
279 | #define DA732X_MICBOOST_SHIFT 0 | ||
280 | #define DA732X_MICBOOST_MIN 0x1 | ||
281 | #define DA732X_MICBOOST_MAX DA732X_MICBOOST_MASK | ||
282 | |||
283 | /* DA732X_REG_MIC1/2/3 (addr=0x13/0x15/0x19) */ | ||
284 | #define DA732X_MIC_VOL_SHIFT 0 | ||
285 | #define DA732X_MIC_VOL_VAL_MASK 0x1F | ||
286 | #define DA732X_MIC_MUTE_SHIFT 6 | ||
287 | #define DA732X_MIC_EN_SHIFT 7 | ||
288 | #define DA732X_MIC_VOL_VAL_MIN 0x7 | ||
289 | #define DA732X_MIC_VOL_VAL_MAX DA732X_MIC_VOL_VAL_MASK | ||
290 | |||
291 | /* DA732X_REG_AUX1L/R (addr=0x16/0x17) */ | ||
292 | #define DA732X_AUX_VOL_SHIFT 0 | ||
293 | #define DA732X_AUX_VOL_MASK 0x7 | ||
294 | #define DA732X_AUX_MUTE_SHIFT 6 | ||
295 | #define DA732X_AUX_EN_SHIFT 7 | ||
296 | #define DA732X_AUX_VOL_VAL_MAX DA732X_AUX_VOL_MASK | ||
297 | |||
298 | /* DA732X_REG_INP_PINBIAS (addr=0x1A) */ | ||
299 | #define DA732X_INP_MICL_PINBIAS_EN (1 << 0) | ||
300 | #define DA732X_INP_MICR_PINBIAS_EN (1 << 1) | ||
301 | #define DA732X_INP_AUX1L_PINBIAS_EN (1 << 2) | ||
302 | #define DA732X_INP_AUX1R_PINBIAS_EN (1 << 3) | ||
303 | #define DA732X_INP_AUX2_PINBIAS_EN (1 << 4) | ||
304 | |||
305 | /* DA732X_REG_INP_ZC_EN (addr=0x1B) */ | ||
306 | #define DA732X_MIC1_PRE_ZC_EN (1 << 0) | ||
307 | #define DA732X_MIC1_ZC_EN (1 << 1) | ||
308 | #define DA732X_MIC2_PRE_ZC_EN (1 << 2) | ||
309 | #define DA732X_MIC2_ZC_EN (1 << 3) | ||
310 | #define DA732X_AUXL_ZC_EN (1 << 4) | ||
311 | #define DA732X_AUXR_ZC_EN (1 << 5) | ||
312 | #define DA732X_MIC3_PRE_ZC_EN (1 << 6) | ||
313 | #define DA732X_MIC3_ZC_EN (1 << 7) | ||
314 | |||
315 | /* DA732X_REG_INP_MUX (addr=0x1D) */ | ||
316 | #define DA732X_INP_ADC1L_MUX_SEL_AUX1L (0 << 0) | ||
317 | #define DA732X_INP_ADC1L_MUX_SEL_MIC1 (1 << 0) | ||
318 | #define DA732X_INP_ADC1R_MUX_SEL_MASK (3 << 2) | ||
319 | #define DA732X_INP_ADC1R_MUX_SEL_AUX1R (0 << 2) | ||
320 | #define DA732X_INP_ADC1R_MUX_SEL_MIC2 (1 << 2) | ||
321 | #define DA732X_INP_ADC1R_MUX_SEL_MIC3 (2 << 2) | ||
322 | #define DA732X_INP_ADC2L_MUX_SEL_AUX1L (0 << 4) | ||
323 | #define DA732X_INP_ADC2L_MUX_SEL_MICL (1 << 4) | ||
324 | #define DA732X_INP_ADC2R_MUX_SEL_MASK (3 << 6) | ||
325 | #define DA732X_INP_ADC2R_MUX_SEL_AUX1R (0 << 6) | ||
326 | #define DA732X_INP_ADC2R_MUX_SEL_MICR (1 << 6) | ||
327 | #define DA732X_INP_ADC2R_MUX_SEL_AUX2 (2 << 6) | ||
328 | #define DA732X_ADC1L_MUX_SEL_SHIFT 0 | ||
329 | #define DA732X_ADC1R_MUX_SEL_SHIFT 2 | ||
330 | #define DA732X_ADC2L_MUX_SEL_SHIFT 4 | ||
331 | #define DA732X_ADC2R_MUX_SEL_SHIFT 6 | ||
332 | |||
333 | /* DA732X_REG_HP_DET (addr=0x20) */ | ||
334 | #define DA732X_HP_DET_AZ (1 << 0) | ||
335 | #define DA732X_HP_DET_SEL1 (1 << 1) | ||
336 | #define DA732X_HP_DET_IS_MASK (3 << 2) | ||
337 | #define DA732X_HP_DET_IS_0_5UA (0 << 2) | ||
338 | #define DA732X_HP_DET_IS_1UA (1 << 2) | ||
339 | #define DA732X_HP_DET_IS_2UA (2 << 2) | ||
340 | #define DA732X_HP_DET_IS_4UA (3 << 2) | ||
341 | #define DA732X_HP_DET_RS_MASK (3 << 4) | ||
342 | #define DA732X_HP_DET_RS_INFINITE (0 << 4) | ||
343 | #define DA732X_HP_DET_RS_100KOHM (1 << 4) | ||
344 | #define DA732X_HP_DET_RS_10KOHM (2 << 4) | ||
345 | #define DA732X_HP_DET_RS_1KOHM (3 << 4) | ||
346 | #define DA732X_HP_DET_EN (1 << 7) | ||
347 | |||
348 | /* DA732X_REG_HPL_DAC_OFFSET (addr=0x21/0x26) */ | ||
349 | #define DA732X_HP_DAC_OFFSET_TRIM_MASK (0x3F << 0) | ||
350 | #define DA732X_HP_DAC_OFFSET_DAC_SIGN (1 << 6) | ||
351 | |||
352 | /* DA732X_REG_HPL_DAC_OFF_CNTL (addr=0x22/0x27) */ | ||
353 | #define DA732X_HP_DAC_OFF_CNTL_CONT_MASK (7 << 0) | ||
354 | #define DA732X_HP_DAC_OFF_CNTL_COMPO (1 << 3) | ||
355 | #define DA732X_HP_DAC_OFF_CALIBRATION (1 << 0) | ||
356 | #define DA732X_HP_DAC_OFF_SCALE_STEPS (1 << 1) | ||
357 | #define DA732X_HP_DAC_OFF_MASK 0x7F | ||
358 | #define DA732X_HP_DAC_COMPO_SHIFT 3 | ||
359 | |||
360 | /* DA732X_REG_HPL_OUT_OFFSET (addr=0x23/0x28) */ | ||
361 | #define DA732X_HP_OUT_OFFSET_MASK (0xFF << 0) | ||
362 | #define DA732X_HP_DAC_OFFSET_TRIM_VAL 0x7F | ||
363 | |||
364 | /* DA732X_REG_HPL/R (addr=0x24/0x29) */ | ||
365 | #define DA732X_HP_OUT_SIGN (1 << 0) | ||
366 | #define DA732X_HP_OUT_COMP (1 << 1) | ||
367 | #define DA732X_HP_OUT_RESERVED (1 << 2) | ||
368 | #define DA732X_HP_OUT_COMPO (1 << 3) | ||
369 | #define DA732X_HP_OUT_DAC_EN (1 << 4) | ||
370 | #define DA732X_HP_OUT_HIZ_EN (1 << 5) | ||
371 | #define DA732X_HP_OUT_HIZ_DIS (0 << 5) | ||
372 | #define DA732X_HP_OUT_MUTE (1 << 6) | ||
373 | #define DA732X_HP_OUT_EN (1 << 7) | ||
374 | #define DA732X_HP_OUT_COMPO_SHIFT 3 | ||
375 | #define DA732X_HP_OUT_DAC_EN_SHIFT 4 | ||
376 | #define DA732X_HP_HIZ_SHIFT 5 | ||
377 | #define DA732X_HP_MUTE_SHIFT 6 | ||
378 | #define DA732X_HP_OUT_EN_SHIFT 7 | ||
379 | |||
380 | #define DA732X_OUT_HIZ_EN (1 << 5) | ||
381 | #define DA732X_OUT_HIZ_DIS (0 << 5) | ||
382 | |||
383 | /* DA732X_REG_HPL/R_VOL (addr=0x25/0x2A) */ | ||
384 | #define DA732X_HP_VOL_VAL_MASK 0xF | ||
385 | #define DA732X_HP_VOL_SHIFT 0 | ||
386 | #define DA732X_HP_VOL_VAL_MAX DA732X_HP_VOL_VAL_MASK | ||
387 | |||
388 | /* DA732X_REG_LIN2/3/4 (addr=0x2B/0x2C/0x2D) */ | ||
389 | #define DA732X_LOUT_VOL_SHIFT 0 | ||
390 | #define DA732X_LOUT_VOL_MASK 0x0F | ||
391 | #define DA732X_LOUT_DAC_OFF (0 << 4) | ||
392 | #define DA732X_LOUT_DAC_EN (1 << 4) | ||
393 | #define DA732X_LOUT_HIZ_N_DIS (0 << 5) | ||
394 | #define DA732X_LOUT_HIZ_N_EN (1 << 5) | ||
395 | #define DA732X_LOUT_UNMUTED (0 << 6) | ||
396 | #define DA732X_LOUT_MUTED (1 << 6) | ||
397 | #define DA732X_LOUT_EN (0 << 7) | ||
398 | #define DA732X_LOUT_DIS (1 << 7) | ||
399 | #define DA732X_LOUT_DAC_EN_SHIFT 4 | ||
400 | #define DA732X_LOUT_MUTE_SHIFT 6 | ||
401 | #define DA732X_LIN_OUT_EN_SHIFT 7 | ||
402 | #define DA732X_LOUT_VOL_VAL_MAX DA732X_LOUT_VOL_MASK | ||
403 | |||
404 | /* DA732X_REG_OUT_ZC_EN (addr=0x2E) */ | ||
405 | #define DA732X_HPL_ZC_EN_SHIFT 0 | ||
406 | #define DA732X_HPR_ZC_EN_SHIFT 1 | ||
407 | #define DA732X_HPL_ZC_EN (1 << 0) | ||
408 | #define DA732X_HPL_ZC_DIS (0 << 0) | ||
409 | #define DA732X_HPR_ZC_EN (1 << 1) | ||
410 | #define DA732X_HPR_ZC_DIS (0 << 1) | ||
411 | #define DA732X_LIN2_ZC_EN (1 << 2) | ||
412 | #define DA732X_LIN2_ZC_DIS (0 << 2) | ||
413 | #define DA732X_LIN3_ZC_EN (1 << 3) | ||
414 | #define DA732X_LIN3_ZC_DIS (0 << 3) | ||
415 | #define DA732X_LIN4_ZC_EN (1 << 4) | ||
416 | #define DA732X_LIN4_ZC_DIS (0 << 4) | ||
417 | |||
418 | /* DA732X_REG_HP_LIN1_GNDSEL (addr=0x37) */ | ||
419 | #define DA732X_HP_OUT_GNDSEL (1 << 0) | ||
420 | |||
421 | /* DA732X_REG_CP_HP2 (addr=0x3a) */ | ||
422 | #define DA732X_HP_CP_PULSESKIP (1 << 0) | ||
423 | #define DA732X_HP_CP_REG (1 << 1) | ||
424 | #define DA732X_HP_CP_EN (1 << 3) | ||
425 | #define DA732X_HP_CP_DIS (0 << 3) | ||
426 | |||
427 | /* DA732X_REG_CP_CTRL1 (addr=0x40) */ | ||
428 | #define DA732X_CP_MODE_MASK (7 << 1) | ||
429 | #define DA732X_CP_CTRL_STANDBY (0 << 1) | ||
430 | #define DA732X_CP_CTRL_CPVDD6 (2 << 1) | ||
431 | #define DA732X_CP_CTRL_CPVDD5 (3 << 1) | ||
432 | #define DA732X_CP_CTRL_CPVDD4 (4 << 1) | ||
433 | #define DA732X_CP_CTRL_CPVDD3 (5 << 1) | ||
434 | #define DA732X_CP_CTRL_CPVDD2 (6 << 1) | ||
435 | #define DA732X_CP_CTRL_CPVDD1 (7 << 1) | ||
436 | #define DA723X_CP_DIS (0 << 7) | ||
437 | #define DA732X_CP_EN (1 << 7) | ||
438 | |||
439 | /* DA732X_REG_CP_CTRL2 (addr=0x41) */ | ||
440 | #define DA732X_CP_BOOST (1 << 0) | ||
441 | #define DA732X_CP_MANAGE_MAGNITUDE (2 << 2) | ||
442 | |||
443 | /* DA732X_REG_CP_CTRL3 (addr=0x42) */ | ||
444 | #define DA732X_CP_1MHZ (0 << 0) | ||
445 | #define DA732X_CP_500KHZ (1 << 0) | ||
446 | #define DA732X_CP_250KHZ (2 << 0) | ||
447 | #define DA732X_CP_125KHZ (3 << 0) | ||
448 | #define DA732X_CP_63KHZ (4 << 0) | ||
449 | #define DA732X_CP_0KHZ (5 << 0) | ||
450 | |||
451 | /* DA732X_REG_PLL_CTRL (addr=0x53) */ | ||
452 | #define DA732X_PLL_INDIV_MASK (3 << 0) | ||
453 | #define DA732X_PLL_SRM_EN (1 << 2) | ||
454 | #define DA732X_PLL_EN (1 << 7) | ||
455 | #define DA732X_PLL_BYPASS (0 << 0) | ||
456 | |||
457 | /* DA732X_REG_CLK_CTRL (addr=0x54) */ | ||
458 | #define DA732X_SR1_MASK (0xF) | ||
459 | #define DA732X_SR2_MASK (0xF0) | ||
460 | |||
461 | /* DA732X_REG_CLK_DSP (addr=0x5A) */ | ||
462 | #define DA732X_DSP_FREQ_MASK (7 << 0) | ||
463 | #define DA732X_DSP_FREQ_12MHZ (0 << 0) | ||
464 | #define DA732X_DSP_FREQ_24MHZ (1 << 0) | ||
465 | #define DA732X_DSP_FREQ_36MHZ (2 << 0) | ||
466 | #define DA732X_DSP_FREQ_48MHZ (3 << 0) | ||
467 | #define DA732X_DSP_FREQ_60MHZ (4 << 0) | ||
468 | #define DA732X_DSP_FREQ_72MHZ (5 << 0) | ||
469 | #define DA732X_DSP_FREQ_84MHZ (6 << 0) | ||
470 | #define DA732X_DSP_FREQ_96MHZ (7 << 0) | ||
471 | |||
472 | /* DA732X_REG_CLK_EN1 (addr=0x5B) */ | ||
473 | #define DA732X_DSP_CLK_EN (1 << 0) | ||
474 | #define DA732X_SYS3_CLK_EN (1 << 1) | ||
475 | #define DA732X_DSP12_CLK_EN (1 << 2) | ||
476 | #define DA732X_PC_CLK_EN (1 << 3) | ||
477 | #define DA732X_MCLK_SQR_EN (1 << 7) | ||
478 | |||
479 | /* DA732X_REG_CLK_EN2 (addr=0x5C) */ | ||
480 | #define DA732X_UART_CLK_EN (1 << 1) | ||
481 | #define DA732X_CP_CLK_EN (1 << 2) | ||
482 | #define DA732X_CP_CLK_DIS (0 << 2) | ||
483 | |||
484 | /* DA732X_REG_CLK_EN3 (addr=0x5D) */ | ||
485 | #define DA732X_ADCA_BB_CLK_EN (1 << 0) | ||
486 | #define DA732X_ADCC_BB_CLK_EN (1 << 4) | ||
487 | |||
488 | /* DA732X_REG_CLK_EN4 (addr=0x5E) */ | ||
489 | #define DA732X_DACA_BB_CLK_EN (1 << 0) | ||
490 | #define DA732X_DACC_BB_CLK_EN (1 << 4) | ||
491 | #define DA732X_DACA_BB_CLK_SHIFT 0 | ||
492 | #define DA732X_DACC_BB_CLK_SHIFT 4 | ||
493 | |||
494 | /* DA732X_REG_CLK_EN5 (addr=0x5F) */ | ||
495 | #define DA732X_DACE_BB_CLK_EN (1 << 0) | ||
496 | #define DA732X_DACE_BB_CLK_SHIFT 0 | ||
497 | |||
498 | /* DA732X_REG_AIF_MCLK (addr=0x60) */ | ||
499 | #define DA732X_AIFM_FRAME_64 (1 << 2) | ||
500 | #define DA732X_AIFM_SRC_SEL_AIFA (1 << 6) | ||
501 | #define DA732X_CLK_GENERATION_AIF_A (1 << 4) | ||
502 | #define DA732X_NO_CLK_GENERATION 0x0 | ||
503 | |||
504 | /* DA732X_REG_AIFA1 (addr=0x61) */ | ||
505 | #define DA732X_AIF_WORD_MASK (0x3 << 0) | ||
506 | #define DA732X_AIF_WORD_16 (0 << 0) | ||
507 | #define DA732X_AIF_WORD_20 (1 << 0) | ||
508 | #define DA732X_AIF_WORD_24 (2 << 0) | ||
509 | #define DA732X_AIF_WORD_32 (3 << 0) | ||
510 | #define DA732X_AIF_TDM_MONO_SHIFT (1 << 6) | ||
511 | #define DA732X_AIF1_CLK_MASK (1 << 7) | ||
512 | #define DA732X_AIF_SLAVE (0 << 7) | ||
513 | #define DA732X_AIF_CLK_FROM_SRC (1 << 7) | ||
514 | |||
515 | /* DA732X_REG_AIFA3 (addr=0x63) */ | ||
516 | #define DA732X_AIF_MODE_SHIFT 0 | ||
517 | #define DA732X_AIF_MODE_MASK 0x3 | ||
518 | #define DA732X_AIF_I2S_MODE (0 << 0) | ||
519 | #define DA732X_AIF_LEFT_J_MODE (1 << 0) | ||
520 | #define DA732X_AIF_RIGHT_J_MODE (2 << 0) | ||
521 | #define DA732X_AIF_DSP_MODE (3 << 0) | ||
522 | #define DA732X_AIF_WCLK_INV (1 << 4) | ||
523 | #define DA732X_AIF_BCLK_INV (1 << 5) | ||
524 | #define DA732X_AIF_EN (1 << 7) | ||
525 | #define DA732X_AIF_EN_SHIFT 7 | ||
526 | |||
527 | /* DA732X_REG_PC_CTRL (addr=0x6a) */ | ||
528 | #define DA732X_PC_PULSE_AIFA (0 << 0) | ||
529 | #define DA732X_PC_PULSE_AIFB (1 << 0) | ||
530 | #define DA732X_PC_RESYNC_AUT (1 << 6) | ||
531 | #define DA732X_PC_RESYNC_NOT_AUT (0 << 6) | ||
532 | #define DA732X_PC_SAME (1 << 7) | ||
533 | |||
534 | /* DA732X_REG_DATA_ROUTE (addr=0x70) */ | ||
535 | #define DA732X_ADC1_TO_AIFA (0 << 0) | ||
536 | #define DA732X_DSP_TO_AIFA (1 << 0) | ||
537 | #define DA732X_ADC2_TO_AIFB (0 << 1) | ||
538 | #define DA732X_DSP_TO_AIFB (1 << 1) | ||
539 | #define DA732X_AIFA_TO_DAC1L (0 << 2) | ||
540 | #define DA732X_DSP_TO_DAC1L (1 << 2) | ||
541 | #define DA732X_AIFA_TO_DAC1R (0 << 3) | ||
542 | #define DA732X_DSP_TO_DAC1R (1 << 3) | ||
543 | #define DA732X_AIFB_TO_DAC2L (0 << 4) | ||
544 | #define DA732X_DSP_TO_DAC2L (1 << 4) | ||
545 | #define DA732X_AIFB_TO_DAC2R (0 << 5) | ||
546 | #define DA732X_DSP_TO_DAC2R (1 << 5) | ||
547 | #define DA732X_AIFB_TO_DAC3 (0 << 6) | ||
548 | #define DA732X_DSP_TO_DAC3 (1 << 6) | ||
549 | #define DA732X_BYPASS_DSP (0 << 0) | ||
550 | #define DA732X_ALL_TO_DSP (0x7F << 0) | ||
551 | |||
552 | /* DA732X_REG_DSP_CTRL (addr=0x71) */ | ||
553 | #define DA732X_DIGITAL_EN (1 << 0) | ||
554 | #define DA732X_DIGITAL_RESET (0 << 0) | ||
555 | #define DA732X_DSP_CORE_EN (1 << 1) | ||
556 | #define DA732X_DSP_CORE_RESET (0 << 1) | ||
557 | |||
558 | /* DA732X_REG_SPARE1_OUT (addr=0x7D)*/ | ||
559 | #define DA732X_HP_DRIVER_EN (1 << 0) | ||
560 | #define DA732X_HP_GATE_LOW (1 << 2) | ||
561 | #define DA732X_HP_LOOP_GAIN_CTRL (1 << 3) | ||
562 | |||
563 | /* DA732X_REG_ID (addr=0x81)*/ | ||
564 | #define DA732X_ID_MINOR_MASK (0xF << 0) | ||
565 | #define DA732X_ID_MAJOR_MASK (0xF << 4) | ||
566 | |||
567 | /* DA732X_REG_ADC1/2_PD (addr=0x90/0x98) */ | ||
568 | #define DA732X_ADC_RST_MASK (0x3 << 0) | ||
569 | #define DA732X_ADC_PD_MASK (0x3 << 2) | ||
570 | #define DA732X_ADC_SET_ACT (0x3 << 0) | ||
571 | #define DA732X_ADC_SET_RST (0x0 << 0) | ||
572 | #define DA732X_ADC_ON (0x3 << 2) | ||
573 | #define DA732X_ADC_OFF (0x0 << 2) | ||
574 | |||
575 | /* DA732X_REG_ADC1/2_SEL (addr=0x94/0x9C) */ | ||
576 | #define DA732X_ADC_VOL_VAL_MASK 0x7 | ||
577 | #define DA732X_ADCL_VOL_SHIFT 0 | ||
578 | #define DA732X_ADCR_VOL_SHIFT 4 | ||
579 | #define DA732X_ADCL_EN_SHIFT 2 | ||
580 | #define DA732X_ADCR_EN_SHIFT 3 | ||
581 | #define DA732X_ADCL_EN (1 << 2) | ||
582 | #define DA732X_ADCR_EN (1 << 3) | ||
583 | #define DA732X_ADC_VOL_VAL_MAX DA732X_ADC_VOL_VAL_MASK | ||
584 | |||
585 | /* | ||
586 | * DA732X_REG_ADC1/2_HPF (addr=0x93/0x9b) | ||
587 | * DA732x_REG_DAC1/2/3_HPG (addr=0xA5/0xB5/0xC5) | ||
588 | */ | ||
589 | #define DA732X_HPF_MUSIC_EN (1 << 3) | ||
590 | #define DA732X_HPF_VOICE_EN ((1 << 3) | (1 << 7)) | ||
591 | #define DA732X_HPF_MASK ((1 << 3) | (1 << 7)) | ||
592 | #define DA732X_HPF_DIS ((0 << 3) | (0 << 7)) | ||
593 | |||
594 | /* DA732X_REG_DAC1/2/3_VOL */ | ||
595 | #define DA732X_DAC_VOL_VAL_MASK 0x7F | ||
596 | #define DA732X_DAC_VOL_SHIFT 0 | ||
597 | #define DA732X_DAC_VOL_VAL_MAX DA732X_DAC_VOL_VAL_MASK | ||
598 | |||
599 | /* DA732X_REG_DAC1/2/3_SEL (addr=0xA3/0xB3/0xC3) */ | ||
600 | #define DA732X_DACL_EN_SHIFT 3 | ||
601 | #define DA732X_DACR_EN_SHIFT 7 | ||
602 | #define DA732X_DACL_MUTE_SHIFT 2 | ||
603 | #define DA732X_DACR_MUTE_SHIFT 6 | ||
604 | #define DA732X_DACL_EN (1 << 3) | ||
605 | #define DA732X_DACR_EN (1 << 7) | ||
606 | #define DA732X_DACL_SDM (1 << 0) | ||
607 | #define DA732X_DACR_SDM (1 << 4) | ||
608 | #define DA732X_DACL_MUTE (1 << 2) | ||
609 | #define DA732X_DACR_MUTE (1 << 6) | ||
610 | |||
611 | /* DA732X_REG_DAC_SOFTMUTE (addr=0xA4/0xB4/0xC4) */ | ||
612 | #define DA732X_SOFTMUTE_EN (1 << 7) | ||
613 | #define DA732X_GAIN_RAMPED (1 << 6) | ||
614 | #define DA732X_16_SAMPLES (4 << 0) | ||
615 | #define DA732X_SOFTMUTE_MASK (1 << 7) | ||
616 | #define DA732X_SOFTMUTE_SHIFT 7 | ||
617 | |||
618 | /* | ||
619 | * DA732x_REG_ADC1/2_EQ12 (addr=0x95/0x9D) | ||
620 | * DA732x_REG_ADC1/2_EQ34 (addr=0x96/0x9E) | ||
621 | * DA732x_REG_ADC1/2_EQ5 (addr=0x97/0x9F) | ||
622 | * DA732x_REG_DAC1/2/3_EQ12 (addr=0xA5/0xB5/0xC5) | ||
623 | * DA732x_REG_DAC1/2/3_EQ34 (addr=0xA6/0xB6/0xC6) | ||
624 | * DA732x_REG_DAC1/2/3_EQ5 (addr=0xA7/0xB7/0xB7) | ||
625 | */ | ||
626 | #define DA732X_EQ_VOL_VAL_MASK 0xF | ||
627 | #define DA732X_EQ_BAND1_SHIFT 0 | ||
628 | #define DA732X_EQ_BAND2_SHIFT 4 | ||
629 | #define DA732X_EQ_BAND3_SHIFT 0 | ||
630 | #define DA732X_EQ_BAND4_SHIFT 4 | ||
631 | #define DA732X_EQ_BAND5_SHIFT 0 | ||
632 | #define DA732X_EQ_OVERALL_SHIFT 4 | ||
633 | #define DA732X_EQ_OVERALL_VOL_VAL_MASK 0x3 | ||
634 | #define DA732X_EQ_DIS (0 << 7) | ||
635 | #define DA732X_EQ_EN (1 << 7) | ||
636 | #define DA732X_EQ_EN_SHIFT 7 | ||
637 | #define DA732X_EQ_VOL_VAL_MAX DA732X_EQ_VOL_VAL_MASK | ||
638 | #define DA732X_EQ_OVERALL_VOL_VAL_MAX DA732X_EQ_OVERALL_VOL_VAL_MASK | ||
639 | |||
640 | /* DA732X_REG_DMA_CMD (addr=0xD3) */ | ||
641 | #define DA732X_SEL_DSP_DMA_MASK (3 << 0) | ||
642 | #define DA732X_SEL_DSP_DMA_DIS (0 << 0) | ||
643 | #define DA732X_SEL_DSP_DMA_PMEM (1 << 0) | ||
644 | #define DA732X_SEL_DSP_DMA_XMEM (2 << 0) | ||
645 | #define DA732X_SEL_DSP_DMA_YMEM (3 << 0) | ||
646 | #define DA732X_DSP_RW_MASK (1 << 4) | ||
647 | #define DA732X_DSP_DMA_WRITE (0 << 4) | ||
648 | #define DA732X_DSP_DMA_READ (1 << 4) | ||
649 | |||
650 | /* DA732X_REG_DMA_STATUS (addr=0xDA) */ | ||
651 | #define DA732X_DSP_DMA_FREE (0 << 0) | ||
652 | #define DA732X_DSP_DMA_BUSY (1 << 0) | ||
653 | |||
654 | #endif /* __DA732X_REG_H_ */ | ||
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c new file mode 100644 index 000000000000..0d62f3b0f474 --- /dev/null +++ b/sound/soc/codecs/isabelle.c | |||
@@ -0,0 +1,1176 @@ | |||
1 | /* | ||
2 | * isabelle.c - Low power high fidelity audio codec driver | ||
3 | * | ||
4 | * Copyright (c) 2012 Texas Instruments, Inc | ||
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 as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * | ||
11 | * Initially based on sound/soc/codecs/twl6040.c | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | #include <linux/version.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/pm.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | #include <sound/soc-dapm.h> | ||
29 | #include <sound/tlv.h> | ||
30 | #include <sound/jack.h> | ||
31 | #include <sound/initval.h> | ||
32 | #include <asm/div64.h> | ||
33 | #include "isabelle.h" | ||
34 | |||
35 | |||
36 | /* Register default values for ISABELLE driver. */ | ||
37 | static struct reg_default isabelle_reg_defs[] = { | ||
38 | { 0, 0x00 }, | ||
39 | { 1, 0x00 }, | ||
40 | { 2, 0x00 }, | ||
41 | { 3, 0x00 }, | ||
42 | { 4, 0x00 }, | ||
43 | { 5, 0x00 }, | ||
44 | { 6, 0x00 }, | ||
45 | { 7, 0x00 }, | ||
46 | { 8, 0x00 }, | ||
47 | { 9, 0x00 }, | ||
48 | { 10, 0x00 }, | ||
49 | { 11, 0x00 }, | ||
50 | { 12, 0x00 }, | ||
51 | { 13, 0x00 }, | ||
52 | { 14, 0x00 }, | ||
53 | { 15, 0x00 }, | ||
54 | { 16, 0x00 }, | ||
55 | { 17, 0x00 }, | ||
56 | { 18, 0x00 }, | ||
57 | { 19, 0x00 }, | ||
58 | { 20, 0x00 }, | ||
59 | { 21, 0x02 }, | ||
60 | { 22, 0x02 }, | ||
61 | { 23, 0x02 }, | ||
62 | { 24, 0x02 }, | ||
63 | { 25, 0x0F }, | ||
64 | { 26, 0x8F }, | ||
65 | { 27, 0x0F }, | ||
66 | { 28, 0x8F }, | ||
67 | { 29, 0x00 }, | ||
68 | { 30, 0x00 }, | ||
69 | { 31, 0x00 }, | ||
70 | { 32, 0x00 }, | ||
71 | { 33, 0x00 }, | ||
72 | { 34, 0x00 }, | ||
73 | { 35, 0x00 }, | ||
74 | { 36, 0x00 }, | ||
75 | { 37, 0x00 }, | ||
76 | { 38, 0x00 }, | ||
77 | { 39, 0x00 }, | ||
78 | { 40, 0x00 }, | ||
79 | { 41, 0x00 }, | ||
80 | { 42, 0x00 }, | ||
81 | { 43, 0x00 }, | ||
82 | { 44, 0x00 }, | ||
83 | { 45, 0x00 }, | ||
84 | { 46, 0x00 }, | ||
85 | { 47, 0x00 }, | ||
86 | { 48, 0x00 }, | ||
87 | { 49, 0x00 }, | ||
88 | { 50, 0x00 }, | ||
89 | { 51, 0x00 }, | ||
90 | { 52, 0x00 }, | ||
91 | { 53, 0x00 }, | ||
92 | { 54, 0x00 }, | ||
93 | { 55, 0x00 }, | ||
94 | { 56, 0x00 }, | ||
95 | { 57, 0x00 }, | ||
96 | { 58, 0x00 }, | ||
97 | { 59, 0x00 }, | ||
98 | { 60, 0x00 }, | ||
99 | { 61, 0x00 }, | ||
100 | { 62, 0x00 }, | ||
101 | { 63, 0x00 }, | ||
102 | { 64, 0x00 }, | ||
103 | { 65, 0x00 }, | ||
104 | { 66, 0x00 }, | ||
105 | { 67, 0x00 }, | ||
106 | { 68, 0x00 }, | ||
107 | { 69, 0x90 }, | ||
108 | { 70, 0x90 }, | ||
109 | { 71, 0x90 }, | ||
110 | { 72, 0x00 }, | ||
111 | { 73, 0x00 }, | ||
112 | { 74, 0x00 }, | ||
113 | { 75, 0x00 }, | ||
114 | { 76, 0x00 }, | ||
115 | { 77, 0x00 }, | ||
116 | { 78, 0x00 }, | ||
117 | { 79, 0x00 }, | ||
118 | { 80, 0x00 }, | ||
119 | { 81, 0x00 }, | ||
120 | { 82, 0x00 }, | ||
121 | { 83, 0x00 }, | ||
122 | { 84, 0x00 }, | ||
123 | { 85, 0x07 }, | ||
124 | { 86, 0x00 }, | ||
125 | { 87, 0x00 }, | ||
126 | { 88, 0x00 }, | ||
127 | { 89, 0x07 }, | ||
128 | { 90, 0x80 }, | ||
129 | { 91, 0x07 }, | ||
130 | { 92, 0x07 }, | ||
131 | { 93, 0x00 }, | ||
132 | { 94, 0x00 }, | ||
133 | { 95, 0x00 }, | ||
134 | { 96, 0x00 }, | ||
135 | { 97, 0x00 }, | ||
136 | { 98, 0x00 }, | ||
137 | { 99, 0x00 }, | ||
138 | }; | ||
139 | |||
140 | static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"}; | ||
141 | static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"}; | ||
142 | |||
143 | static const struct soc_enum isabelle_rx1_enum[] = { | ||
144 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts), | ||
145 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts), | ||
146 | }; | ||
147 | |||
148 | static const struct soc_enum isabelle_rx2_enum[] = { | ||
149 | SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts), | ||
150 | SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts), | ||
151 | }; | ||
152 | |||
153 | /* Headset DAC playback switches */ | ||
154 | static const struct snd_kcontrol_new rx1_mux_controls = | ||
155 | SOC_DAPM_ENUM("Route", isabelle_rx1_enum); | ||
156 | |||
157 | static const struct snd_kcontrol_new rx2_mux_controls = | ||
158 | SOC_DAPM_ENUM("Route", isabelle_rx2_enum); | ||
159 | |||
160 | /* TX input selection */ | ||
161 | static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"}; | ||
162 | static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"}; | ||
163 | |||
164 | static const struct soc_enum isabelle_atx_enum[] = { | ||
165 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts), | ||
166 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts), | ||
167 | }; | ||
168 | |||
169 | static const struct soc_enum isabelle_vtx_enum[] = { | ||
170 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts), | ||
171 | SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts), | ||
172 | }; | ||
173 | |||
174 | static const struct snd_kcontrol_new atx_mux_controls = | ||
175 | SOC_DAPM_ENUM("Route", isabelle_atx_enum); | ||
176 | |||
177 | static const struct snd_kcontrol_new vtx_mux_controls = | ||
178 | SOC_DAPM_ENUM("Route", isabelle_vtx_enum); | ||
179 | |||
180 | /* Left analog microphone selection */ | ||
181 | static const char *isabelle_amic1_texts[] = { | ||
182 | "Main Mic", "Headset Mic", "Aux/FM Left"}; | ||
183 | |||
184 | /* Left analog microphone selection */ | ||
185 | static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"}; | ||
186 | |||
187 | static const struct soc_enum isabelle_amic1_enum[] = { | ||
188 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5, | ||
189 | ARRAY_SIZE(isabelle_amic1_texts), | ||
190 | isabelle_amic1_texts), | ||
191 | }; | ||
192 | |||
193 | static const struct soc_enum isabelle_amic2_enum[] = { | ||
194 | SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4, | ||
195 | ARRAY_SIZE(isabelle_amic2_texts), | ||
196 | isabelle_amic2_texts), | ||
197 | }; | ||
198 | |||
199 | static const struct snd_kcontrol_new amic1_control = | ||
200 | SOC_DAPM_ENUM("Route", isabelle_amic1_enum); | ||
201 | |||
202 | static const struct snd_kcontrol_new amic2_control = | ||
203 | SOC_DAPM_ENUM("Route", isabelle_amic2_enum); | ||
204 | |||
205 | static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"}; | ||
206 | |||
207 | static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"}; | ||
208 | |||
209 | static const struct soc_enum isabelle_st_audio_enum[] = { | ||
210 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1, | ||
211 | isabelle_st_audio_texts), | ||
212 | SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1, | ||
213 | isabelle_st_audio_texts), | ||
214 | }; | ||
215 | |||
216 | static const struct soc_enum isabelle_st_voice_enum[] = { | ||
217 | SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1, | ||
218 | isabelle_st_voice_texts), | ||
219 | SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1, | ||
220 | isabelle_st_voice_texts), | ||
221 | }; | ||
222 | |||
223 | static const struct snd_kcontrol_new st_audio_control = | ||
224 | SOC_DAPM_ENUM("Route", isabelle_st_audio_enum); | ||
225 | |||
226 | static const struct snd_kcontrol_new st_voice_control = | ||
227 | SOC_DAPM_ENUM("Route", isabelle_st_voice_enum); | ||
228 | |||
229 | /* Mixer controls */ | ||
230 | static const struct snd_kcontrol_new isabelle_hs_left_mixer_controls[] = { | ||
231 | SOC_DAPM_SINGLE("DAC1L Playback Switch", ISABELLE_HSDRV_CFG1_REG, 7, 1, 0), | ||
232 | SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 6, 1, 0), | ||
233 | }; | ||
234 | |||
235 | static const struct snd_kcontrol_new isabelle_hs_right_mixer_controls[] = { | ||
236 | SOC_DAPM_SINGLE("DAC1R Playback Switch", ISABELLE_HSDRV_CFG1_REG, 5, 1, 0), | ||
237 | SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 4, 1, 0), | ||
238 | }; | ||
239 | |||
240 | static const struct snd_kcontrol_new isabelle_hf_left_mixer_controls[] = { | ||
241 | SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_HFLPGA_CFG_REG, 7, 1, 0), | ||
242 | SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HFLPGA_CFG_REG, 6, 1, 0), | ||
243 | }; | ||
244 | |||
245 | static const struct snd_kcontrol_new isabelle_hf_right_mixer_controls[] = { | ||
246 | SOC_DAPM_SINGLE("DAC2R Playback Switch", ISABELLE_HFRPGA_CFG_REG, 7, 1, 0), | ||
247 | SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HFRPGA_CFG_REG, 6, 1, 0), | ||
248 | }; | ||
249 | |||
250 | static const struct snd_kcontrol_new isabelle_ep_mixer_controls[] = { | ||
251 | SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_EARDRV_CFG1_REG, 7, 1, 0), | ||
252 | SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_EARDRV_CFG1_REG, 6, 1, 0), | ||
253 | }; | ||
254 | |||
255 | static const struct snd_kcontrol_new isabelle_aux_left_mixer_controls[] = { | ||
256 | SOC_DAPM_SINGLE("DAC3L Playback Switch", ISABELLE_LINEAMP_CFG_REG, 7, 1, 0), | ||
257 | SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 6, 1, 0), | ||
258 | }; | ||
259 | |||
260 | static const struct snd_kcontrol_new isabelle_aux_right_mixer_controls[] = { | ||
261 | SOC_DAPM_SINGLE("DAC3R Playback Switch", ISABELLE_LINEAMP_CFG_REG, 5, 1, 0), | ||
262 | SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 4, 1, 0), | ||
263 | }; | ||
264 | |||
265 | static const struct snd_kcontrol_new isabelle_dpga1_left_mixer_controls[] = { | ||
266 | SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 7, 1, 0), | ||
267 | SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 6, 1, 0), | ||
268 | SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 5, 1, 0), | ||
269 | }; | ||
270 | |||
271 | static const struct snd_kcontrol_new isabelle_dpga1_right_mixer_controls[] = { | ||
272 | SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 3, 1, 0), | ||
273 | SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 2, 1, 0), | ||
274 | SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 1, 1, 0), | ||
275 | }; | ||
276 | |||
277 | static const struct snd_kcontrol_new isabelle_dpga2_left_mixer_controls[] = { | ||
278 | SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 7, 1, 0), | ||
279 | SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 6, 1, 0), | ||
280 | SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 5, 1, 0), | ||
281 | SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 4, 1, 0), | ||
282 | SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 3, 1, 0), | ||
283 | SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 2, 1, 0), | ||
284 | }; | ||
285 | |||
286 | static const struct snd_kcontrol_new isabelle_dpga2_right_mixer_controls[] = { | ||
287 | SOC_DAPM_SINGLE("USNC Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 7, 1, 0), | ||
288 | SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 3, 1, 0), | ||
289 | SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 2, 1, 0), | ||
290 | SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 1, 1, 0), | ||
291 | }; | ||
292 | |||
293 | static const struct snd_kcontrol_new isabelle_dpga3_left_mixer_controls[] = { | ||
294 | SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 7, 1, 0), | ||
295 | SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 6, 1, 0), | ||
296 | SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 5, 1, 0), | ||
297 | }; | ||
298 | |||
299 | static const struct snd_kcontrol_new isabelle_dpga3_right_mixer_controls[] = { | ||
300 | SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 3, 1, 0), | ||
301 | SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 2, 1, 0), | ||
302 | SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 1, 1, 0), | ||
303 | }; | ||
304 | |||
305 | static const struct snd_kcontrol_new isabelle_rx1_mixer_controls[] = { | ||
306 | SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 7, 1, 0), | ||
307 | SOC_DAPM_SINGLE("DL1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 6, 1, 0), | ||
308 | }; | ||
309 | |||
310 | static const struct snd_kcontrol_new isabelle_rx2_mixer_controls[] = { | ||
311 | SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 5, 1, 0), | ||
312 | SOC_DAPM_SINGLE("DL2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 4, 1, 0), | ||
313 | }; | ||
314 | |||
315 | static const struct snd_kcontrol_new isabelle_rx3_mixer_controls[] = { | ||
316 | SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 3, 1, 0), | ||
317 | SOC_DAPM_SINGLE("DL3 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 2, 1, 0), | ||
318 | }; | ||
319 | |||
320 | static const struct snd_kcontrol_new isabelle_rx4_mixer_controls[] = { | ||
321 | SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 1, 1, 0), | ||
322 | SOC_DAPM_SINGLE("DL4 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 0, 1, 0), | ||
323 | }; | ||
324 | |||
325 | static const struct snd_kcontrol_new isabelle_rx5_mixer_controls[] = { | ||
326 | SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 7, 1, 0), | ||
327 | SOC_DAPM_SINGLE("DL5 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 6, 1, 0), | ||
328 | }; | ||
329 | |||
330 | static const struct snd_kcontrol_new isabelle_rx6_mixer_controls[] = { | ||
331 | SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 5, 1, 0), | ||
332 | SOC_DAPM_SINGLE("DL6 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 4, 1, 0), | ||
333 | }; | ||
334 | |||
335 | static const struct snd_kcontrol_new ep_path_enable_control = | ||
336 | SOC_DAPM_SINGLE("Switch", ISABELLE_EARDRV_CFG2_REG, 0, 1, 0); | ||
337 | |||
338 | /* TLV Declarations */ | ||
339 | static const DECLARE_TLV_DB_SCALE(mic_amp_tlv, 0, 100, 0); | ||
340 | static const DECLARE_TLV_DB_SCALE(afm_amp_tlv, -3300, 300, 0); | ||
341 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -1200, 200, 0); | ||
342 | static const DECLARE_TLV_DB_SCALE(hf_tlv, -5000, 200, 0); | ||
343 | |||
344 | /* from -63 to 0 dB in 1 dB steps */ | ||
345 | static const DECLARE_TLV_DB_SCALE(dpga_tlv, -6300, 100, 1); | ||
346 | |||
347 | /* from -63 to 9 dB in 1 dB steps */ | ||
348 | static const DECLARE_TLV_DB_SCALE(rx_tlv, -6300, 100, 1); | ||
349 | |||
350 | static const DECLARE_TLV_DB_SCALE(st_tlv, -2700, 300, 1); | ||
351 | static const DECLARE_TLV_DB_SCALE(tx_tlv, -600, 100, 0); | ||
352 | |||
353 | static const struct snd_kcontrol_new isabelle_snd_controls[] = { | ||
354 | SOC_DOUBLE_TLV("Headset Playback Volume", ISABELLE_HSDRV_GAIN_REG, | ||
355 | 4, 0, 0xF, 0, dac_tlv), | ||
356 | SOC_DOUBLE_R_TLV("Handsfree Playback Volume", | ||
357 | ISABELLE_HFLPGA_CFG_REG, ISABELLE_HFRPGA_CFG_REG, | ||
358 | 0, 0x1F, 0, hf_tlv), | ||
359 | SOC_DOUBLE_TLV("Aux Playback Volume", ISABELLE_LINEAMP_GAIN_REG, | ||
360 | 4, 0, 0xF, 0, dac_tlv), | ||
361 | SOC_SINGLE_TLV("Earpiece Playback Volume", ISABELLE_EARDRV_CFG1_REG, | ||
362 | 0, 0xF, 0, dac_tlv), | ||
363 | |||
364 | SOC_DOUBLE_TLV("Aux FM Volume", ISABELLE_APGA_GAIN_REG, 4, 0, 0xF, 0, | ||
365 | afm_amp_tlv), | ||
366 | SOC_SINGLE_TLV("Mic1 Capture Volume", ISABELLE_MIC1_GAIN_REG, 3, 0x1F, | ||
367 | 0, mic_amp_tlv), | ||
368 | SOC_SINGLE_TLV("Mic2 Capture Volume", ISABELLE_MIC2_GAIN_REG, 3, 0x1F, | ||
369 | 0, mic_amp_tlv), | ||
370 | |||
371 | SOC_DOUBLE_R_TLV("DPGA1 Volume", ISABELLE_DPGA1L_GAIN_REG, | ||
372 | ISABELLE_DPGA1R_GAIN_REG, 0, 0x3F, 0, dpga_tlv), | ||
373 | SOC_DOUBLE_R_TLV("DPGA2 Volume", ISABELLE_DPGA2L_GAIN_REG, | ||
374 | ISABELLE_DPGA2R_GAIN_REG, 0, 0x3F, 0, dpga_tlv), | ||
375 | SOC_DOUBLE_R_TLV("DPGA3 Volume", ISABELLE_DPGA3L_GAIN_REG, | ||
376 | ISABELLE_DPGA3R_GAIN_REG, 0, 0x3F, 0, dpga_tlv), | ||
377 | |||
378 | SOC_SINGLE_TLV("Sidetone Audio TX1 Volume", | ||
379 | ISABELLE_ATX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv), | ||
380 | SOC_SINGLE_TLV("Sidetone Audio TX2 Volume", | ||
381 | ISABELLE_ATX_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv), | ||
382 | SOC_SINGLE_TLV("Sidetone Voice TX1 Volume", | ||
383 | ISABELLE_VTX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv), | ||
384 | SOC_SINGLE_TLV("Sidetone Voice TX2 Volume", | ||
385 | ISABELLE_VTX2_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv), | ||
386 | |||
387 | SOC_SINGLE_TLV("Audio TX1 Volume", ISABELLE_ATX1_DPGA_REG, 4, 0xF, 0, | ||
388 | tx_tlv), | ||
389 | SOC_SINGLE_TLV("Audio TX2 Volume", ISABELLE_ATX2_DPGA_REG, 4, 0xF, 0, | ||
390 | tx_tlv), | ||
391 | SOC_SINGLE_TLV("Voice TX1 Volume", ISABELLE_VTX1_DPGA_REG, 4, 0xF, 0, | ||
392 | tx_tlv), | ||
393 | SOC_SINGLE_TLV("Voice TX2 Volume", ISABELLE_VTX2_DPGA_REG, 4, 0xF, 0, | ||
394 | tx_tlv), | ||
395 | |||
396 | SOC_SINGLE_TLV("RX1 DPGA Volume", ISABELLE_RX1_DPGA_REG, 0, 0x3F, 0, | ||
397 | rx_tlv), | ||
398 | SOC_SINGLE_TLV("RX2 DPGA Volume", ISABELLE_RX2_DPGA_REG, 0, 0x3F, 0, | ||
399 | rx_tlv), | ||
400 | SOC_SINGLE_TLV("RX3 DPGA Volume", ISABELLE_RX3_DPGA_REG, 0, 0x3F, 0, | ||
401 | rx_tlv), | ||
402 | SOC_SINGLE_TLV("RX4 DPGA Volume", ISABELLE_RX4_DPGA_REG, 0, 0x3F, 0, | ||
403 | rx_tlv), | ||
404 | SOC_SINGLE_TLV("RX5 DPGA Volume", ISABELLE_RX5_DPGA_REG, 0, 0x3F, 0, | ||
405 | rx_tlv), | ||
406 | SOC_SINGLE_TLV("RX6 DPGA Volume", ISABELLE_RX6_DPGA_REG, 0, 0x3F, 0, | ||
407 | rx_tlv), | ||
408 | |||
409 | SOC_SINGLE("Headset Noise Gate", ISABELLE_HS_NG_CFG1_REG, 7, 1, 0), | ||
410 | SOC_SINGLE("Handsfree Noise Gate", ISABELLE_HF_NG_CFG1_REG, 7, 1, 0), | ||
411 | |||
412 | SOC_SINGLE("ATX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
413 | 7, 1, 0), | ||
414 | SOC_SINGLE("ATX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
415 | 6, 1, 0), | ||
416 | SOC_SINGLE("ARX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
417 | 5, 1, 0), | ||
418 | SOC_SINGLE("ARX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
419 | 4, 1, 0), | ||
420 | SOC_SINGLE("ARX3 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
421 | 3, 1, 0), | ||
422 | SOC_SINGLE("ARX4 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
423 | 2, 1, 0), | ||
424 | SOC_SINGLE("ARX5 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
425 | 1, 1, 0), | ||
426 | SOC_SINGLE("ARX6 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
427 | 0, 1, 0), | ||
428 | SOC_SINGLE("VRX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
429 | 3, 1, 0), | ||
430 | SOC_SINGLE("VRX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG, | ||
431 | 2, 1, 0), | ||
432 | |||
433 | SOC_SINGLE("ATX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, | ||
434 | 7, 1, 0), | ||
435 | SOC_SINGLE("ATX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, | ||
436 | 6, 1, 0), | ||
437 | SOC_SINGLE("VTX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, | ||
438 | 5, 1, 0), | ||
439 | SOC_SINGLE("VTX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG, | ||
440 | 4, 1, 0), | ||
441 | SOC_SINGLE("RX1 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, | ||
442 | 5, 1, 0), | ||
443 | SOC_SINGLE("RX2 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, | ||
444 | 4, 1, 0), | ||
445 | SOC_SINGLE("RX3 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, | ||
446 | 3, 1, 0), | ||
447 | SOC_SINGLE("RX4 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, | ||
448 | 2, 1, 0), | ||
449 | SOC_SINGLE("RX5 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, | ||
450 | 1, 1, 0), | ||
451 | SOC_SINGLE("RX6 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG, | ||
452 | 0, 1, 0), | ||
453 | |||
454 | SOC_SINGLE("ULATX12 Capture Switch", ISABELLE_ULATX12_INTF_CFG_REG, | ||
455 | 7, 1, 0), | ||
456 | |||
457 | SOC_SINGLE("DL12 Playback Switch", ISABELLE_DL12_INTF_CFG_REG, | ||
458 | 7, 1, 0), | ||
459 | SOC_SINGLE("DL34 Playback Switch", ISABELLE_DL34_INTF_CFG_REG, | ||
460 | 7, 1, 0), | ||
461 | SOC_SINGLE("DL56 Playback Switch", ISABELLE_DL56_INTF_CFG_REG, | ||
462 | 7, 1, 0), | ||
463 | |||
464 | /* DMIC Switch */ | ||
465 | SOC_SINGLE("DMIC Switch", ISABELLE_DMIC_CFG_REG, 0, 1, 0), | ||
466 | }; | ||
467 | |||
468 | static const struct snd_soc_dapm_widget isabelle_dapm_widgets[] = { | ||
469 | /* Inputs */ | ||
470 | SND_SOC_DAPM_INPUT("MAINMIC"), | ||
471 | SND_SOC_DAPM_INPUT("HSMIC"), | ||
472 | SND_SOC_DAPM_INPUT("SUBMIC"), | ||
473 | SND_SOC_DAPM_INPUT("LINEIN1"), | ||
474 | SND_SOC_DAPM_INPUT("LINEIN2"), | ||
475 | SND_SOC_DAPM_INPUT("DMICDAT"), | ||
476 | |||
477 | /* Outputs */ | ||
478 | SND_SOC_DAPM_OUTPUT("HSOL"), | ||
479 | SND_SOC_DAPM_OUTPUT("HSOR"), | ||
480 | SND_SOC_DAPM_OUTPUT("HFL"), | ||
481 | SND_SOC_DAPM_OUTPUT("HFR"), | ||
482 | SND_SOC_DAPM_OUTPUT("EP"), | ||
483 | SND_SOC_DAPM_OUTPUT("LINEOUT1"), | ||
484 | SND_SOC_DAPM_OUTPUT("LINEOUT2"), | ||
485 | |||
486 | SND_SOC_DAPM_PGA("DL1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
487 | SND_SOC_DAPM_PGA("DL2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
488 | SND_SOC_DAPM_PGA("DL3", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
489 | SND_SOC_DAPM_PGA("DL4", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
490 | SND_SOC_DAPM_PGA("DL5", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
491 | SND_SOC_DAPM_PGA("DL6", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
492 | |||
493 | /* Analog input muxes for the capture amplifiers */ | ||
494 | SND_SOC_DAPM_MUX("Analog Left Capture Route", | ||
495 | SND_SOC_NOPM, 0, 0, &amic1_control), | ||
496 | SND_SOC_DAPM_MUX("Analog Right Capture Route", | ||
497 | SND_SOC_NOPM, 0, 0, &amic2_control), | ||
498 | |||
499 | SND_SOC_DAPM_MUX("Sidetone Audio Playback", SND_SOC_NOPM, 0, 0, | ||
500 | &st_audio_control), | ||
501 | SND_SOC_DAPM_MUX("Sidetone Voice Playback", SND_SOC_NOPM, 0, 0, | ||
502 | &st_voice_control), | ||
503 | |||
504 | /* AIF */ | ||
505 | SND_SOC_DAPM_AIF_IN("INTF1_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 7, 0), | ||
506 | SND_SOC_DAPM_AIF_IN("INTF2_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 6, 0), | ||
507 | |||
508 | SND_SOC_DAPM_AIF_OUT("INTF1_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 5, 0), | ||
509 | SND_SOC_DAPM_AIF_OUT("INTF2_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 4, 0), | ||
510 | |||
511 | SND_SOC_DAPM_OUT_DRV("ULATX1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
512 | SND_SOC_DAPM_OUT_DRV("ULATX2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
513 | SND_SOC_DAPM_OUT_DRV("ULVTX1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
514 | SND_SOC_DAPM_OUT_DRV("ULVTX2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
515 | |||
516 | /* Analog Capture PGAs */ | ||
517 | SND_SOC_DAPM_PGA("MicAmp1", ISABELLE_AMIC_CFG_REG, 5, 0, NULL, 0), | ||
518 | SND_SOC_DAPM_PGA("MicAmp2", ISABELLE_AMIC_CFG_REG, 4, 0, NULL, 0), | ||
519 | |||
520 | /* Auxiliary FM PGAs */ | ||
521 | SND_SOC_DAPM_PGA("APGA1", ISABELLE_APGA_CFG_REG, 7, 0, NULL, 0), | ||
522 | SND_SOC_DAPM_PGA("APGA2", ISABELLE_APGA_CFG_REG, 6, 0, NULL, 0), | ||
523 | |||
524 | /* ADCs */ | ||
525 | SND_SOC_DAPM_ADC("ADC1", "Left Front Capture", | ||
526 | ISABELLE_AMIC_CFG_REG, 7, 0), | ||
527 | SND_SOC_DAPM_ADC("ADC2", "Right Front Capture", | ||
528 | ISABELLE_AMIC_CFG_REG, 6, 0), | ||
529 | |||
530 | /* Microphone Bias */ | ||
531 | SND_SOC_DAPM_SUPPLY("Headset Mic Bias", ISABELLE_ABIAS_CFG_REG, | ||
532 | 3, 0, NULL, 0), | ||
533 | SND_SOC_DAPM_SUPPLY("Main Mic Bias", ISABELLE_ABIAS_CFG_REG, | ||
534 | 2, 0, NULL, 0), | ||
535 | SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias", | ||
536 | ISABELLE_DBIAS_CFG_REG, 3, 0, NULL, 0), | ||
537 | SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias", | ||
538 | ISABELLE_DBIAS_CFG_REG, 2, 0, NULL, 0), | ||
539 | |||
540 | /* Mixers */ | ||
541 | SND_SOC_DAPM_MIXER("Headset Left Mixer", SND_SOC_NOPM, 0, 0, | ||
542 | isabelle_hs_left_mixer_controls, | ||
543 | ARRAY_SIZE(isabelle_hs_left_mixer_controls)), | ||
544 | SND_SOC_DAPM_MIXER("Headset Right Mixer", SND_SOC_NOPM, 0, 0, | ||
545 | isabelle_hs_right_mixer_controls, | ||
546 | ARRAY_SIZE(isabelle_hs_right_mixer_controls)), | ||
547 | SND_SOC_DAPM_MIXER("Handsfree Left Mixer", SND_SOC_NOPM, 0, 0, | ||
548 | isabelle_hf_left_mixer_controls, | ||
549 | ARRAY_SIZE(isabelle_hf_left_mixer_controls)), | ||
550 | SND_SOC_DAPM_MIXER("Handsfree Right Mixer", SND_SOC_NOPM, 0, 0, | ||
551 | isabelle_hf_right_mixer_controls, | ||
552 | ARRAY_SIZE(isabelle_hf_right_mixer_controls)), | ||
553 | SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, | ||
554 | isabelle_aux_left_mixer_controls, | ||
555 | ARRAY_SIZE(isabelle_aux_left_mixer_controls)), | ||
556 | SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0, | ||
557 | isabelle_aux_right_mixer_controls, | ||
558 | ARRAY_SIZE(isabelle_aux_right_mixer_controls)), | ||
559 | SND_SOC_DAPM_MIXER("Earphone Mixer", SND_SOC_NOPM, 0, 0, | ||
560 | isabelle_ep_mixer_controls, | ||
561 | ARRAY_SIZE(isabelle_ep_mixer_controls)), | ||
562 | |||
563 | SND_SOC_DAPM_MIXER("DPGA1L Mixer", SND_SOC_NOPM, 0, 0, | ||
564 | isabelle_dpga1_left_mixer_controls, | ||
565 | ARRAY_SIZE(isabelle_dpga1_left_mixer_controls)), | ||
566 | SND_SOC_DAPM_MIXER("DPGA1R Mixer", SND_SOC_NOPM, 0, 0, | ||
567 | isabelle_dpga1_right_mixer_controls, | ||
568 | ARRAY_SIZE(isabelle_dpga1_right_mixer_controls)), | ||
569 | SND_SOC_DAPM_MIXER("DPGA2L Mixer", SND_SOC_NOPM, 0, 0, | ||
570 | isabelle_dpga2_left_mixer_controls, | ||
571 | ARRAY_SIZE(isabelle_dpga2_left_mixer_controls)), | ||
572 | SND_SOC_DAPM_MIXER("DPGA2R Mixer", SND_SOC_NOPM, 0, 0, | ||
573 | isabelle_dpga2_right_mixer_controls, | ||
574 | ARRAY_SIZE(isabelle_dpga2_right_mixer_controls)), | ||
575 | SND_SOC_DAPM_MIXER("DPGA3L Mixer", SND_SOC_NOPM, 0, 0, | ||
576 | isabelle_dpga3_left_mixer_controls, | ||
577 | ARRAY_SIZE(isabelle_dpga3_left_mixer_controls)), | ||
578 | SND_SOC_DAPM_MIXER("DPGA3R Mixer", SND_SOC_NOPM, 0, 0, | ||
579 | isabelle_dpga3_right_mixer_controls, | ||
580 | ARRAY_SIZE(isabelle_dpga3_right_mixer_controls)), | ||
581 | |||
582 | SND_SOC_DAPM_MIXER("RX1 Mixer", SND_SOC_NOPM, 0, 0, | ||
583 | isabelle_rx1_mixer_controls, | ||
584 | ARRAY_SIZE(isabelle_rx1_mixer_controls)), | ||
585 | SND_SOC_DAPM_MIXER("RX2 Mixer", SND_SOC_NOPM, 0, 0, | ||
586 | isabelle_rx2_mixer_controls, | ||
587 | ARRAY_SIZE(isabelle_rx2_mixer_controls)), | ||
588 | SND_SOC_DAPM_MIXER("RX3 Mixer", SND_SOC_NOPM, 0, 0, | ||
589 | isabelle_rx3_mixer_controls, | ||
590 | ARRAY_SIZE(isabelle_rx3_mixer_controls)), | ||
591 | SND_SOC_DAPM_MIXER("RX4 Mixer", SND_SOC_NOPM, 0, 0, | ||
592 | isabelle_rx4_mixer_controls, | ||
593 | ARRAY_SIZE(isabelle_rx4_mixer_controls)), | ||
594 | SND_SOC_DAPM_MIXER("RX5 Mixer", SND_SOC_NOPM, 0, 0, | ||
595 | isabelle_rx5_mixer_controls, | ||
596 | ARRAY_SIZE(isabelle_rx5_mixer_controls)), | ||
597 | SND_SOC_DAPM_MIXER("RX6 Mixer", SND_SOC_NOPM, 0, 0, | ||
598 | isabelle_rx6_mixer_controls, | ||
599 | ARRAY_SIZE(isabelle_rx6_mixer_controls)), | ||
600 | |||
601 | /* DACs */ | ||
602 | SND_SOC_DAPM_DAC("DAC1L", "Headset Playback", ISABELLE_DAC_CFG_REG, | ||
603 | 5, 0), | ||
604 | SND_SOC_DAPM_DAC("DAC1R", "Headset Playback", ISABELLE_DAC_CFG_REG, | ||
605 | 4, 0), | ||
606 | SND_SOC_DAPM_DAC("DAC2L", "Handsfree Playback", ISABELLE_DAC_CFG_REG, | ||
607 | 3, 0), | ||
608 | SND_SOC_DAPM_DAC("DAC2R", "Handsfree Playback", ISABELLE_DAC_CFG_REG, | ||
609 | 2, 0), | ||
610 | SND_SOC_DAPM_DAC("DAC3L", "Lineout Playback", ISABELLE_DAC_CFG_REG, | ||
611 | 1, 0), | ||
612 | SND_SOC_DAPM_DAC("DAC3R", "Lineout Playback", ISABELLE_DAC_CFG_REG, | ||
613 | 0, 0), | ||
614 | |||
615 | /* Analog Playback PGAs */ | ||
616 | SND_SOC_DAPM_PGA("Sidetone Audio PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
617 | SND_SOC_DAPM_PGA("Sidetone Voice PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
618 | SND_SOC_DAPM_PGA("HF Left PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
619 | SND_SOC_DAPM_PGA("HF Right PGA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
620 | SND_SOC_DAPM_PGA("DPGA1L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
621 | SND_SOC_DAPM_PGA("DPGA1R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
622 | SND_SOC_DAPM_PGA("DPGA2L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
623 | SND_SOC_DAPM_PGA("DPGA2R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
624 | SND_SOC_DAPM_PGA("DPGA3L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
625 | SND_SOC_DAPM_PGA("DPGA3R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
626 | |||
627 | /* Analog Playback Mux */ | ||
628 | SND_SOC_DAPM_MUX("RX1 Playback", ISABELLE_ALU_RX_EN_REG, 5, 0, | ||
629 | &rx1_mux_controls), | ||
630 | SND_SOC_DAPM_MUX("RX2 Playback", ISABELLE_ALU_RX_EN_REG, 4, 0, | ||
631 | &rx2_mux_controls), | ||
632 | |||
633 | /* TX Select */ | ||
634 | SND_SOC_DAPM_MUX("ATX Select", ISABELLE_TX_INPUT_CFG_REG, | ||
635 | 7, 0, &atx_mux_controls), | ||
636 | SND_SOC_DAPM_MUX("VTX Select", ISABELLE_TX_INPUT_CFG_REG, | ||
637 | 6, 0, &vtx_mux_controls), | ||
638 | |||
639 | SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, | ||
640 | &ep_path_enable_control), | ||
641 | |||
642 | /* Output Drivers */ | ||
643 | SND_SOC_DAPM_OUT_DRV("HS Left Driver", ISABELLE_HSDRV_CFG2_REG, | ||
644 | 1, 0, NULL, 0), | ||
645 | SND_SOC_DAPM_OUT_DRV("HS Right Driver", ISABELLE_HSDRV_CFG2_REG, | ||
646 | 0, 0, NULL, 0), | ||
647 | SND_SOC_DAPM_OUT_DRV("LINEOUT1 Left Driver", ISABELLE_LINEAMP_CFG_REG, | ||
648 | 1, 0, NULL, 0), | ||
649 | SND_SOC_DAPM_OUT_DRV("LINEOUT2 Right Driver", ISABELLE_LINEAMP_CFG_REG, | ||
650 | 0, 0, NULL, 0), | ||
651 | SND_SOC_DAPM_OUT_DRV("Earphone Driver", ISABELLE_EARDRV_CFG2_REG, | ||
652 | 1, 0, NULL, 0), | ||
653 | |||
654 | SND_SOC_DAPM_OUT_DRV("HF Left Driver", ISABELLE_HFDRV_CFG_REG, | ||
655 | 1, 0, NULL, 0), | ||
656 | SND_SOC_DAPM_OUT_DRV("HF Right Driver", ISABELLE_HFDRV_CFG_REG, | ||
657 | 0, 0, NULL, 0), | ||
658 | }; | ||
659 | |||
660 | static const struct snd_soc_dapm_route isabelle_intercon[] = { | ||
661 | /* Interface mapping */ | ||
662 | { "DL1", "DL12 Playback Switch", "INTF1_SDI" }, | ||
663 | { "DL2", "DL12 Playback Switch", "INTF1_SDI" }, | ||
664 | { "DL3", "DL34 Playback Switch", "INTF1_SDI" }, | ||
665 | { "DL4", "DL34 Playback Switch", "INTF1_SDI" }, | ||
666 | { "DL5", "DL56 Playback Switch", "INTF1_SDI" }, | ||
667 | { "DL6", "DL56 Playback Switch", "INTF1_SDI" }, | ||
668 | |||
669 | { "DL1", "DL12 Playback Switch", "INTF2_SDI" }, | ||
670 | { "DL2", "DL12 Playback Switch", "INTF2_SDI" }, | ||
671 | { "DL3", "DL34 Playback Switch", "INTF2_SDI" }, | ||
672 | { "DL4", "DL34 Playback Switch", "INTF2_SDI" }, | ||
673 | { "DL5", "DL56 Playback Switch", "INTF2_SDI" }, | ||
674 | { "DL6", "DL56 Playback Switch", "INTF2_SDI" }, | ||
675 | |||
676 | /* Input side mapping */ | ||
677 | { "Sidetone Audio PGA", NULL, "Sidetone Audio Playback" }, | ||
678 | { "Sidetone Voice PGA", NULL, "Sidetone Voice Playback" }, | ||
679 | |||
680 | { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Audio PGA" }, | ||
681 | |||
682 | { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" }, | ||
683 | { "RX1 Mixer", "DL1 Playback Switch", "DL1" }, | ||
684 | |||
685 | { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Audio PGA" }, | ||
686 | |||
687 | { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" }, | ||
688 | { "RX2 Mixer", "DL2 Playback Switch", "DL2" }, | ||
689 | |||
690 | { "RX3 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" }, | ||
691 | { "RX3 Mixer", "DL3 Playback Switch", "DL3" }, | ||
692 | |||
693 | { "RX4 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" }, | ||
694 | { "RX4 Mixer", "DL4 Playback Switch", "DL4" }, | ||
695 | |||
696 | { "RX5 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" }, | ||
697 | { "RX5 Mixer", "DL5 Playback Switch", "DL5" }, | ||
698 | |||
699 | { "RX6 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" }, | ||
700 | { "RX6 Mixer", "DL6 Playback Switch", "DL6" }, | ||
701 | |||
702 | /* Capture path */ | ||
703 | { "Analog Left Capture Route", "Headset Mic", "HSMIC" }, | ||
704 | { "Analog Left Capture Route", "Main Mic", "MAINMIC" }, | ||
705 | { "Analog Left Capture Route", "Aux/FM Left", "LINEIN1" }, | ||
706 | |||
707 | { "Analog Right Capture Route", "Sub Mic", "SUBMIC" }, | ||
708 | { "Analog Right Capture Route", "Aux/FM Right", "LINEIN2" }, | ||
709 | |||
710 | { "MicAmp1", NULL, "Analog Left Capture Route" }, | ||
711 | { "MicAmp2", NULL, "Analog Right Capture Route" }, | ||
712 | |||
713 | { "ADC1", NULL, "MicAmp1" }, | ||
714 | { "ADC2", NULL, "MicAmp2" }, | ||
715 | |||
716 | { "ATX Select", "AMIC1", "ADC1" }, | ||
717 | { "ATX Select", "DMIC", "DMICDAT" }, | ||
718 | { "ATX Select", "AMIC2", "ADC2" }, | ||
719 | |||
720 | { "VTX Select", "AMIC1", "ADC1" }, | ||
721 | { "VTX Select", "DMIC", "DMICDAT" }, | ||
722 | { "VTX Select", "AMIC2", "ADC2" }, | ||
723 | |||
724 | { "ULATX1", "ATX1 Filter Enable Switch", "ATX Select" }, | ||
725 | { "ULATX1", "ATX1 Filter Bypass Switch", "ATX Select" }, | ||
726 | { "ULATX2", "ATX2 Filter Enable Switch", "ATX Select" }, | ||
727 | { "ULATX2", "ATX2 Filter Bypass Switch", "ATX Select" }, | ||
728 | |||
729 | { "ULVTX1", "VTX1 Filter Enable Switch", "VTX Select" }, | ||
730 | { "ULVTX1", "VTX1 Filter Bypass Switch", "VTX Select" }, | ||
731 | { "ULVTX2", "VTX2 Filter Enable Switch", "VTX Select" }, | ||
732 | { "ULVTX2", "VTX2 Filter Bypass Switch", "VTX Select" }, | ||
733 | |||
734 | { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX1" }, | ||
735 | { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX2" }, | ||
736 | { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX1" }, | ||
737 | { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX2" }, | ||
738 | |||
739 | { "INTF1_SDO", NULL, "ULVTX1" }, | ||
740 | { "INTF1_SDO", NULL, "ULVTX2" }, | ||
741 | { "INTF2_SDO", NULL, "ULVTX1" }, | ||
742 | { "INTF2_SDO", NULL, "ULVTX2" }, | ||
743 | |||
744 | /* AFM Path */ | ||
745 | { "APGA1", NULL, "LINEIN1" }, | ||
746 | { "APGA2", NULL, "LINEIN2" }, | ||
747 | |||
748 | { "RX1 Playback", "VRX1 Filter Bypass Switch", "RX1 Mixer" }, | ||
749 | { "RX1 Playback", "ARX1 Filter Bypass Switch", "RX1 Mixer" }, | ||
750 | { "RX1 Playback", "RX1 Filter Enable Switch", "RX1 Mixer" }, | ||
751 | |||
752 | { "RX2 Playback", "VRX2 Filter Bypass Switch", "RX2 Mixer" }, | ||
753 | { "RX2 Playback", "ARX2 Filter Bypass Switch", "RX2 Mixer" }, | ||
754 | { "RX2 Playback", "RX2 Filter Enable Switch", "RX2 Mixer" }, | ||
755 | |||
756 | { "RX3 Playback", "ARX3 Filter Bypass Switch", "RX3 Mixer" }, | ||
757 | { "RX3 Playback", "RX3 Filter Enable Switch", "RX3 Mixer" }, | ||
758 | |||
759 | { "RX4 Playback", "ARX4 Filter Bypass Switch", "RX4 Mixer" }, | ||
760 | { "RX4 Playback", "RX4 Filter Enable Switch", "RX4 Mixer" }, | ||
761 | |||
762 | { "RX5 Playback", "ARX5 Filter Bypass Switch", "RX5 Mixer" }, | ||
763 | { "RX5 Playback", "RX5 Filter Enable Switch", "RX5 Mixer" }, | ||
764 | |||
765 | { "RX6 Playback", "ARX6 Filter Bypass Switch", "RX6 Mixer" }, | ||
766 | { "RX6 Playback", "RX6 Filter Enable Switch", "RX6 Mixer" }, | ||
767 | |||
768 | { "DPGA1L Mixer", "RX1 Playback Switch", "RX1 Playback" }, | ||
769 | { "DPGA1L Mixer", "RX3 Playback Switch", "RX3 Playback" }, | ||
770 | { "DPGA1L Mixer", "RX5 Playback Switch", "RX5 Playback" }, | ||
771 | |||
772 | { "DPGA1R Mixer", "RX2 Playback Switch", "RX2 Playback" }, | ||
773 | { "DPGA1R Mixer", "RX4 Playback Switch", "RX4 Playback" }, | ||
774 | { "DPGA1R Mixer", "RX6 Playback Switch", "RX6 Playback" }, | ||
775 | |||
776 | { "DPGA1L", NULL, "DPGA1L Mixer" }, | ||
777 | { "DPGA1R", NULL, "DPGA1R Mixer" }, | ||
778 | |||
779 | { "DAC1L", NULL, "DPGA1L" }, | ||
780 | { "DAC1R", NULL, "DPGA1R" }, | ||
781 | |||
782 | { "DPGA2L Mixer", "RX1 Playback Switch", "RX1 Playback" }, | ||
783 | { "DPGA2L Mixer", "RX2 Playback Switch", "RX2 Playback" }, | ||
784 | { "DPGA2L Mixer", "RX3 Playback Switch", "RX3 Playback" }, | ||
785 | { "DPGA2L Mixer", "RX4 Playback Switch", "RX4 Playback" }, | ||
786 | { "DPGA2L Mixer", "RX5 Playback Switch", "RX5 Playback" }, | ||
787 | { "DPGA2L Mixer", "RX6 Playback Switch", "RX6 Playback" }, | ||
788 | |||
789 | { "DPGA2R Mixer", "RX2 Playback Switch", "RX2 Playback" }, | ||
790 | { "DPGA2R Mixer", "RX4 Playback Switch", "RX4 Playback" }, | ||
791 | { "DPGA2R Mixer", "RX6 Playback Switch", "RX6 Playback" }, | ||
792 | |||
793 | { "DPGA2L", NULL, "DPGA2L Mixer" }, | ||
794 | { "DPGA2R", NULL, "DPGA2R Mixer" }, | ||
795 | |||
796 | { "DAC2L", NULL, "DPGA2L" }, | ||
797 | { "DAC2R", NULL, "DPGA2R" }, | ||
798 | |||
799 | { "DPGA3L Mixer", "RX1 Playback Switch", "RX1 Playback" }, | ||
800 | { "DPGA3L Mixer", "RX3 Playback Switch", "RX3 Playback" }, | ||
801 | { "DPGA3L Mixer", "RX5 Playback Switch", "RX5 Playback" }, | ||
802 | |||
803 | { "DPGA3R Mixer", "RX2 Playback Switch", "RX2 Playback" }, | ||
804 | { "DPGA3R Mixer", "RX4 Playback Switch", "RX4 Playback" }, | ||
805 | { "DPGA3R Mixer", "RX6 Playback Switch", "RX6 Playback" }, | ||
806 | |||
807 | { "DPGA3L", NULL, "DPGA3L Mixer" }, | ||
808 | { "DPGA3R", NULL, "DPGA3R Mixer" }, | ||
809 | |||
810 | { "DAC3L", NULL, "DPGA3L" }, | ||
811 | { "DAC3R", NULL, "DPGA3R" }, | ||
812 | |||
813 | { "Headset Left Mixer", "DAC1L Playback Switch", "DAC1L" }, | ||
814 | { "Headset Left Mixer", "APGA1 Playback Switch", "APGA1" }, | ||
815 | |||
816 | { "Headset Right Mixer", "DAC1R Playback Switch", "DAC1R" }, | ||
817 | { "Headset Right Mixer", "APGA2 Playback Switch", "APGA2" }, | ||
818 | |||
819 | { "HS Left Driver", NULL, "Headset Left Mixer" }, | ||
820 | { "HS Right Driver", NULL, "Headset Right Mixer" }, | ||
821 | |||
822 | { "HSOL", NULL, "HS Left Driver" }, | ||
823 | { "HSOR", NULL, "HS Right Driver" }, | ||
824 | |||
825 | /* Earphone playback path */ | ||
826 | { "Earphone Mixer", "DAC2L Playback Switch", "DAC2L" }, | ||
827 | { "Earphone Mixer", "APGA1 Playback Switch", "APGA1" }, | ||
828 | |||
829 | { "Earphone Playback", "Switch", "Earphone Mixer" }, | ||
830 | { "Earphone Driver", NULL, "Earphone Playback" }, | ||
831 | { "EP", NULL, "Earphone Driver" }, | ||
832 | |||
833 | { "Handsfree Left Mixer", "DAC2L Playback Switch", "DAC2L" }, | ||
834 | { "Handsfree Left Mixer", "APGA1 Playback Switch", "APGA1" }, | ||
835 | |||
836 | { "Handsfree Right Mixer", "DAC2R Playback Switch", "DAC2R" }, | ||
837 | { "Handsfree Right Mixer", "APGA2 Playback Switch", "APGA2" }, | ||
838 | |||
839 | { "HF Left PGA", NULL, "Handsfree Left Mixer" }, | ||
840 | { "HF Right PGA", NULL, "Handsfree Right Mixer" }, | ||
841 | |||
842 | { "HF Left Driver", NULL, "HF Left PGA" }, | ||
843 | { "HF Right Driver", NULL, "HF Right PGA" }, | ||
844 | |||
845 | { "HFL", NULL, "HF Left Driver" }, | ||
846 | { "HFR", NULL, "HF Right Driver" }, | ||
847 | |||
848 | { "LINEOUT1 Mixer", "DAC3L Playback Switch", "DAC3L" }, | ||
849 | { "LINEOUT1 Mixer", "APGA1 Playback Switch", "APGA1" }, | ||
850 | |||
851 | { "LINEOUT2 Mixer", "DAC3R Playback Switch", "DAC3R" }, | ||
852 | { "LINEOUT2 Mixer", "APGA2 Playback Switch", "APGA2" }, | ||
853 | |||
854 | { "LINEOUT1 Driver", NULL, "LINEOUT1 Mixer" }, | ||
855 | { "LINEOUT2 Driver", NULL, "LINEOUT2 Mixer" }, | ||
856 | |||
857 | { "LINEOUT1", NULL, "LINEOUT1 Driver" }, | ||
858 | { "LINEOUT2", NULL, "LINEOUT2 Driver" }, | ||
859 | }; | ||
860 | |||
861 | static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute) | ||
862 | { | ||
863 | snd_soc_update_bits(dai->codec, ISABELLE_DAC1_SOFTRAMP_REG, | ||
864 | BIT(4), (mute ? BIT(4) : 0)); | ||
865 | |||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute) | ||
870 | { | ||
871 | snd_soc_update_bits(dai->codec, ISABELLE_DAC2_SOFTRAMP_REG, | ||
872 | BIT(4), (mute ? BIT(4) : 0)); | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | static int isabelle_line_mute(struct snd_soc_dai *dai, int mute) | ||
878 | { | ||
879 | snd_soc_update_bits(dai->codec, ISABELLE_DAC3_SOFTRAMP_REG, | ||
880 | BIT(4), (mute ? BIT(4) : 0)); | ||
881 | |||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | static int isabelle_set_bias_level(struct snd_soc_codec *codec, | ||
886 | enum snd_soc_bias_level level) | ||
887 | { | ||
888 | switch (level) { | ||
889 | case SND_SOC_BIAS_ON: | ||
890 | break; | ||
891 | case SND_SOC_BIAS_PREPARE: | ||
892 | break; | ||
893 | |||
894 | case SND_SOC_BIAS_STANDBY: | ||
895 | snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG, | ||
896 | ISABELLE_CHIP_EN, BIT(0)); | ||
897 | break; | ||
898 | |||
899 | case SND_SOC_BIAS_OFF: | ||
900 | snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG, | ||
901 | ISABELLE_CHIP_EN, 0); | ||
902 | break; | ||
903 | } | ||
904 | |||
905 | codec->dapm.bias_level = level; | ||
906 | |||
907 | return 0; | ||
908 | } | ||
909 | |||
910 | static int isabelle_hw_params(struct snd_pcm_substream *substream, | ||
911 | struct snd_pcm_hw_params *params, | ||
912 | struct snd_soc_dai *dai) | ||
913 | { | ||
914 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
915 | struct snd_soc_codec *codec = rtd->codec; | ||
916 | u16 aif = 0; | ||
917 | unsigned int fs_val = 0; | ||
918 | |||
919 | switch (params_rate(params)) { | ||
920 | case 8000: | ||
921 | fs_val = ISABELLE_FS_RATE_8; | ||
922 | break; | ||
923 | case 11025: | ||
924 | fs_val = ISABELLE_FS_RATE_11; | ||
925 | break; | ||
926 | case 12000: | ||
927 | fs_val = ISABELLE_FS_RATE_12; | ||
928 | break; | ||
929 | case 16000: | ||
930 | fs_val = ISABELLE_FS_RATE_16; | ||
931 | break; | ||
932 | case 22050: | ||
933 | fs_val = ISABELLE_FS_RATE_22; | ||
934 | break; | ||
935 | case 24000: | ||
936 | fs_val = ISABELLE_FS_RATE_24; | ||
937 | break; | ||
938 | case 32000: | ||
939 | fs_val = ISABELLE_FS_RATE_32; | ||
940 | break; | ||
941 | case 44100: | ||
942 | fs_val = ISABELLE_FS_RATE_44; | ||
943 | break; | ||
944 | case 48000: | ||
945 | fs_val = ISABELLE_FS_RATE_48; | ||
946 | break; | ||
947 | default: | ||
948 | return -EINVAL; | ||
949 | } | ||
950 | |||
951 | snd_soc_update_bits(codec, ISABELLE_FS_RATE_CFG_REG, | ||
952 | ISABELLE_FS_RATE_MASK, fs_val); | ||
953 | |||
954 | /* bit size */ | ||
955 | switch (params_format(params)) { | ||
956 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
957 | aif |= ISABELLE_AIF_LENGTH_20; | ||
958 | break; | ||
959 | case SNDRV_PCM_FORMAT_S32_LE: | ||
960 | aif |= ISABELLE_AIF_LENGTH_32; | ||
961 | break; | ||
962 | default: | ||
963 | return -EINVAL; | ||
964 | } | ||
965 | |||
966 | snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG, | ||
967 | ISABELLE_AIF_LENGTH_MASK, aif); | ||
968 | |||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | ||
973 | { | ||
974 | struct snd_soc_codec *codec = codec_dai->codec; | ||
975 | unsigned int aif_val = 0; | ||
976 | |||
977 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
978 | case SND_SOC_DAIFMT_CBS_CFS: | ||
979 | aif_val &= ~ISABELLE_AIF_MS; | ||
980 | break; | ||
981 | case SND_SOC_DAIFMT_CBM_CFM: | ||
982 | aif_val |= ISABELLE_AIF_MS; | ||
983 | break; | ||
984 | default: | ||
985 | return -EINVAL; | ||
986 | } | ||
987 | |||
988 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
989 | case SND_SOC_DAIFMT_I2S: | ||
990 | aif_val |= ISABELLE_I2S_MODE; | ||
991 | break; | ||
992 | case SND_SOC_DAIFMT_LEFT_J: | ||
993 | aif_val |= ISABELLE_LEFT_J_MODE; | ||
994 | break; | ||
995 | case SND_SOC_DAIFMT_PDM: | ||
996 | aif_val |= ISABELLE_PDM_MODE; | ||
997 | break; | ||
998 | default: | ||
999 | return -EINVAL; | ||
1000 | } | ||
1001 | |||
1002 | snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG, | ||
1003 | (ISABELLE_AIF_MS | ISABELLE_AIF_FMT_MASK), aif_val); | ||
1004 | |||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | /* Rates supported by Isabelle driver */ | ||
1009 | #define ISABELLE_RATES SNDRV_PCM_RATE_8000_48000 | ||
1010 | |||
1011 | /* Formates supported by Isabelle driver. */ | ||
1012 | #define ISABELLE_FORMATS (SNDRV_PCM_FMTBIT_S20_3LE |\ | ||
1013 | SNDRV_PCM_FMTBIT_S32_LE) | ||
1014 | |||
1015 | static struct snd_soc_dai_ops isabelle_hs_dai_ops = { | ||
1016 | .hw_params = isabelle_hw_params, | ||
1017 | .set_fmt = isabelle_set_dai_fmt, | ||
1018 | .digital_mute = isabelle_hs_mute, | ||
1019 | }; | ||
1020 | |||
1021 | static struct snd_soc_dai_ops isabelle_hf_dai_ops = { | ||
1022 | .hw_params = isabelle_hw_params, | ||
1023 | .set_fmt = isabelle_set_dai_fmt, | ||
1024 | .digital_mute = isabelle_hf_mute, | ||
1025 | }; | ||
1026 | |||
1027 | static struct snd_soc_dai_ops isabelle_line_dai_ops = { | ||
1028 | .hw_params = isabelle_hw_params, | ||
1029 | .set_fmt = isabelle_set_dai_fmt, | ||
1030 | .digital_mute = isabelle_line_mute, | ||
1031 | }; | ||
1032 | |||
1033 | static struct snd_soc_dai_ops isabelle_ul_dai_ops = { | ||
1034 | .hw_params = isabelle_hw_params, | ||
1035 | .set_fmt = isabelle_set_dai_fmt, | ||
1036 | }; | ||
1037 | |||
1038 | /* ISABELLE dai structure */ | ||
1039 | struct snd_soc_dai_driver isabelle_dai[] = { | ||
1040 | { | ||
1041 | .name = "isabelle-dl1", | ||
1042 | .playback = { | ||
1043 | .stream_name = "Headset Playback", | ||
1044 | .channels_min = 1, | ||
1045 | .channels_max = 2, | ||
1046 | .rates = ISABELLE_RATES, | ||
1047 | .formats = ISABELLE_FORMATS, | ||
1048 | }, | ||
1049 | .ops = &isabelle_hs_dai_ops, | ||
1050 | }, | ||
1051 | { | ||
1052 | .name = "isabelle-dl2", | ||
1053 | .playback = { | ||
1054 | .stream_name = "Handsfree Playback", | ||
1055 | .channels_min = 1, | ||
1056 | .channels_max = 2, | ||
1057 | .rates = ISABELLE_RATES, | ||
1058 | .formats = ISABELLE_FORMATS, | ||
1059 | }, | ||
1060 | .ops = &isabelle_hf_dai_ops, | ||
1061 | }, | ||
1062 | { | ||
1063 | .name = "isabelle-lineout", | ||
1064 | .playback = { | ||
1065 | .stream_name = "Lineout Playback", | ||
1066 | .channels_min = 1, | ||
1067 | .channels_max = 2, | ||
1068 | .rates = ISABELLE_RATES, | ||
1069 | .formats = ISABELLE_FORMATS, | ||
1070 | }, | ||
1071 | .ops = &isabelle_line_dai_ops, | ||
1072 | }, | ||
1073 | { | ||
1074 | .name = "isabelle-ul", | ||
1075 | .capture = { | ||
1076 | .stream_name = "Capture", | ||
1077 | .channels_min = 1, | ||
1078 | .channels_max = 2, | ||
1079 | .rates = ISABELLE_RATES, | ||
1080 | .formats = ISABELLE_FORMATS, | ||
1081 | }, | ||
1082 | .ops = &isabelle_ul_dai_ops, | ||
1083 | }, | ||
1084 | }; | ||
1085 | |||
1086 | static int isabelle_probe(struct snd_soc_codec *codec) | ||
1087 | { | ||
1088 | int ret = 0; | ||
1089 | |||
1090 | codec->control_data = dev_get_regmap(codec->dev, NULL); | ||
1091 | |||
1092 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
1093 | if (ret < 0) { | ||
1094 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1095 | return ret; | ||
1096 | } | ||
1097 | |||
1098 | return 0; | ||
1099 | } | ||
1100 | |||
1101 | static struct snd_soc_codec_driver soc_codec_dev_isabelle = { | ||
1102 | .probe = isabelle_probe, | ||
1103 | .set_bias_level = isabelle_set_bias_level, | ||
1104 | .controls = isabelle_snd_controls, | ||
1105 | .num_controls = ARRAY_SIZE(isabelle_snd_controls), | ||
1106 | .dapm_widgets = isabelle_dapm_widgets, | ||
1107 | .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets), | ||
1108 | .dapm_routes = isabelle_intercon, | ||
1109 | .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), | ||
1110 | .idle_bias_off = true, | ||
1111 | }; | ||
1112 | |||
1113 | static const struct regmap_config isabelle_regmap_config = { | ||
1114 | .reg_bits = 8, | ||
1115 | .val_bits = 8, | ||
1116 | |||
1117 | .max_register = ISABELLE_MAX_REGISTER, | ||
1118 | .reg_defaults = isabelle_reg_defs, | ||
1119 | .num_reg_defaults = ARRAY_SIZE(isabelle_reg_defs), | ||
1120 | .cache_type = REGCACHE_RBTREE, | ||
1121 | }; | ||
1122 | |||
1123 | static int __devinit isabelle_i2c_probe(struct i2c_client *i2c, | ||
1124 | const struct i2c_device_id *id) | ||
1125 | { | ||
1126 | struct regmap *isabelle_regmap; | ||
1127 | int ret = 0; | ||
1128 | |||
1129 | isabelle_regmap = devm_regmap_init_i2c(i2c, &isabelle_regmap_config); | ||
1130 | if (IS_ERR(isabelle_regmap)) { | ||
1131 | ret = PTR_ERR(isabelle_regmap); | ||
1132 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1133 | ret); | ||
1134 | return ret; | ||
1135 | } | ||
1136 | i2c_set_clientdata(i2c, isabelle_regmap); | ||
1137 | |||
1138 | ret = snd_soc_register_codec(&i2c->dev, | ||
1139 | &soc_codec_dev_isabelle, isabelle_dai, | ||
1140 | ARRAY_SIZE(isabelle_dai)); | ||
1141 | if (ret < 0) { | ||
1142 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | ||
1143 | return ret; | ||
1144 | } | ||
1145 | |||
1146 | return ret; | ||
1147 | } | ||
1148 | |||
1149 | static int __devexit isabelle_i2c_remove(struct i2c_client *client) | ||
1150 | { | ||
1151 | snd_soc_unregister_codec(&client->dev); | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | static const struct i2c_device_id isabelle_i2c_id[] = { | ||
1156 | { "isabelle", 0 }, | ||
1157 | { } | ||
1158 | }; | ||
1159 | MODULE_DEVICE_TABLE(i2c, isabelle_i2c_id); | ||
1160 | |||
1161 | static struct i2c_driver isabelle_i2c_driver = { | ||
1162 | .driver = { | ||
1163 | .name = "isabelle", | ||
1164 | .owner = THIS_MODULE, | ||
1165 | }, | ||
1166 | .probe = isabelle_i2c_probe, | ||
1167 | .remove = __devexit_p(isabelle_i2c_remove), | ||
1168 | .id_table = isabelle_i2c_id, | ||
1169 | }; | ||
1170 | |||
1171 | module_i2c_driver(isabelle_i2c_driver); | ||
1172 | |||
1173 | MODULE_DESCRIPTION("ASoC ISABELLE driver"); | ||
1174 | MODULE_AUTHOR("Vishwas A Deshpande <vishwas.a.deshpande@ti.com>"); | ||
1175 | MODULE_AUTHOR("M R Swami Reddy <MR.Swami.Reddy@ti.com>"); | ||
1176 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/isabelle.h b/sound/soc/codecs/isabelle.h new file mode 100644 index 000000000000..96d839a8c956 --- /dev/null +++ b/sound/soc/codecs/isabelle.h | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * isabelle.h - Low power high fidelity audio codec driver header file | ||
3 | * | ||
4 | * Copyright (c) 2012 Texas Instruments, Inc | ||
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 as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef _ISABELLE_H | ||
13 | #define _ISABELLE_H | ||
14 | |||
15 | #include <linux/bitops.h> | ||
16 | |||
17 | /* ISABELLE REGISTERS */ | ||
18 | |||
19 | #define ISABELLE_PWR_CFG_REG 0x01 | ||
20 | #define ISABELLE_PWR_EN_REG 0x02 | ||
21 | #define ISABELLE_PS_EN1_REG 0x03 | ||
22 | #define ISABELLE_INT1_STATUS_REG 0x04 | ||
23 | #define ISABELLE_INT1_MASK_REG 0x05 | ||
24 | #define ISABELLE_INT2_STATUS_REG 0x06 | ||
25 | #define ISABELLE_INT2_MASK_REG 0x07 | ||
26 | #define ISABELLE_HKCTL1_REG 0x08 | ||
27 | #define ISABELLE_HKCTL2_REG 0x09 | ||
28 | #define ISABELLE_HKCTL3_REG 0x0A | ||
29 | #define ISABELLE_ACCDET_STATUS_REG 0x0B | ||
30 | #define ISABELLE_BUTTON_ID_REG 0x0C | ||
31 | #define ISABELLE_PLL_CFG_REG 0x10 | ||
32 | #define ISABELLE_PLL_EN_REG 0x11 | ||
33 | #define ISABELLE_FS_RATE_CFG_REG 0x12 | ||
34 | #define ISABELLE_INTF_CFG_REG 0x13 | ||
35 | #define ISABELLE_INTF_EN_REG 0x14 | ||
36 | #define ISABELLE_ULATX12_INTF_CFG_REG 0x15 | ||
37 | #define ISABELLE_DL12_INTF_CFG_REG 0x16 | ||
38 | #define ISABELLE_DL34_INTF_CFG_REG 0x17 | ||
39 | #define ISABELLE_DL56_INTF_CFG_REG 0x18 | ||
40 | #define ISABELLE_ATX_STPGA1_CFG_REG 0x19 | ||
41 | #define ISABELLE_ATX_STPGA2_CFG_REG 0x1A | ||
42 | #define ISABELLE_VTX_STPGA1_CFG_REG 0x1B | ||
43 | #define ISABELLE_VTX2_STPGA2_CFG_REG 0x1C | ||
44 | #define ISABELLE_ATX1_DPGA_REG 0x1D | ||
45 | #define ISABELLE_ATX2_DPGA_REG 0x1E | ||
46 | #define ISABELLE_VTX1_DPGA_REG 0x1F | ||
47 | #define ISABELLE_VTX2_DPGA_REG 0x20 | ||
48 | #define ISABELLE_TX_INPUT_CFG_REG 0x21 | ||
49 | #define ISABELLE_RX_INPUT_CFG_REG 0x22 | ||
50 | #define ISABELLE_RX_INPUT_CFG2_REG 0x23 | ||
51 | #define ISABELLE_VOICE_HPF_CFG_REG 0x24 | ||
52 | #define ISABELLE_AUDIO_HPF_CFG_REG 0x25 | ||
53 | #define ISABELLE_RX1_DPGA_REG 0x26 | ||
54 | #define ISABELLE_RX2_DPGA_REG 0x27 | ||
55 | #define ISABELLE_RX3_DPGA_REG 0x28 | ||
56 | #define ISABELLE_RX4_DPGA_REG 0x29 | ||
57 | #define ISABELLE_RX5_DPGA_REG 0x2A | ||
58 | #define ISABELLE_RX6_DPGA_REG 0x2B | ||
59 | #define ISABELLE_ALU_TX_EN_REG 0x2C | ||
60 | #define ISABELLE_ALU_RX_EN_REG 0x2D | ||
61 | #define ISABELLE_IIR_RESYNC_REG 0x2E | ||
62 | #define ISABELLE_ABIAS_CFG_REG 0x30 | ||
63 | #define ISABELLE_DBIAS_CFG_REG 0x31 | ||
64 | #define ISABELLE_MIC1_GAIN_REG 0x32 | ||
65 | #define ISABELLE_MIC2_GAIN_REG 0x33 | ||
66 | #define ISABELLE_AMIC_CFG_REG 0x34 | ||
67 | #define ISABELLE_DMIC_CFG_REG 0x35 | ||
68 | #define ISABELLE_APGA_GAIN_REG 0x36 | ||
69 | #define ISABELLE_APGA_CFG_REG 0x37 | ||
70 | #define ISABELLE_TX_GAIN_DLY_REG 0x38 | ||
71 | #define ISABELLE_RX_GAIN_DLY_REG 0x39 | ||
72 | #define ISABELLE_RX_PWR_CTRL_REG 0x3A | ||
73 | #define ISABELLE_DPGA1LR_IN_SEL_REG 0x3B | ||
74 | #define ISABELLE_DPGA1L_GAIN_REG 0x3C | ||
75 | #define ISABELLE_DPGA1R_GAIN_REG 0x3D | ||
76 | #define ISABELLE_DPGA2L_IN_SEL_REG 0x3E | ||
77 | #define ISABELLE_DPGA2R_IN_SEL_REG 0x3F | ||
78 | #define ISABELLE_DPGA2L_GAIN_REG 0x40 | ||
79 | #define ISABELLE_DPGA2R_GAIN_REG 0x41 | ||
80 | #define ISABELLE_DPGA3LR_IN_SEL_REG 0x42 | ||
81 | #define ISABELLE_DPGA3L_GAIN_REG 0x43 | ||
82 | #define ISABELLE_DPGA3R_GAIN_REG 0x44 | ||
83 | #define ISABELLE_DAC1_SOFTRAMP_REG 0x45 | ||
84 | #define ISABELLE_DAC2_SOFTRAMP_REG 0x46 | ||
85 | #define ISABELLE_DAC3_SOFTRAMP_REG 0x47 | ||
86 | #define ISABELLE_DAC_CFG_REG 0x48 | ||
87 | #define ISABELLE_EARDRV_CFG1_REG 0x49 | ||
88 | #define ISABELLE_EARDRV_CFG2_REG 0x4A | ||
89 | #define ISABELLE_HSDRV_GAIN_REG 0x4B | ||
90 | #define ISABELLE_HSDRV_CFG1_REG 0x4C | ||
91 | #define ISABELLE_HSDRV_CFG2_REG 0x4D | ||
92 | #define ISABELLE_HS_NG_CFG1_REG 0x4E | ||
93 | #define ISABELLE_HS_NG_CFG2_REG 0x4F | ||
94 | #define ISABELLE_LINEAMP_GAIN_REG 0x50 | ||
95 | #define ISABELLE_LINEAMP_CFG_REG 0x51 | ||
96 | #define ISABELLE_HFL_VOL_CTRL_REG 0x52 | ||
97 | #define ISABELLE_HFL_SFTVOL_CTRL_REG 0x53 | ||
98 | #define ISABELLE_HFL_LIM_CTRL_1_REG 0x54 | ||
99 | #define ISABELLE_HFL_LIM_CTRL_2_REG 0x55 | ||
100 | #define ISABELLE_HFR_VOL_CTRL_REG 0x56 | ||
101 | #define ISABELLE_HFR_SFTVOL_CTRL_REG 0x57 | ||
102 | #define ISABELLE_HFR_LIM_CTRL_1_REG 0x58 | ||
103 | #define ISABELLE_HFR_LIM_CTRL_2_REG 0x59 | ||
104 | #define ISABELLE_HF_MODE_REG 0x5A | ||
105 | #define ISABELLE_HFLPGA_CFG_REG 0x5B | ||
106 | #define ISABELLE_HFRPGA_CFG_REG 0x5C | ||
107 | #define ISABELLE_HFDRV_CFG_REG 0x5D | ||
108 | #define ISABELLE_PDMOUT_CFG1_REG 0x5E | ||
109 | #define ISABELLE_PDMOUT_CFG2_REG 0x5F | ||
110 | #define ISABELLE_PDMOUT_L_WM_REG 0x60 | ||
111 | #define ISABELLE_PDMOUT_R_WM_REG 0x61 | ||
112 | #define ISABELLE_HF_NG_CFG1_REG 0x62 | ||
113 | #define ISABELLE_HF_NG_CFG2_REG 0x63 | ||
114 | |||
115 | /* ISABELLE_PWR_EN_REG (0x02h) */ | ||
116 | #define ISABELLE_CHIP_EN BIT(0) | ||
117 | |||
118 | /* ISABELLE DAI FORMATS */ | ||
119 | #define ISABELLE_AIF_FMT_MASK 0x70 | ||
120 | #define ISABELLE_I2S_MODE 0x0 | ||
121 | #define ISABELLE_LEFT_J_MODE 0x1 | ||
122 | #define ISABELLE_PDM_MODE 0x2 | ||
123 | |||
124 | #define ISABELLE_AIF_LENGTH_MASK 0x30 | ||
125 | #define ISABELLE_AIF_LENGTH_20 0x00 | ||
126 | #define ISABELLE_AIF_LENGTH_32 0x10 | ||
127 | |||
128 | #define ISABELLE_AIF_MS 0x80 | ||
129 | |||
130 | #define ISABELLE_FS_RATE_MASK 0xF | ||
131 | #define ISABELLE_FS_RATE_8 0x0 | ||
132 | #define ISABELLE_FS_RATE_11 0x1 | ||
133 | #define ISABELLE_FS_RATE_12 0x2 | ||
134 | #define ISABELLE_FS_RATE_16 0x4 | ||
135 | #define ISABELLE_FS_RATE_22 0x5 | ||
136 | #define ISABELLE_FS_RATE_24 0x6 | ||
137 | #define ISABELLE_FS_RATE_32 0x8 | ||
138 | #define ISABELLE_FS_RATE_44 0x9 | ||
139 | #define ISABELLE_FS_RATE_48 0xA | ||
140 | |||
141 | #define ISABELLE_MAX_REGISTER 0xFF | ||
142 | |||
143 | #endif | ||
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 802b9f176b16..99b0a9dcff34 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c | |||
@@ -12,7 +12,6 @@ | |||
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/version.h> | ||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
18 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
@@ -1358,7 +1357,7 @@ static struct snd_soc_dai_ops lm49453_lineout_dai_ops = { | |||
1358 | }; | 1357 | }; |
1359 | 1358 | ||
1360 | /* LM49453 dai structure. */ | 1359 | /* LM49453 dai structure. */ |
1361 | static const struct snd_soc_dai_driver lm49453_dai[] = { | 1360 | static struct snd_soc_dai_driver lm49453_dai[] = { |
1362 | { | 1361 | { |
1363 | .name = "LM49453 Headset", | 1362 | .name = "LM49453 Headset", |
1364 | .playback = { | 1363 | .playback = { |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 35179e2c23c9..7cd508e16a5c 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -2216,7 +2216,7 @@ static irqreturn_t max98095_report_jack(int irq, void *data) | |||
2216 | return IRQ_HANDLED; | 2216 | return IRQ_HANDLED; |
2217 | } | 2217 | } |
2218 | 2218 | ||
2219 | int max98095_jack_detect_enable(struct snd_soc_codec *codec) | 2219 | static int max98095_jack_detect_enable(struct snd_soc_codec *codec) |
2220 | { | 2220 | { |
2221 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 2221 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
2222 | int ret = 0; | 2222 | int ret = 0; |
@@ -2245,7 +2245,7 @@ int max98095_jack_detect_enable(struct snd_soc_codec *codec) | |||
2245 | return ret; | 2245 | return ret; |
2246 | } | 2246 | } |
2247 | 2247 | ||
2248 | int max98095_jack_detect_disable(struct snd_soc_codec *codec) | 2248 | static int max98095_jack_detect_disable(struct snd_soc_codec *codec) |
2249 | { | 2249 | { |
2250 | int ret = 0; | 2250 | int ret = 0; |
2251 | 2251 | ||
@@ -2286,6 +2286,7 @@ int max98095_jack_detect(struct snd_soc_codec *codec, | |||
2286 | max98095_report_jack(client->irq, codec); | 2286 | max98095_report_jack(client->irq, codec); |
2287 | return 0; | 2287 | return 0; |
2288 | } | 2288 | } |
2289 | EXPORT_SYMBOL_GPL(max98095_jack_detect); | ||
2289 | 2290 | ||
2290 | #ifdef CONFIG_PM | 2291 | #ifdef CONFIG_PM |
2291 | static int max98095_suspend(struct snd_soc_codec *codec) | 2292 | static int max98095_suspend(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64d2a4fa34b2..58ef59dfbae9 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -368,7 +368,7 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { | |||
368 | static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0); | 368 | static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0); |
369 | 369 | ||
370 | static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl = | 370 | static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl = |
371 | SOC_DOUBLE_TLV("Class-D Amplifier Gain", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv); | 371 | SOC_DOUBLE_TLV("Class-D Playback Volume", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv); |
372 | 372 | ||
373 | /* Left DAC Mux */ | 373 | /* Left DAC Mux */ |
374 | static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = | 374 | static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index a75c3766aede..78a148f0a8ef 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm2000.c -- WM2000 ALSA Soc Audio driver | 2 | * wm2000.c -- WM2000 ALSA Soc Audio driver |
3 | * | 3 | * |
4 | * Copyright 2008-2010 Wolfson Microelectronics PLC. | 4 | * Copyright 2008-2011 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
@@ -691,9 +691,39 @@ static int wm2000_resume(struct snd_soc_codec *codec) | |||
691 | #define wm2000_resume NULL | 691 | #define wm2000_resume NULL |
692 | #endif | 692 | #endif |
693 | 693 | ||
694 | static bool wm2000_readable_reg(struct device *dev, unsigned int reg) | ||
695 | { | ||
696 | switch (reg) { | ||
697 | case WM2000_REG_SYS_START: | ||
698 | case WM2000_REG_SPEECH_CLARITY: | ||
699 | case WM2000_REG_SYS_WATCHDOG: | ||
700 | case WM2000_REG_ANA_VMID_PD_TIME: | ||
701 | case WM2000_REG_ANA_VMID_PU_TIME: | ||
702 | case WM2000_REG_CAT_FLTR_INDX: | ||
703 | case WM2000_REG_CAT_GAIN_0: | ||
704 | case WM2000_REG_SYS_STATUS: | ||
705 | case WM2000_REG_SYS_MODE_CNTRL: | ||
706 | case WM2000_REG_SYS_START0: | ||
707 | case WM2000_REG_SYS_START1: | ||
708 | case WM2000_REG_ID1: | ||
709 | case WM2000_REG_ID2: | ||
710 | case WM2000_REG_REVISON: | ||
711 | case WM2000_REG_SYS_CTL1: | ||
712 | case WM2000_REG_SYS_CTL2: | ||
713 | case WM2000_REG_ANC_STAT: | ||
714 | case WM2000_REG_IF_CTL: | ||
715 | return true; | ||
716 | default: | ||
717 | return false; | ||
718 | } | ||
719 | } | ||
720 | |||
694 | static const struct regmap_config wm2000_regmap = { | 721 | static const struct regmap_config wm2000_regmap = { |
695 | .reg_bits = 8, | 722 | .reg_bits = 8, |
696 | .val_bits = 8, | 723 | .val_bits = 8, |
724 | |||
725 | .max_register = WM2000_REG_IF_CTL, | ||
726 | .readable_reg = wm2000_readable_reg, | ||
697 | }; | 727 | }; |
698 | 728 | ||
699 | static int wm2000_probe(struct snd_soc_codec *codec) | 729 | static int wm2000_probe(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c index e167207a19cc..e239f4bf2460 100644 --- a/sound/soc/codecs/wm5100-tables.c +++ b/sound/soc/codecs/wm5100-tables.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data | 2 | * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data |
3 | * | 3 | * |
4 | * Copyright 2011 Wolfson Microelectronics plc | 4 | * Copyright 2011-2 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index cb6d5372103a..3823af362912 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm5100.c -- WM5100 ALSA SoC Audio driver | 2 | * wm5100.c -- WM5100 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2011 Wolfson Microelectronics plc | 4 | * Copyright 2011-2 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 555ee146ae0d..d26c8ae4e6d9 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8350.c -- WM8350 ALSA SoC audio driver | 2 | * wm8350.c -- WM8350 ALSA SoC audio driver |
3 | * | 3 | * |
4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. | 4 | * Copyright (C) 2007-12 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
6 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> | 6 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
7 | * | 7 | * |
@@ -71,20 +71,6 @@ struct wm8350_data { | |||
71 | int fll_freq_in; | 71 | int fll_freq_in; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static unsigned int wm8350_codec_read(struct snd_soc_codec *codec, | ||
75 | unsigned int reg) | ||
76 | { | ||
77 | struct wm8350 *wm8350 = codec->control_data; | ||
78 | return wm8350_reg_read(wm8350, reg); | ||
79 | } | ||
80 | |||
81 | static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg, | ||
82 | unsigned int value) | ||
83 | { | ||
84 | struct wm8350 *wm8350 = codec->control_data; | ||
85 | return wm8350_reg_write(wm8350, reg, value); | ||
86 | } | ||
87 | |||
88 | /* | 74 | /* |
89 | * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. | 75 | * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. |
90 | */ | 76 | */ |
@@ -1519,7 +1505,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) | |||
1519 | if (ret != 0) | 1505 | if (ret != 0) |
1520 | return ret; | 1506 | return ret; |
1521 | 1507 | ||
1522 | codec->control_data = wm8350; | 1508 | codec->control_data = wm8350->regmap; |
1509 | |||
1510 | snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1523 | 1511 | ||
1524 | /* Put the codec into reset if it wasn't already */ | 1512 | /* Put the codec into reset if it wasn't already */ |
1525 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); | 1513 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); |
@@ -1629,8 +1617,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { | |||
1629 | .remove = wm8350_codec_remove, | 1617 | .remove = wm8350_codec_remove, |
1630 | .suspend = wm8350_suspend, | 1618 | .suspend = wm8350_suspend, |
1631 | .resume = wm8350_resume, | 1619 | .resume = wm8350_resume, |
1632 | .read = wm8350_codec_read, | ||
1633 | .write = wm8350_codec_write, | ||
1634 | .set_bias_level = wm8350_set_bias_level, | 1620 | .set_bias_level = wm8350_set_bias_level, |
1635 | 1621 | ||
1636 | .controls = wm8350_snd_controls, | 1622 | .controls = wm8350_snd_controls, |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 5dc31ebcd0e7..5d277a915f81 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8400.c -- WM8400 ALSA Soc Audio driver | 2 | * wm8400.c -- WM8400 ALSA Soc Audio driver |
3 | * | 3 | * |
4 | * Copyright 2008, 2009 Wolfson Microelectronics PLC. | 4 | * Copyright 2008-11 Wolfson Microelectronics PLC. |
5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 211285164d70..7c68226376e4 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8580.c -- WM8580 ALSA Soc Audio driver | 2 | * wm8580.c -- WM8580 ALSA Soc Audio driver |
3 | * | 3 | * |
4 | * Copyright 2008, 2009 Wolfson Microelectronics PLC. | 4 | * Copyright 2008-11 Wolfson Microelectronics PLC. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 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 | 7 | * under the terms of the GNU General Public License as published by the |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 9d1b9b0271f1..bb1d26919b10 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * wm8731.c -- WM8731 ALSA SoC Audio driver | 2 | * wm8731.c -- WM8731 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2005 Openedhand Ltd. | 4 | * Copyright 2005 Openedhand Ltd. |
5 | * Copyright 2006-12 Wolfson Microelectronics, plc | ||
5 | * | 6 | * |
6 | * Author: Richard Purdie <richard@openedhand.com> | 7 | * Author: Richard Purdie <richard@openedhand.com> |
7 | * | 8 | * |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 6e849cb04243..35f3d23200e0 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8741.c -- WM8741 ALSA SoC Audio driver | 2 | * wm8741.c -- WM8741 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2010 Wolfson Microelectronics plc | 4 | * Copyright 2010-1 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Ian Lartey <ian@opensource.wolfsonmicro.com> | 6 | * Author: Ian Lartey <ian@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index a26482cd7654..13bff87ddcf5 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8753.c -- WM8753 ALSA Soc Audio driver | 2 | * wm8753.c -- WM8753 ALSA Soc Audio driver |
3 | * | 3 | * |
4 | * Copyright 2003 Wolfson Microelectronics PLC. | 4 | * Copyright 2003-11 Wolfson Microelectronics PLC. |
5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> | 5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index a19db5a0a17a..879c356a9045 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8776.c -- WM8776 ALSA SoC Audio driver | 2 | * wm8776.c -- WM8776 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics plc | 4 | * Copyright 2009-12 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 6bd1b767b138..c088020172ab 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8804.c -- WM8804 S/PDIF transceiver driver | 2 | * wm8804.c -- WM8804 S/PDIF transceiver driver |
3 | * | 3 | * |
4 | * Copyright 2010 Wolfson Microelectronics plc | 4 | * Copyright 2010-11 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 6 | * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 86b8a2926591..73f1c8d7bafb 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * wm8903.c -- WM8903 ALSA SoC Audio driver | 2 | * wm8903.c -- WM8903 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2008 Wolfson Microelectronics | 4 | * Copyright 2008-12 Wolfson Microelectronics |
5 | * Copyright 2011 NVIDIA, Inc. | 5 | * Copyright 2011-2012 NVIDIA, Inc. |
6 | * | 6 | * |
7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
8 | * | 8 | * |
@@ -116,6 +116,7 @@ static const struct reg_default wm8903_reg_defaults[] = { | |||
116 | 116 | ||
117 | struct wm8903_priv { | 117 | struct wm8903_priv { |
118 | struct wm8903_platform_data *pdata; | 118 | struct wm8903_platform_data *pdata; |
119 | struct device *dev; | ||
119 | struct snd_soc_codec *codec; | 120 | struct snd_soc_codec *codec; |
120 | struct regmap *regmap; | 121 | struct regmap *regmap; |
121 | 122 | ||
@@ -1635,17 +1636,27 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect); | |||
1635 | 1636 | ||
1636 | static irqreturn_t wm8903_irq(int irq, void *data) | 1637 | static irqreturn_t wm8903_irq(int irq, void *data) |
1637 | { | 1638 | { |
1638 | struct snd_soc_codec *codec = data; | 1639 | struct wm8903_priv *wm8903 = data; |
1639 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1640 | int mic_report, ret; |
1640 | int mic_report; | 1641 | unsigned int int_val, mask, int_pol; |
1641 | int int_pol; | ||
1642 | int int_val = 0; | ||
1643 | int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK); | ||
1644 | 1642 | ||
1645 | int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; | 1643 | ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1_MASK, |
1644 | &mask); | ||
1645 | if (ret != 0) { | ||
1646 | dev_err(wm8903->dev, "Failed to read IRQ mask: %d\n", ret); | ||
1647 | return IRQ_NONE; | ||
1648 | } | ||
1649 | |||
1650 | ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1, &int_val); | ||
1651 | if (ret != 0) { | ||
1652 | dev_err(wm8903->dev, "Failed to read IRQ status: %d\n", ret); | ||
1653 | return IRQ_NONE; | ||
1654 | } | ||
1655 | |||
1656 | int_val &= ~mask; | ||
1646 | 1657 | ||
1647 | if (int_val & WM8903_WSEQ_BUSY_EINT) { | 1658 | if (int_val & WM8903_WSEQ_BUSY_EINT) { |
1648 | dev_warn(codec->dev, "Write sequencer done\n"); | 1659 | dev_warn(wm8903->dev, "Write sequencer done\n"); |
1649 | } | 1660 | } |
1650 | 1661 | ||
1651 | /* | 1662 | /* |
@@ -1656,22 +1667,28 @@ static irqreturn_t wm8903_irq(int irq, void *data) | |||
1656 | * the polarity register. | 1667 | * the polarity register. |
1657 | */ | 1668 | */ |
1658 | mic_report = wm8903->mic_last_report; | 1669 | mic_report = wm8903->mic_last_report; |
1659 | int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); | 1670 | ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1, |
1671 | &int_pol); | ||
1672 | if (ret != 0) { | ||
1673 | dev_err(wm8903->dev, "Failed to read interrupt polarity: %d\n", | ||
1674 | ret); | ||
1675 | return IRQ_HANDLED; | ||
1676 | } | ||
1660 | 1677 | ||
1661 | #ifndef CONFIG_SND_SOC_WM8903_MODULE | 1678 | #ifndef CONFIG_SND_SOC_WM8903_MODULE |
1662 | if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) | 1679 | if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) |
1663 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 1680 | trace_snd_soc_jack_irq(dev_name(wm8903->dev)); |
1664 | #endif | 1681 | #endif |
1665 | 1682 | ||
1666 | if (int_val & WM8903_MICSHRT_EINT) { | 1683 | if (int_val & WM8903_MICSHRT_EINT) { |
1667 | dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); | 1684 | dev_dbg(wm8903->dev, "Microphone short (pol=%x)\n", int_pol); |
1668 | 1685 | ||
1669 | mic_report ^= wm8903->mic_short; | 1686 | mic_report ^= wm8903->mic_short; |
1670 | int_pol ^= WM8903_MICSHRT_INV; | 1687 | int_pol ^= WM8903_MICSHRT_INV; |
1671 | } | 1688 | } |
1672 | 1689 | ||
1673 | if (int_val & WM8903_MICDET_EINT) { | 1690 | if (int_val & WM8903_MICDET_EINT) { |
1674 | dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); | 1691 | dev_dbg(wm8903->dev, "Microphone detect (pol=%x)\n", int_pol); |
1675 | 1692 | ||
1676 | mic_report ^= wm8903->mic_det; | 1693 | mic_report ^= wm8903->mic_det; |
1677 | int_pol ^= WM8903_MICDET_INV; | 1694 | int_pol ^= WM8903_MICDET_INV; |
@@ -1679,8 +1696,8 @@ static irqreturn_t wm8903_irq(int irq, void *data) | |||
1679 | msleep(wm8903->mic_delay); | 1696 | msleep(wm8903->mic_delay); |
1680 | } | 1697 | } |
1681 | 1698 | ||
1682 | snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1, | 1699 | regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1, |
1683 | WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol); | 1700 | WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol); |
1684 | 1701 | ||
1685 | snd_soc_jack_report(wm8903->mic_jack, mic_report, | 1702 | snd_soc_jack_report(wm8903->mic_jack, mic_report, |
1686 | wm8903->mic_short | wm8903->mic_det); | 1703 | wm8903->mic_short | wm8903->mic_det); |
@@ -1774,7 +1791,6 @@ static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
1774 | static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | 1791 | static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) |
1775 | { | 1792 | { |
1776 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | 1793 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
1777 | struct snd_soc_codec *codec = wm8903->codec; | ||
1778 | unsigned int mask, val; | 1794 | unsigned int mask, val; |
1779 | int ret; | 1795 | int ret; |
1780 | 1796 | ||
@@ -1782,8 +1798,8 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | |||
1782 | val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | | 1798 | val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | |
1783 | WM8903_GP1_DIR; | 1799 | WM8903_GP1_DIR; |
1784 | 1800 | ||
1785 | ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, | 1801 | ret = regmap_update_bits(wm8903->regmap, |
1786 | mask, val); | 1802 | WM8903_GPIO_CONTROL_1 + offset, mask, val); |
1787 | if (ret < 0) | 1803 | if (ret < 0) |
1788 | return ret; | 1804 | return ret; |
1789 | 1805 | ||
@@ -1793,10 +1809,9 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | |||
1793 | static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) | 1809 | static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) |
1794 | { | 1810 | { |
1795 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | 1811 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
1796 | struct snd_soc_codec *codec = wm8903->codec; | 1812 | unsigned int reg; |
1797 | int reg; | ||
1798 | 1813 | ||
1799 | reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset); | 1814 | regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, ®); |
1800 | 1815 | ||
1801 | return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; | 1816 | return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; |
1802 | } | 1817 | } |
@@ -1805,7 +1820,6 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, | |||
1805 | unsigned offset, int value) | 1820 | unsigned offset, int value) |
1806 | { | 1821 | { |
1807 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | 1822 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
1808 | struct snd_soc_codec *codec = wm8903->codec; | ||
1809 | unsigned int mask, val; | 1823 | unsigned int mask, val; |
1810 | int ret; | 1824 | int ret; |
1811 | 1825 | ||
@@ -1813,8 +1827,8 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, | |||
1813 | val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | | 1827 | val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | |
1814 | (value << WM8903_GP2_LVL_SHIFT); | 1828 | (value << WM8903_GP2_LVL_SHIFT); |
1815 | 1829 | ||
1816 | ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, | 1830 | ret = regmap_update_bits(wm8903->regmap, |
1817 | mask, val); | 1831 | WM8903_GPIO_CONTROL_1 + offset, mask, val); |
1818 | if (ret < 0) | 1832 | if (ret < 0) |
1819 | return ret; | 1833 | return ret; |
1820 | 1834 | ||
@@ -1824,11 +1838,10 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, | |||
1824 | static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 1838 | static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
1825 | { | 1839 | { |
1826 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | 1840 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
1827 | struct snd_soc_codec *codec = wm8903->codec; | ||
1828 | 1841 | ||
1829 | snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, | 1842 | regmap_update_bits(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, |
1830 | WM8903_GP1_LVL_MASK, | 1843 | WM8903_GP1_LVL_MASK, |
1831 | !!value << WM8903_GP1_LVL_SHIFT); | 1844 | !!value << WM8903_GP1_LVL_SHIFT); |
1832 | } | 1845 | } |
1833 | 1846 | ||
1834 | static struct gpio_chip wm8903_template_chip = { | 1847 | static struct gpio_chip wm8903_template_chip = { |
@@ -1842,15 +1855,14 @@ static struct gpio_chip wm8903_template_chip = { | |||
1842 | .can_sleep = 1, | 1855 | .can_sleep = 1, |
1843 | }; | 1856 | }; |
1844 | 1857 | ||
1845 | static void wm8903_init_gpio(struct snd_soc_codec *codec) | 1858 | static void wm8903_init_gpio(struct wm8903_priv *wm8903) |
1846 | { | 1859 | { |
1847 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1848 | struct wm8903_platform_data *pdata = wm8903->pdata; | 1860 | struct wm8903_platform_data *pdata = wm8903->pdata; |
1849 | int ret; | 1861 | int ret; |
1850 | 1862 | ||
1851 | wm8903->gpio_chip = wm8903_template_chip; | 1863 | wm8903->gpio_chip = wm8903_template_chip; |
1852 | wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; | 1864 | wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; |
1853 | wm8903->gpio_chip.dev = codec->dev; | 1865 | wm8903->gpio_chip.dev = wm8903->dev; |
1854 | 1866 | ||
1855 | if (pdata->gpio_base) | 1867 | if (pdata->gpio_base) |
1856 | wm8903->gpio_chip.base = pdata->gpio_base; | 1868 | wm8903->gpio_chip.base = pdata->gpio_base; |
@@ -1859,24 +1871,23 @@ static void wm8903_init_gpio(struct snd_soc_codec *codec) | |||
1859 | 1871 | ||
1860 | ret = gpiochip_add(&wm8903->gpio_chip); | 1872 | ret = gpiochip_add(&wm8903->gpio_chip); |
1861 | if (ret != 0) | 1873 | if (ret != 0) |
1862 | dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); | 1874 | dev_err(wm8903->dev, "Failed to add GPIOs: %d\n", ret); |
1863 | } | 1875 | } |
1864 | 1876 | ||
1865 | static void wm8903_free_gpio(struct snd_soc_codec *codec) | 1877 | static void wm8903_free_gpio(struct wm8903_priv *wm8903) |
1866 | { | 1878 | { |
1867 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1868 | int ret; | 1879 | int ret; |
1869 | 1880 | ||
1870 | ret = gpiochip_remove(&wm8903->gpio_chip); | 1881 | ret = gpiochip_remove(&wm8903->gpio_chip); |
1871 | if (ret != 0) | 1882 | if (ret != 0) |
1872 | dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); | 1883 | dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret); |
1873 | } | 1884 | } |
1874 | #else | 1885 | #else |
1875 | static void wm8903_init_gpio(struct snd_soc_codec *codec) | 1886 | static void wm8903_init_gpio(struct wm8903_priv *wm8903) |
1876 | { | 1887 | { |
1877 | } | 1888 | } |
1878 | 1889 | ||
1879 | static void wm8903_free_gpio(struct snd_soc_codec *codec) | 1890 | static void wm8903_free_gpio(struct wm8903_priv *wm8903) |
1880 | { | 1891 | { |
1881 | } | 1892 | } |
1882 | #endif | 1893 | #endif |
@@ -1884,11 +1895,7 @@ static void wm8903_free_gpio(struct snd_soc_codec *codec) | |||
1884 | static int wm8903_probe(struct snd_soc_codec *codec) | 1895 | static int wm8903_probe(struct snd_soc_codec *codec) |
1885 | { | 1896 | { |
1886 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1897 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
1887 | struct wm8903_platform_data *pdata = wm8903->pdata; | 1898 | int ret; |
1888 | int ret, i; | ||
1889 | int trigger, irq_pol; | ||
1890 | u16 val; | ||
1891 | bool mic_gpio = false; | ||
1892 | 1899 | ||
1893 | wm8903->codec = codec; | 1900 | wm8903->codec = codec; |
1894 | codec->control_data = wm8903->regmap; | 1901 | codec->control_data = wm8903->regmap; |
@@ -1899,121 +1906,16 @@ static int wm8903_probe(struct snd_soc_codec *codec) | |||
1899 | return ret; | 1906 | return ret; |
1900 | } | 1907 | } |
1901 | 1908 | ||
1902 | /* Set up GPIOs, detect if any are MIC detect outputs */ | ||
1903 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { | ||
1904 | if ((!pdata->gpio_cfg[i]) || | ||
1905 | (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO)) | ||
1906 | continue; | ||
1907 | |||
1908 | snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, | ||
1909 | pdata->gpio_cfg[i] & 0x7fff); | ||
1910 | |||
1911 | val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) | ||
1912 | >> WM8903_GP1_FN_SHIFT; | ||
1913 | |||
1914 | switch (val) { | ||
1915 | case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: | ||
1916 | case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: | ||
1917 | mic_gpio = true; | ||
1918 | break; | ||
1919 | default: | ||
1920 | break; | ||
1921 | } | ||
1922 | } | ||
1923 | |||
1924 | /* Set up microphone detection */ | ||
1925 | snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, | ||
1926 | pdata->micdet_cfg); | ||
1927 | |||
1928 | /* Microphone detection needs the WSEQ clock */ | ||
1929 | if (pdata->micdet_cfg) | ||
1930 | snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, | ||
1931 | WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); | ||
1932 | |||
1933 | /* If microphone detection is enabled by pdata but | ||
1934 | * detected via IRQ then interrupts can be lost before | ||
1935 | * the machine driver has set up microphone detection | ||
1936 | * IRQs as the IRQs are clear on read. The detection | ||
1937 | * will be enabled when the machine driver configures. | ||
1938 | */ | ||
1939 | WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); | ||
1940 | |||
1941 | wm8903->mic_delay = pdata->micdet_delay; | ||
1942 | |||
1943 | if (wm8903->irq) { | ||
1944 | if (pdata->irq_active_low) { | ||
1945 | trigger = IRQF_TRIGGER_LOW; | ||
1946 | irq_pol = WM8903_IRQ_POL; | ||
1947 | } else { | ||
1948 | trigger = IRQF_TRIGGER_HIGH; | ||
1949 | irq_pol = 0; | ||
1950 | } | ||
1951 | |||
1952 | snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, | ||
1953 | WM8903_IRQ_POL, irq_pol); | ||
1954 | |||
1955 | ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq, | ||
1956 | trigger | IRQF_ONESHOT, | ||
1957 | "wm8903", codec); | ||
1958 | if (ret != 0) { | ||
1959 | dev_err(codec->dev, "Failed to request IRQ: %d\n", | ||
1960 | ret); | ||
1961 | return ret; | ||
1962 | } | ||
1963 | |||
1964 | /* Enable write sequencer interrupts */ | ||
1965 | snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK, | ||
1966 | WM8903_IM_WSEQ_BUSY_EINT, 0); | ||
1967 | } | ||
1968 | |||
1969 | /* power on device */ | 1909 | /* power on device */ |
1970 | wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1910 | wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1971 | 1911 | ||
1972 | /* Latch volume update bits */ | ||
1973 | val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT); | ||
1974 | val |= WM8903_ADCVU; | ||
1975 | snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val); | ||
1976 | snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val); | ||
1977 | |||
1978 | val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT); | ||
1979 | val |= WM8903_DACVU; | ||
1980 | snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val); | ||
1981 | snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val); | ||
1982 | |||
1983 | val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT); | ||
1984 | val |= WM8903_HPOUTVU; | ||
1985 | snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val); | ||
1986 | snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val); | ||
1987 | |||
1988 | val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT); | ||
1989 | val |= WM8903_LINEOUTVU; | ||
1990 | snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val); | ||
1991 | snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val); | ||
1992 | |||
1993 | val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT); | ||
1994 | val |= WM8903_SPKVU; | ||
1995 | snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val); | ||
1996 | snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); | ||
1997 | |||
1998 | /* Enable DAC soft mute by default */ | ||
1999 | snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, | ||
2000 | WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, | ||
2001 | WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); | ||
2002 | |||
2003 | wm8903_init_gpio(codec); | ||
2004 | |||
2005 | return ret; | 1912 | return ret; |
2006 | } | 1913 | } |
2007 | 1914 | ||
2008 | /* power down chip */ | 1915 | /* power down chip */ |
2009 | static int wm8903_remove(struct snd_soc_codec *codec) | 1916 | static int wm8903_remove(struct snd_soc_codec *codec) |
2010 | { | 1917 | { |
2011 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
2012 | |||
2013 | wm8903_free_gpio(codec); | ||
2014 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1918 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2015 | if (wm8903->irq) | ||
2016 | free_irq(wm8903->irq, codec); | ||
2017 | 1919 | ||
2018 | return 0; | 1920 | return 0; |
2019 | } | 1921 | } |
@@ -2123,15 +2025,18 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
2123 | { | 2025 | { |
2124 | struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); | 2026 | struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); |
2125 | struct wm8903_priv *wm8903; | 2027 | struct wm8903_priv *wm8903; |
2126 | unsigned int val; | 2028 | int trigger; |
2127 | int ret; | 2029 | bool mic_gpio = false; |
2030 | unsigned int val, irq_pol; | ||
2031 | int ret, i; | ||
2128 | 2032 | ||
2129 | wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), | 2033 | wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), |
2130 | GFP_KERNEL); | 2034 | GFP_KERNEL); |
2131 | if (wm8903 == NULL) | 2035 | if (wm8903 == NULL) |
2132 | return -ENOMEM; | 2036 | return -ENOMEM; |
2037 | wm8903->dev = &i2c->dev; | ||
2133 | 2038 | ||
2134 | wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); | 2039 | wm8903->regmap = devm_regmap_init_i2c(i2c, &wm8903_regmap); |
2135 | if (IS_ERR(wm8903->regmap)) { | 2040 | if (IS_ERR(wm8903->regmap)) { |
2136 | ret = PTR_ERR(wm8903->regmap); | 2041 | ret = PTR_ERR(wm8903->regmap); |
2137 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 2042 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -2140,7 +2045,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
2140 | } | 2045 | } |
2141 | 2046 | ||
2142 | i2c_set_clientdata(i2c, wm8903); | 2047 | i2c_set_clientdata(i2c, wm8903); |
2143 | wm8903->irq = i2c->irq; | ||
2144 | 2048 | ||
2145 | /* If no platform data was supplied, create storage for defaults */ | 2049 | /* If no platform data was supplied, create storage for defaults */ |
2146 | if (pdata) { | 2050 | if (pdata) { |
@@ -2167,6 +2071,8 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
2167 | } | 2071 | } |
2168 | } | 2072 | } |
2169 | 2073 | ||
2074 | pdata = wm8903->pdata; | ||
2075 | |||
2170 | ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); | 2076 | ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); |
2171 | if (ret != 0) { | 2077 | if (ret != 0) { |
2172 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | 2078 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); |
@@ -2189,6 +2095,107 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
2189 | /* Reset the device */ | 2095 | /* Reset the device */ |
2190 | regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); | 2096 | regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); |
2191 | 2097 | ||
2098 | wm8903_init_gpio(wm8903); | ||
2099 | |||
2100 | /* Set up GPIO pin state, detect if any are MIC detect outputs */ | ||
2101 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { | ||
2102 | if ((!pdata->gpio_cfg[i]) || | ||
2103 | (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO)) | ||
2104 | continue; | ||
2105 | |||
2106 | regmap_write(wm8903->regmap, WM8903_GPIO_CONTROL_1 + i, | ||
2107 | pdata->gpio_cfg[i] & 0x7fff); | ||
2108 | |||
2109 | val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) | ||
2110 | >> WM8903_GP1_FN_SHIFT; | ||
2111 | |||
2112 | switch (val) { | ||
2113 | case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: | ||
2114 | case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: | ||
2115 | mic_gpio = true; | ||
2116 | break; | ||
2117 | default: | ||
2118 | break; | ||
2119 | } | ||
2120 | } | ||
2121 | |||
2122 | /* Set up microphone detection */ | ||
2123 | regmap_write(wm8903->regmap, WM8903_MIC_BIAS_CONTROL_0, | ||
2124 | pdata->micdet_cfg); | ||
2125 | |||
2126 | /* Microphone detection needs the WSEQ clock */ | ||
2127 | if (pdata->micdet_cfg) | ||
2128 | regmap_update_bits(wm8903->regmap, WM8903_WRITE_SEQUENCER_0, | ||
2129 | WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); | ||
2130 | |||
2131 | /* If microphone detection is enabled by pdata but | ||
2132 | * detected via IRQ then interrupts can be lost before | ||
2133 | * the machine driver has set up microphone detection | ||
2134 | * IRQs as the IRQs are clear on read. The detection | ||
2135 | * will be enabled when the machine driver configures. | ||
2136 | */ | ||
2137 | WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); | ||
2138 | |||
2139 | wm8903->mic_delay = pdata->micdet_delay; | ||
2140 | |||
2141 | if (i2c->irq) { | ||
2142 | if (pdata->irq_active_low) { | ||
2143 | trigger = IRQF_TRIGGER_LOW; | ||
2144 | irq_pol = WM8903_IRQ_POL; | ||
2145 | } else { | ||
2146 | trigger = IRQF_TRIGGER_HIGH; | ||
2147 | irq_pol = 0; | ||
2148 | } | ||
2149 | |||
2150 | regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_CONTROL, | ||
2151 | WM8903_IRQ_POL, irq_pol); | ||
2152 | |||
2153 | ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq, | ||
2154 | trigger | IRQF_ONESHOT, | ||
2155 | "wm8903", wm8903); | ||
2156 | if (ret != 0) { | ||
2157 | dev_err(wm8903->dev, "Failed to request IRQ: %d\n", | ||
2158 | ret); | ||
2159 | return ret; | ||
2160 | } | ||
2161 | |||
2162 | /* Enable write sequencer interrupts */ | ||
2163 | regmap_update_bits(wm8903->regmap, | ||
2164 | WM8903_INTERRUPT_STATUS_1_MASK, | ||
2165 | WM8903_IM_WSEQ_BUSY_EINT, 0); | ||
2166 | } | ||
2167 | |||
2168 | /* Latch volume update bits */ | ||
2169 | regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_LEFT, | ||
2170 | WM8903_ADCVU, WM8903_ADCVU); | ||
2171 | regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_RIGHT, | ||
2172 | WM8903_ADCVU, WM8903_ADCVU); | ||
2173 | |||
2174 | regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_LEFT, | ||
2175 | WM8903_DACVU, WM8903_DACVU); | ||
2176 | regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_RIGHT, | ||
2177 | WM8903_DACVU, WM8903_DACVU); | ||
2178 | |||
2179 | regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_LEFT, | ||
2180 | WM8903_HPOUTVU, WM8903_HPOUTVU); | ||
2181 | regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_RIGHT, | ||
2182 | WM8903_HPOUTVU, WM8903_HPOUTVU); | ||
2183 | |||
2184 | regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_LEFT, | ||
2185 | WM8903_LINEOUTVU, WM8903_LINEOUTVU); | ||
2186 | regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_RIGHT, | ||
2187 | WM8903_LINEOUTVU, WM8903_LINEOUTVU); | ||
2188 | |||
2189 | regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_LEFT, | ||
2190 | WM8903_SPKVU, WM8903_SPKVU); | ||
2191 | regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_RIGHT, | ||
2192 | WM8903_SPKVU, WM8903_SPKVU); | ||
2193 | |||
2194 | /* Enable DAC soft mute by default */ | ||
2195 | regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_1, | ||
2196 | WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, | ||
2197 | WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); | ||
2198 | |||
2192 | ret = snd_soc_register_codec(&i2c->dev, | 2199 | ret = snd_soc_register_codec(&i2c->dev, |
2193 | &soc_codec_dev_wm8903, &wm8903_dai, 1); | 2200 | &soc_codec_dev_wm8903, &wm8903_dai, 1); |
2194 | if (ret != 0) | 2201 | if (ret != 0) |
@@ -2196,7 +2203,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
2196 | 2203 | ||
2197 | return 0; | 2204 | return 0; |
2198 | err: | 2205 | err: |
2199 | regmap_exit(wm8903->regmap); | ||
2200 | return ret; | 2206 | return ret; |
2201 | } | 2207 | } |
2202 | 2208 | ||
@@ -2204,7 +2210,9 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client) | |||
2204 | { | 2210 | { |
2205 | struct wm8903_priv *wm8903 = i2c_get_clientdata(client); | 2211 | struct wm8903_priv *wm8903 = i2c_get_clientdata(client); |
2206 | 2212 | ||
2207 | regmap_exit(wm8903->regmap); | 2213 | if (client->irq) |
2214 | free_irq(client->irq, wm8903); | ||
2215 | wm8903_free_gpio(wm8903); | ||
2208 | snd_soc_unregister_codec(&client->dev); | 2216 | snd_soc_unregister_codec(&client->dev); |
2209 | 2217 | ||
2210 | return 0; | 2218 | return 0; |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 65d525d74c54..560a9a47596b 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8904.c -- WM8904 ALSA SoC Audio driver | 2 | * wm8904.c -- WM8904 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics plc | 4 | * Copyright 2009-12 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
@@ -2263,7 +2263,7 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | |||
2263 | if (wm8904 == NULL) | 2263 | if (wm8904 == NULL) |
2264 | return -ENOMEM; | 2264 | return -ENOMEM; |
2265 | 2265 | ||
2266 | wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap); | 2266 | wm8904->regmap = devm_regmap_init_i2c(i2c, &wm8904_regmap); |
2267 | if (IS_ERR(wm8904->regmap)) { | 2267 | if (IS_ERR(wm8904->regmap)) { |
2268 | ret = PTR_ERR(wm8904->regmap); | 2268 | ret = PTR_ERR(wm8904->regmap); |
2269 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 2269 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -2283,15 +2283,12 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | |||
2283 | return 0; | 2283 | return 0; |
2284 | 2284 | ||
2285 | err: | 2285 | err: |
2286 | regmap_exit(wm8904->regmap); | ||
2287 | return ret; | 2286 | return ret; |
2288 | } | 2287 | } |
2289 | 2288 | ||
2290 | static __devexit int wm8904_i2c_remove(struct i2c_client *client) | 2289 | static __devexit int wm8904_i2c_remove(struct i2c_client *client) |
2291 | { | 2290 | { |
2292 | struct wm8904_priv *wm8904 = i2c_get_clientdata(client); | ||
2293 | snd_soc_unregister_codec(&client->dev); | 2291 | snd_soc_unregister_codec(&client->dev); |
2294 | regmap_exit(wm8904->regmap); | ||
2295 | return 0; | 2292 | return 0; |
2296 | } | 2293 | } |
2297 | 2294 | ||
@@ -2313,23 +2310,7 @@ static struct i2c_driver wm8904_i2c_driver = { | |||
2313 | .id_table = wm8904_i2c_id, | 2310 | .id_table = wm8904_i2c_id, |
2314 | }; | 2311 | }; |
2315 | 2312 | ||
2316 | static int __init wm8904_modinit(void) | 2313 | module_i2c_driver(wm8904_i2c_driver); |
2317 | { | ||
2318 | int ret = 0; | ||
2319 | ret = i2c_add_driver(&wm8904_i2c_driver); | ||
2320 | if (ret != 0) { | ||
2321 | printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", | ||
2322 | ret); | ||
2323 | } | ||
2324 | return ret; | ||
2325 | } | ||
2326 | module_init(wm8904_modinit); | ||
2327 | |||
2328 | static void __exit wm8904_exit(void) | ||
2329 | { | ||
2330 | i2c_del_driver(&wm8904_i2c_driver); | ||
2331 | } | ||
2332 | module_exit(wm8904_exit); | ||
2333 | 2314 | ||
2334 | MODULE_DESCRIPTION("ASoC WM8904 driver"); | 2315 | MODULE_DESCRIPTION("ASoC WM8904 driver"); |
2335 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 2316 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8bc659d8dd2e..96518ac8e24c 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * wm8960.c -- WM8960 ALSA SoC Audio driver | 2 | * wm8960.c -- WM8960 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2007-11 Wolfson Microelectronics, plc | ||
5 | * | ||
4 | * Author: Liam Girdwood | 6 | * Author: Liam Girdwood |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 05ea7c274093..01edbcc754d2 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * wm8961.c -- WM8961 ALSA SoC Audio driver | 2 | * wm8961.c -- WM8961 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2009-10 Wolfson Microelectronics, plc | ||
5 | * | ||
4 | * Author: Mark Brown | 6 | * Author: Mark Brown |
5 | * | 7 | * |
6 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 0cfce9999c89..27da4d722edc 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8962.c -- WM8962 ALSA SoC Audio driver | 2 | * wm8962.c -- WM8962 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2010 Wolfson Microelectronics plc | 4 | * Copyright 2010-2 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 36acfccab999..9fd80d688979 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8993.c -- WM8993 ALSA SoC audio driver | 2 | * wm8993.c -- WM8993 ALSA SoC audio driver |
3 | * | 3 | * |
4 | * Copyright 2009, 2010 Wolfson Microelectronics plc | 4 | * Copyright 2009-12 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 993639d694ce..5d4d7df8d339 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8994.c -- WM8994 ALSA SoC Audio driver | 2 | * wm8994.c -- WM8994 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics plc | 4 | * Copyright 2009-12 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 8af422e38fd0..a6b5cffa498a 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm8996.c - WM8996 audio codec interface | 2 | * wm8996.c - WM8996 audio codec interface |
3 | * | 3 | * |
4 | * Copyright 2011 Wolfson Microelectronics PLC. | 4 | * Copyright 2011-2 Wolfson Microelectronics PLC. |
5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
@@ -296,184 +296,6 @@ static struct reg_default wm8996_reg[] = { | |||
296 | { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, | 296 | { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, |
297 | { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, | 297 | { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, |
298 | { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, | 298 | { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, |
299 | { WM8996_WRITE_SEQUENCER_0, 0x1 }, | ||
300 | { WM8996_WRITE_SEQUENCER_1, 0x1 }, | ||
301 | { WM8996_WRITE_SEQUENCER_3, 0x6 }, | ||
302 | { WM8996_WRITE_SEQUENCER_4, 0x40 }, | ||
303 | { WM8996_WRITE_SEQUENCER_5, 0x1 }, | ||
304 | { WM8996_WRITE_SEQUENCER_6, 0xf }, | ||
305 | { WM8996_WRITE_SEQUENCER_7, 0x6 }, | ||
306 | { WM8996_WRITE_SEQUENCER_8, 0x1 }, | ||
307 | { WM8996_WRITE_SEQUENCER_9, 0x3 }, | ||
308 | { WM8996_WRITE_SEQUENCER_10, 0x104 }, | ||
309 | { WM8996_WRITE_SEQUENCER_12, 0x60 }, | ||
310 | { WM8996_WRITE_SEQUENCER_13, 0x11 }, | ||
311 | { WM8996_WRITE_SEQUENCER_14, 0x401 }, | ||
312 | { WM8996_WRITE_SEQUENCER_16, 0x50 }, | ||
313 | { WM8996_WRITE_SEQUENCER_17, 0x3 }, | ||
314 | { WM8996_WRITE_SEQUENCER_18, 0x100 }, | ||
315 | { WM8996_WRITE_SEQUENCER_20, 0x51 }, | ||
316 | { WM8996_WRITE_SEQUENCER_21, 0x3 }, | ||
317 | { WM8996_WRITE_SEQUENCER_22, 0x104 }, | ||
318 | { WM8996_WRITE_SEQUENCER_23, 0xa }, | ||
319 | { WM8996_WRITE_SEQUENCER_24, 0x60 }, | ||
320 | { WM8996_WRITE_SEQUENCER_25, 0x3b }, | ||
321 | { WM8996_WRITE_SEQUENCER_26, 0x502 }, | ||
322 | { WM8996_WRITE_SEQUENCER_27, 0x100 }, | ||
323 | { WM8996_WRITE_SEQUENCER_28, 0x2fff }, | ||
324 | { WM8996_WRITE_SEQUENCER_32, 0x2fff }, | ||
325 | { WM8996_WRITE_SEQUENCER_36, 0x2fff }, | ||
326 | { WM8996_WRITE_SEQUENCER_40, 0x2fff }, | ||
327 | { WM8996_WRITE_SEQUENCER_44, 0x2fff }, | ||
328 | { WM8996_WRITE_SEQUENCER_48, 0x2fff }, | ||
329 | { WM8996_WRITE_SEQUENCER_52, 0x2fff }, | ||
330 | { WM8996_WRITE_SEQUENCER_56, 0x2fff }, | ||
331 | { WM8996_WRITE_SEQUENCER_60, 0x2fff }, | ||
332 | { WM8996_WRITE_SEQUENCER_64, 0x1 }, | ||
333 | { WM8996_WRITE_SEQUENCER_65, 0x1 }, | ||
334 | { WM8996_WRITE_SEQUENCER_67, 0x6 }, | ||
335 | { WM8996_WRITE_SEQUENCER_68, 0x40 }, | ||
336 | { WM8996_WRITE_SEQUENCER_69, 0x1 }, | ||
337 | { WM8996_WRITE_SEQUENCER_70, 0xf }, | ||
338 | { WM8996_WRITE_SEQUENCER_71, 0x6 }, | ||
339 | { WM8996_WRITE_SEQUENCER_72, 0x1 }, | ||
340 | { WM8996_WRITE_SEQUENCER_73, 0x3 }, | ||
341 | { WM8996_WRITE_SEQUENCER_74, 0x104 }, | ||
342 | { WM8996_WRITE_SEQUENCER_76, 0x60 }, | ||
343 | { WM8996_WRITE_SEQUENCER_77, 0x11 }, | ||
344 | { WM8996_WRITE_SEQUENCER_78, 0x401 }, | ||
345 | { WM8996_WRITE_SEQUENCER_80, 0x50 }, | ||
346 | { WM8996_WRITE_SEQUENCER_81, 0x3 }, | ||
347 | { WM8996_WRITE_SEQUENCER_82, 0x100 }, | ||
348 | { WM8996_WRITE_SEQUENCER_84, 0x60 }, | ||
349 | { WM8996_WRITE_SEQUENCER_85, 0x3b }, | ||
350 | { WM8996_WRITE_SEQUENCER_86, 0x502 }, | ||
351 | { WM8996_WRITE_SEQUENCER_87, 0x100 }, | ||
352 | { WM8996_WRITE_SEQUENCER_88, 0x2fff }, | ||
353 | { WM8996_WRITE_SEQUENCER_92, 0x2fff }, | ||
354 | { WM8996_WRITE_SEQUENCER_96, 0x2fff }, | ||
355 | { WM8996_WRITE_SEQUENCER_100, 0x2fff }, | ||
356 | { WM8996_WRITE_SEQUENCER_104, 0x2fff }, | ||
357 | { WM8996_WRITE_SEQUENCER_108, 0x2fff }, | ||
358 | { WM8996_WRITE_SEQUENCER_112, 0x2fff }, | ||
359 | { WM8996_WRITE_SEQUENCER_116, 0x2fff }, | ||
360 | { WM8996_WRITE_SEQUENCER_120, 0x2fff }, | ||
361 | { WM8996_WRITE_SEQUENCER_124, 0x2fff }, | ||
362 | { WM8996_WRITE_SEQUENCER_128, 0x1 }, | ||
363 | { WM8996_WRITE_SEQUENCER_129, 0x1 }, | ||
364 | { WM8996_WRITE_SEQUENCER_131, 0x6 }, | ||
365 | { WM8996_WRITE_SEQUENCER_132, 0x40 }, | ||
366 | { WM8996_WRITE_SEQUENCER_133, 0x1 }, | ||
367 | { WM8996_WRITE_SEQUENCER_134, 0xf }, | ||
368 | { WM8996_WRITE_SEQUENCER_135, 0x6 }, | ||
369 | { WM8996_WRITE_SEQUENCER_136, 0x1 }, | ||
370 | { WM8996_WRITE_SEQUENCER_137, 0x3 }, | ||
371 | { WM8996_WRITE_SEQUENCER_138, 0x106 }, | ||
372 | { WM8996_WRITE_SEQUENCER_140, 0x61 }, | ||
373 | { WM8996_WRITE_SEQUENCER_141, 0x11 }, | ||
374 | { WM8996_WRITE_SEQUENCER_142, 0x401 }, | ||
375 | { WM8996_WRITE_SEQUENCER_144, 0x50 }, | ||
376 | { WM8996_WRITE_SEQUENCER_145, 0x3 }, | ||
377 | { WM8996_WRITE_SEQUENCER_146, 0x102 }, | ||
378 | { WM8996_WRITE_SEQUENCER_148, 0x51 }, | ||
379 | { WM8996_WRITE_SEQUENCER_149, 0x3 }, | ||
380 | { WM8996_WRITE_SEQUENCER_150, 0x106 }, | ||
381 | { WM8996_WRITE_SEQUENCER_151, 0xa }, | ||
382 | { WM8996_WRITE_SEQUENCER_152, 0x61 }, | ||
383 | { WM8996_WRITE_SEQUENCER_153, 0x3b }, | ||
384 | { WM8996_WRITE_SEQUENCER_154, 0x502 }, | ||
385 | { WM8996_WRITE_SEQUENCER_155, 0x100 }, | ||
386 | { WM8996_WRITE_SEQUENCER_156, 0x2fff }, | ||
387 | { WM8996_WRITE_SEQUENCER_160, 0x2fff }, | ||
388 | { WM8996_WRITE_SEQUENCER_164, 0x2fff }, | ||
389 | { WM8996_WRITE_SEQUENCER_168, 0x2fff }, | ||
390 | { WM8996_WRITE_SEQUENCER_172, 0x2fff }, | ||
391 | { WM8996_WRITE_SEQUENCER_176, 0x2fff }, | ||
392 | { WM8996_WRITE_SEQUENCER_180, 0x2fff }, | ||
393 | { WM8996_WRITE_SEQUENCER_184, 0x2fff }, | ||
394 | { WM8996_WRITE_SEQUENCER_188, 0x2fff }, | ||
395 | { WM8996_WRITE_SEQUENCER_192, 0x1 }, | ||
396 | { WM8996_WRITE_SEQUENCER_193, 0x1 }, | ||
397 | { WM8996_WRITE_SEQUENCER_195, 0x6 }, | ||
398 | { WM8996_WRITE_SEQUENCER_196, 0x40 }, | ||
399 | { WM8996_WRITE_SEQUENCER_197, 0x1 }, | ||
400 | { WM8996_WRITE_SEQUENCER_198, 0xf }, | ||
401 | { WM8996_WRITE_SEQUENCER_199, 0x6 }, | ||
402 | { WM8996_WRITE_SEQUENCER_200, 0x1 }, | ||
403 | { WM8996_WRITE_SEQUENCER_201, 0x3 }, | ||
404 | { WM8996_WRITE_SEQUENCER_202, 0x106 }, | ||
405 | { WM8996_WRITE_SEQUENCER_204, 0x61 }, | ||
406 | { WM8996_WRITE_SEQUENCER_205, 0x11 }, | ||
407 | { WM8996_WRITE_SEQUENCER_206, 0x401 }, | ||
408 | { WM8996_WRITE_SEQUENCER_208, 0x50 }, | ||
409 | { WM8996_WRITE_SEQUENCER_209, 0x3 }, | ||
410 | { WM8996_WRITE_SEQUENCER_210, 0x102 }, | ||
411 | { WM8996_WRITE_SEQUENCER_212, 0x61 }, | ||
412 | { WM8996_WRITE_SEQUENCER_213, 0x3b }, | ||
413 | { WM8996_WRITE_SEQUENCER_214, 0x502 }, | ||
414 | { WM8996_WRITE_SEQUENCER_215, 0x100 }, | ||
415 | { WM8996_WRITE_SEQUENCER_216, 0x2fff }, | ||
416 | { WM8996_WRITE_SEQUENCER_220, 0x2fff }, | ||
417 | { WM8996_WRITE_SEQUENCER_224, 0x2fff }, | ||
418 | { WM8996_WRITE_SEQUENCER_228, 0x2fff }, | ||
419 | { WM8996_WRITE_SEQUENCER_232, 0x2fff }, | ||
420 | { WM8996_WRITE_SEQUENCER_236, 0x2fff }, | ||
421 | { WM8996_WRITE_SEQUENCER_240, 0x2fff }, | ||
422 | { WM8996_WRITE_SEQUENCER_244, 0x2fff }, | ||
423 | { WM8996_WRITE_SEQUENCER_248, 0x2fff }, | ||
424 | { WM8996_WRITE_SEQUENCER_252, 0x2fff }, | ||
425 | { WM8996_WRITE_SEQUENCER_256, 0x60 }, | ||
426 | { WM8996_WRITE_SEQUENCER_258, 0x601 }, | ||
427 | { WM8996_WRITE_SEQUENCER_260, 0x50 }, | ||
428 | { WM8996_WRITE_SEQUENCER_262, 0x100 }, | ||
429 | { WM8996_WRITE_SEQUENCER_264, 0x1 }, | ||
430 | { WM8996_WRITE_SEQUENCER_266, 0x104 }, | ||
431 | { WM8996_WRITE_SEQUENCER_267, 0x100 }, | ||
432 | { WM8996_WRITE_SEQUENCER_268, 0x2fff }, | ||
433 | { WM8996_WRITE_SEQUENCER_272, 0x2fff }, | ||
434 | { WM8996_WRITE_SEQUENCER_276, 0x2fff }, | ||
435 | { WM8996_WRITE_SEQUENCER_280, 0x2fff }, | ||
436 | { WM8996_WRITE_SEQUENCER_284, 0x2fff }, | ||
437 | { WM8996_WRITE_SEQUENCER_288, 0x2fff }, | ||
438 | { WM8996_WRITE_SEQUENCER_292, 0x2fff }, | ||
439 | { WM8996_WRITE_SEQUENCER_296, 0x2fff }, | ||
440 | { WM8996_WRITE_SEQUENCER_300, 0x2fff }, | ||
441 | { WM8996_WRITE_SEQUENCER_304, 0x2fff }, | ||
442 | { WM8996_WRITE_SEQUENCER_308, 0x2fff }, | ||
443 | { WM8996_WRITE_SEQUENCER_312, 0x2fff }, | ||
444 | { WM8996_WRITE_SEQUENCER_316, 0x2fff }, | ||
445 | { WM8996_WRITE_SEQUENCER_320, 0x61 }, | ||
446 | { WM8996_WRITE_SEQUENCER_322, 0x601 }, | ||
447 | { WM8996_WRITE_SEQUENCER_324, 0x50 }, | ||
448 | { WM8996_WRITE_SEQUENCER_326, 0x102 }, | ||
449 | { WM8996_WRITE_SEQUENCER_328, 0x1 }, | ||
450 | { WM8996_WRITE_SEQUENCER_330, 0x106 }, | ||
451 | { WM8996_WRITE_SEQUENCER_331, 0x100 }, | ||
452 | { WM8996_WRITE_SEQUENCER_332, 0x2fff }, | ||
453 | { WM8996_WRITE_SEQUENCER_336, 0x2fff }, | ||
454 | { WM8996_WRITE_SEQUENCER_340, 0x2fff }, | ||
455 | { WM8996_WRITE_SEQUENCER_344, 0x2fff }, | ||
456 | { WM8996_WRITE_SEQUENCER_348, 0x2fff }, | ||
457 | { WM8996_WRITE_SEQUENCER_352, 0x2fff }, | ||
458 | { WM8996_WRITE_SEQUENCER_356, 0x2fff }, | ||
459 | { WM8996_WRITE_SEQUENCER_360, 0x2fff }, | ||
460 | { WM8996_WRITE_SEQUENCER_364, 0x2fff }, | ||
461 | { WM8996_WRITE_SEQUENCER_368, 0x2fff }, | ||
462 | { WM8996_WRITE_SEQUENCER_372, 0x2fff }, | ||
463 | { WM8996_WRITE_SEQUENCER_376, 0x2fff }, | ||
464 | { WM8996_WRITE_SEQUENCER_380, 0x2fff }, | ||
465 | { WM8996_WRITE_SEQUENCER_384, 0x60 }, | ||
466 | { WM8996_WRITE_SEQUENCER_386, 0x601 }, | ||
467 | { WM8996_WRITE_SEQUENCER_388, 0x61 }, | ||
468 | { WM8996_WRITE_SEQUENCER_390, 0x601 }, | ||
469 | { WM8996_WRITE_SEQUENCER_392, 0x50 }, | ||
470 | { WM8996_WRITE_SEQUENCER_394, 0x300 }, | ||
471 | { WM8996_WRITE_SEQUENCER_396, 0x1 }, | ||
472 | { WM8996_WRITE_SEQUENCER_398, 0x304 }, | ||
473 | { WM8996_WRITE_SEQUENCER_400, 0x40 }, | ||
474 | { WM8996_WRITE_SEQUENCER_402, 0xf }, | ||
475 | { WM8996_WRITE_SEQUENCER_404, 0x1 }, | ||
476 | { WM8996_WRITE_SEQUENCER_407, 0x100 }, | ||
477 | }; | 299 | }; |
478 | 300 | ||
479 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); | 301 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); |
@@ -3178,7 +3000,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | |||
3178 | msleep(5); | 3000 | msleep(5); |
3179 | } | 3001 | } |
3180 | 3002 | ||
3181 | wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); | 3003 | wm8996->regmap = devm_regmap_init_i2c(i2c, &wm8996_regmap); |
3182 | if (IS_ERR(wm8996->regmap)) { | 3004 | if (IS_ERR(wm8996->regmap)) { |
3183 | ret = PTR_ERR(wm8996->regmap); | 3005 | ret = PTR_ERR(wm8996->regmap); |
3184 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | 3006 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
@@ -3227,7 +3049,6 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | |||
3227 | err_gpiolib: | 3049 | err_gpiolib: |
3228 | wm8996_free_gpio(wm8996); | 3050 | wm8996_free_gpio(wm8996); |
3229 | err_regmap: | 3051 | err_regmap: |
3230 | regmap_exit(wm8996->regmap); | ||
3231 | err_enable: | 3052 | err_enable: |
3232 | if (wm8996->pdata.ldo_ena > 0) | 3053 | if (wm8996->pdata.ldo_ena > 0) |
3233 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 3054 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
@@ -3246,7 +3067,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) | |||
3246 | 3067 | ||
3247 | snd_soc_unregister_codec(&client->dev); | 3068 | snd_soc_unregister_codec(&client->dev); |
3248 | wm8996_free_gpio(wm8996); | 3069 | wm8996_free_gpio(wm8996); |
3249 | regmap_exit(wm8996->regmap); | ||
3250 | if (wm8996->pdata.ldo_ena > 0) { | 3070 | if (wm8996->pdata.ldo_ena > 0) { |
3251 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 3071 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
3252 | gpio_free(wm8996->pdata.ldo_ena); | 3072 | gpio_free(wm8996->pdata.ldo_ena); |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 9328270df16c..2de74e1ea225 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Author: Mark Brown | 4 | * Author: Mark Brown |
5 | * | 5 | * |
6 | * Copyright 2009 Wolfson Microelectronics plc | 6 | * Copyright 2009-12 Wolfson Microelectronics plc |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 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 | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 4b263b6edf13..2c2346fdd637 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ALSA SoC WM9090 driver | 2 | * ALSA SoC WM9090 driver |
3 | * | 3 | * |
4 | * Copyright 2009, 2010 Wolfson Microelectronics | 4 | * Copyright 2009-12 Wolfson Microelectronics |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index a1541414d904..099e6ec32125 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm9712.c -- ALSA Soc WM9712 codec support | 2 | * wm9712.c -- ALSA Soc WM9712 codec support |
3 | * | 3 | * |
4 | * Copyright 2006 Wolfson Microelectronics PLC. | 4 | * Copyright 2006-12 Wolfson Microelectronics PLC. |
5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> | 5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 2d22cc70d536..3eb19fb71d17 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm9713.c -- ALSA Soc WM9713 codec support | 2 | * wm9713.c -- ALSA Soc WM9713 codec support |
3 | * | 3 | * |
4 | * Copyright 2006 Wolfson Microelectronics PLC. | 4 | * Copyright 2006-10 Wolfson Microelectronics PLC. |
5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> | 5 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index dfe957a47f29..61baa48823cb 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * wm_hubs.c -- WM8993/4 common code | 2 | * wm_hubs.c -- WM8993/4 common code |
3 | * | 3 | * |
4 | * Copyright 2009 Wolfson Microelectronics plc | 4 | * Copyright 2009-12 Wolfson Microelectronics plc |
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 3e6e8764b2e6..215113b05f7d 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c | |||
@@ -133,7 +133,7 @@ static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev) | |||
133 | mxs_sgtl5000_dai[i].codec_name = NULL; | 133 | mxs_sgtl5000_dai[i].codec_name = NULL; |
134 | mxs_sgtl5000_dai[i].codec_of_node = codec_np; | 134 | mxs_sgtl5000_dai[i].codec_of_node = codec_np; |
135 | mxs_sgtl5000_dai[i].cpu_dai_name = NULL; | 135 | mxs_sgtl5000_dai[i].cpu_dai_name = NULL; |
136 | mxs_sgtl5000_dai[i].cpu_dai_of_node = saif_np[i]; | 136 | mxs_sgtl5000_dai[i].cpu_of_node = saif_np[i]; |
137 | mxs_sgtl5000_dai[i].platform_name = NULL; | 137 | mxs_sgtl5000_dai[i].platform_name = NULL; |
138 | mxs_sgtl5000_dai[i].platform_of_node = saif_np[i]; | 138 | mxs_sgtl5000_dai[i].platform_of_node = saif_np[i]; |
139 | } | 139 | } |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 2ef98536f1da..53486ff9c2af 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -247,7 +247,7 @@ struct fsi_priv { | |||
247 | struct fsi_stream_handler { | 247 | struct fsi_stream_handler { |
248 | int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); | 248 | int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); |
249 | int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); | 249 | int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); |
250 | int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io); | 250 | int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev); |
251 | int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); | 251 | int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); |
252 | int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); | 252 | int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); |
253 | void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, | 253 | void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, |
@@ -571,16 +571,16 @@ static int fsi_stream_transfer(struct fsi_stream *io) | |||
571 | #define fsi_stream_stop(fsi, io)\ | 571 | #define fsi_stream_stop(fsi, io)\ |
572 | fsi_stream_handler_call(io, start_stop, fsi, io, 0) | 572 | fsi_stream_handler_call(io, start_stop, fsi, io, 0) |
573 | 573 | ||
574 | static int fsi_stream_probe(struct fsi_priv *fsi) | 574 | static int fsi_stream_probe(struct fsi_priv *fsi, struct device *dev) |
575 | { | 575 | { |
576 | struct fsi_stream *io; | 576 | struct fsi_stream *io; |
577 | int ret1, ret2; | 577 | int ret1, ret2; |
578 | 578 | ||
579 | io = &fsi->playback; | 579 | io = &fsi->playback; |
580 | ret1 = fsi_stream_handler_call(io, probe, fsi, io); | 580 | ret1 = fsi_stream_handler_call(io, probe, fsi, io, dev); |
581 | 581 | ||
582 | io = &fsi->capture; | 582 | io = &fsi->capture; |
583 | ret2 = fsi_stream_handler_call(io, probe, fsi, io); | 583 | ret2 = fsi_stream_handler_call(io, probe, fsi, io, dev); |
584 | 584 | ||
585 | if (ret1 < 0) | 585 | if (ret1 < 0) |
586 | return ret1; | 586 | return ret1; |
@@ -1089,13 +1089,10 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1089 | { | 1089 | { |
1090 | struct fsi_stream *io = (struct fsi_stream *)data; | 1090 | struct fsi_stream *io = (struct fsi_stream *)data; |
1091 | struct fsi_priv *fsi = fsi_stream_to_priv(io); | 1091 | struct fsi_priv *fsi = fsi_stream_to_priv(io); |
1092 | struct dma_chan *chan; | ||
1093 | struct snd_soc_dai *dai; | 1092 | struct snd_soc_dai *dai; |
1094 | struct dma_async_tx_descriptor *desc; | 1093 | struct dma_async_tx_descriptor *desc; |
1095 | struct scatterlist sg; | ||
1096 | struct snd_pcm_runtime *runtime; | 1094 | struct snd_pcm_runtime *runtime; |
1097 | enum dma_data_direction dir; | 1095 | enum dma_data_direction dir; |
1098 | dma_cookie_t cookie; | ||
1099 | int is_play = fsi_stream_is_play(fsi, io); | 1096 | int is_play = fsi_stream_is_play(fsi, io); |
1100 | int len; | 1097 | int len; |
1101 | dma_addr_t buf; | 1098 | dma_addr_t buf; |
@@ -1104,7 +1101,6 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1104 | return; | 1101 | return; |
1105 | 1102 | ||
1106 | dai = fsi_get_dai(io->substream); | 1103 | dai = fsi_get_dai(io->substream); |
1107 | chan = io->chan; | ||
1108 | runtime = io->substream->runtime; | 1104 | runtime = io->substream->runtime; |
1109 | dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | 1105 | dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; |
1110 | len = samples_to_bytes(runtime, io->period_samples); | 1106 | len = samples_to_bytes(runtime, io->period_samples); |
@@ -1112,14 +1108,8 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1112 | 1108 | ||
1113 | dma_sync_single_for_device(dai->dev, buf, len, dir); | 1109 | dma_sync_single_for_device(dai->dev, buf, len, dir); |
1114 | 1110 | ||
1115 | sg_init_table(&sg, 1); | 1111 | desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, |
1116 | sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), | 1112 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
1117 | len , offset_in_page(buf)); | ||
1118 | sg_dma_address(&sg) = buf; | ||
1119 | sg_dma_len(&sg) = len; | ||
1120 | |||
1121 | desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, | ||
1122 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1123 | if (!desc) { | 1113 | if (!desc) { |
1124 | dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); | 1114 | dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); |
1125 | return; | 1115 | return; |
@@ -1128,13 +1118,12 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1128 | desc->callback = fsi_dma_complete; | 1118 | desc->callback = fsi_dma_complete; |
1129 | desc->callback_param = io; | 1119 | desc->callback_param = io; |
1130 | 1120 | ||
1131 | cookie = desc->tx_submit(desc); | 1121 | if (dmaengine_submit(desc) < 0) { |
1132 | if (cookie < 0) { | ||
1133 | dev_err(dai->dev, "tx_submit() fail\n"); | 1122 | dev_err(dai->dev, "tx_submit() fail\n"); |
1134 | return; | 1123 | return; |
1135 | } | 1124 | } |
1136 | 1125 | ||
1137 | dma_async_issue_pending(chan); | 1126 | dma_async_issue_pending(io->chan); |
1138 | 1127 | ||
1139 | /* | 1128 | /* |
1140 | * FIXME | 1129 | * FIXME |
@@ -1184,7 +1173,7 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, | |||
1184 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | 1173 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); |
1185 | } | 1174 | } |
1186 | 1175 | ||
1187 | static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) | 1176 | static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) |
1188 | { | 1177 | { |
1189 | dma_cap_mask_t mask; | 1178 | dma_cap_mask_t mask; |
1190 | 1179 | ||
@@ -1192,8 +1181,19 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) | |||
1192 | dma_cap_set(DMA_SLAVE, mask); | 1181 | dma_cap_set(DMA_SLAVE, mask); |
1193 | 1182 | ||
1194 | io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); | 1183 | io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); |
1195 | if (!io->chan) | 1184 | if (!io->chan) { |
1196 | return -EIO; | 1185 | |
1186 | /* switch to PIO handler */ | ||
1187 | if (fsi_stream_is_play(fsi, io)) | ||
1188 | fsi->playback.handler = &fsi_pio_push_handler; | ||
1189 | else | ||
1190 | fsi->capture.handler = &fsi_pio_pop_handler; | ||
1191 | |||
1192 | dev_info(dev, "switch handler (dma => pio)\n"); | ||
1193 | |||
1194 | /* probe again */ | ||
1195 | return fsi_stream_probe(fsi, dev); | ||
1196 | } | ||
1197 | 1197 | ||
1198 | tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); | 1198 | tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); |
1199 | 1199 | ||
@@ -1683,7 +1683,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1683 | master->fsia.master = master; | 1683 | master->fsia.master = master; |
1684 | master->fsia.info = &info->port_a; | 1684 | master->fsia.info = &info->port_a; |
1685 | fsi_handler_init(&master->fsia); | 1685 | fsi_handler_init(&master->fsia); |
1686 | ret = fsi_stream_probe(&master->fsia); | 1686 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); |
1687 | if (ret < 0) { | 1687 | if (ret < 0) { |
1688 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 1688 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
1689 | goto exit_iounmap; | 1689 | goto exit_iounmap; |
@@ -1694,7 +1694,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1694 | master->fsib.master = master; | 1694 | master->fsib.master = master; |
1695 | master->fsib.info = &info->port_b; | 1695 | master->fsib.info = &info->port_b; |
1696 | fsi_handler_init(&master->fsib); | 1696 | fsi_handler_init(&master->fsib); |
1697 | ret = fsi_stream_probe(&master->fsib); | 1697 | ret = fsi_stream_probe(&master->fsib, &pdev->dev); |
1698 | if (ret < 0) { | 1698 | if (ret < 0) { |
1699 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | 1699 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); |
1700 | goto exit_fsia; | 1700 | goto exit_fsia; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b37ee8077ed1..3d803f3cd272 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -812,13 +812,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
812 | 812 | ||
813 | /* Find CPU DAI from registered DAIs*/ | 813 | /* Find CPU DAI from registered DAIs*/ |
814 | list_for_each_entry(cpu_dai, &dai_list, list) { | 814 | list_for_each_entry(cpu_dai, &dai_list, list) { |
815 | if (dai_link->cpu_dai_of_node) { | 815 | if (dai_link->cpu_of_node && |
816 | if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) | 816 | (cpu_dai->dev->of_node != dai_link->cpu_of_node)) |
817 | continue; | 817 | continue; |
818 | } else { | 818 | if (dai_link->cpu_name && |
819 | if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) | 819 | strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name)) |
820 | continue; | 820 | continue; |
821 | } | 821 | if (dai_link->cpu_dai_name && |
822 | strcmp(cpu_dai->name, dai_link->cpu_dai_name)) | ||
823 | continue; | ||
822 | 824 | ||
823 | rtd->cpu_dai = cpu_dai; | 825 | rtd->cpu_dai = cpu_dai; |
824 | } | 826 | } |
@@ -2790,6 +2792,104 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, | |||
2790 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); | 2792 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); |
2791 | 2793 | ||
2792 | /** | 2794 | /** |
2795 | * snd_soc_info_volsw_range - single mixer info callback with range. | ||
2796 | * @kcontrol: mixer control | ||
2797 | * @uinfo: control element information | ||
2798 | * | ||
2799 | * Callback to provide information, within a range, about a single | ||
2800 | * mixer control. | ||
2801 | * | ||
2802 | * returns 0 for success. | ||
2803 | */ | ||
2804 | int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, | ||
2805 | struct snd_ctl_elem_info *uinfo) | ||
2806 | { | ||
2807 | struct soc_mixer_control *mc = | ||
2808 | (struct soc_mixer_control *)kcontrol->private_value; | ||
2809 | int platform_max; | ||
2810 | int min = mc->min; | ||
2811 | |||
2812 | if (!mc->platform_max) | ||
2813 | mc->platform_max = mc->max; | ||
2814 | platform_max = mc->platform_max; | ||
2815 | |||
2816 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
2817 | uinfo->count = 1; | ||
2818 | uinfo->value.integer.min = 0; | ||
2819 | uinfo->value.integer.max = platform_max - min; | ||
2820 | |||
2821 | return 0; | ||
2822 | } | ||
2823 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); | ||
2824 | |||
2825 | /** | ||
2826 | * snd_soc_put_volsw_range - single mixer put value callback with range. | ||
2827 | * @kcontrol: mixer control | ||
2828 | * @ucontrol: control element information | ||
2829 | * | ||
2830 | * Callback to set the value, within a range, for a single mixer control. | ||
2831 | * | ||
2832 | * Returns 0 for success. | ||
2833 | */ | ||
2834 | int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | ||
2835 | struct snd_ctl_elem_value *ucontrol) | ||
2836 | { | ||
2837 | struct soc_mixer_control *mc = | ||
2838 | (struct soc_mixer_control *)kcontrol->private_value; | ||
2839 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2840 | unsigned int reg = mc->reg; | ||
2841 | unsigned int shift = mc->shift; | ||
2842 | int min = mc->min; | ||
2843 | int max = mc->max; | ||
2844 | unsigned int mask = (1 << fls(max)) - 1; | ||
2845 | unsigned int invert = mc->invert; | ||
2846 | unsigned int val, val_mask; | ||
2847 | |||
2848 | val = ((ucontrol->value.integer.value[0] + min) & mask); | ||
2849 | if (invert) | ||
2850 | val = max - val; | ||
2851 | val_mask = mask << shift; | ||
2852 | val = val << shift; | ||
2853 | |||
2854 | return snd_soc_update_bits_locked(codec, reg, val_mask, val); | ||
2855 | } | ||
2856 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); | ||
2857 | |||
2858 | /** | ||
2859 | * snd_soc_get_volsw_range - single mixer get callback with range | ||
2860 | * @kcontrol: mixer control | ||
2861 | * @ucontrol: control element information | ||
2862 | * | ||
2863 | * Callback to get the value, within a range, of a single mixer control. | ||
2864 | * | ||
2865 | * Returns 0 for success. | ||
2866 | */ | ||
2867 | int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | ||
2868 | struct snd_ctl_elem_value *ucontrol) | ||
2869 | { | ||
2870 | struct soc_mixer_control *mc = | ||
2871 | (struct soc_mixer_control *)kcontrol->private_value; | ||
2872 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2873 | unsigned int reg = mc->reg; | ||
2874 | unsigned int shift = mc->shift; | ||
2875 | int min = mc->min; | ||
2876 | int max = mc->max; | ||
2877 | unsigned int mask = (1 << fls(max)) - 1; | ||
2878 | unsigned int invert = mc->invert; | ||
2879 | |||
2880 | ucontrol->value.integer.value[0] = | ||
2881 | (snd_soc_read(codec, reg) >> shift) & mask; | ||
2882 | if (invert) | ||
2883 | ucontrol->value.integer.value[0] = | ||
2884 | max - ucontrol->value.integer.value[0]; | ||
2885 | ucontrol->value.integer.value[0] = | ||
2886 | ucontrol->value.integer.value[0] - min; | ||
2887 | |||
2888 | return 0; | ||
2889 | } | ||
2890 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); | ||
2891 | |||
2892 | /** | ||
2793 | * snd_soc_limit_volume - Set new limit to an existing volume control. | 2893 | * snd_soc_limit_volume - Set new limit to an existing volume control. |
2794 | * | 2894 | * |
2795 | * @codec: where to look for the control | 2895 | * @codec: where to look for the control |
@@ -3346,6 +3446,12 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3346 | link->name); | 3446 | link->name); |
3347 | return -EINVAL; | 3447 | return -EINVAL; |
3348 | } | 3448 | } |
3449 | /* Codec DAI name must be specified */ | ||
3450 | if (!link->codec_dai_name) { | ||
3451 | dev_err(card->dev, "codec_dai_name not set for %s\n", | ||
3452 | link->name); | ||
3453 | return -EINVAL; | ||
3454 | } | ||
3349 | 3455 | ||
3350 | /* | 3456 | /* |
3351 | * Platform may be specified by either name or OF node, but | 3457 | * Platform may be specified by either name or OF node, but |
@@ -3358,12 +3464,24 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3358 | } | 3464 | } |
3359 | 3465 | ||
3360 | /* | 3466 | /* |
3361 | * CPU DAI must be specified by 1 of name or OF node, | 3467 | * CPU device may be specified by either name or OF node, but |
3362 | * not both or neither. | 3468 | * can be left unspecified, and will be matched based on DAI |
3469 | * name alone.. | ||
3470 | */ | ||
3471 | if (link->cpu_name && link->cpu_of_node) { | ||
3472 | dev_err(card->dev, | ||
3473 | "Neither/both cpu name/of_node are set for %s\n", | ||
3474 | link->name); | ||
3475 | return -EINVAL; | ||
3476 | } | ||
3477 | /* | ||
3478 | * At least one of CPU DAI name or CPU device name/node must be | ||
3479 | * specified | ||
3363 | */ | 3480 | */ |
3364 | if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { | 3481 | if (!link->cpu_dai_name && |
3482 | !(link->cpu_name || link->cpu_of_node)) { | ||
3365 | dev_err(card->dev, | 3483 | dev_err(card->dev, |
3366 | "Neither/both cpu_dai name/of_node are set for %s\n", | 3484 | "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", |
3367 | link->name); | 3485 | link->name); |
3368 | return -EINVAL; | 3486 | return -EINVAL; |
3369 | } | 3487 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 90ee77d2409d..7365fed1ba74 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/debugfs.h> | 35 | #include <linux/debugfs.h> |
36 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
38 | #include <linux/clk.h> | ||
38 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
39 | #include <sound/core.h> | 40 | #include <sound/core.h> |
40 | #include <sound/pcm.h> | 41 | #include <sound/pcm.h> |
@@ -51,6 +52,7 @@ static int dapm_up_seq[] = { | |||
51 | [snd_soc_dapm_pre] = 0, | 52 | [snd_soc_dapm_pre] = 0, |
52 | [snd_soc_dapm_supply] = 1, | 53 | [snd_soc_dapm_supply] = 1, |
53 | [snd_soc_dapm_regulator_supply] = 1, | 54 | [snd_soc_dapm_regulator_supply] = 1, |
55 | [snd_soc_dapm_clock_supply] = 1, | ||
54 | [snd_soc_dapm_micbias] = 2, | 56 | [snd_soc_dapm_micbias] = 2, |
55 | [snd_soc_dapm_dai_link] = 2, | 57 | [snd_soc_dapm_dai_link] = 2, |
56 | [snd_soc_dapm_dai] = 3, | 58 | [snd_soc_dapm_dai] = 3, |
@@ -92,6 +94,7 @@ static int dapm_down_seq[] = { | |||
92 | [snd_soc_dapm_aif_out] = 10, | 94 | [snd_soc_dapm_aif_out] = 10, |
93 | [snd_soc_dapm_dai] = 10, | 95 | [snd_soc_dapm_dai] = 10, |
94 | [snd_soc_dapm_dai_link] = 11, | 96 | [snd_soc_dapm_dai_link] = 11, |
97 | [snd_soc_dapm_clock_supply] = 12, | ||
95 | [snd_soc_dapm_regulator_supply] = 12, | 98 | [snd_soc_dapm_regulator_supply] = 12, |
96 | [snd_soc_dapm_supply] = 12, | 99 | [snd_soc_dapm_supply] = 12, |
97 | [snd_soc_dapm_post] = 13, | 100 | [snd_soc_dapm_post] = 13, |
@@ -391,6 +394,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
391 | case snd_soc_dapm_vmid: | 394 | case snd_soc_dapm_vmid: |
392 | case snd_soc_dapm_supply: | 395 | case snd_soc_dapm_supply: |
393 | case snd_soc_dapm_regulator_supply: | 396 | case snd_soc_dapm_regulator_supply: |
397 | case snd_soc_dapm_clock_supply: | ||
394 | case snd_soc_dapm_aif_in: | 398 | case snd_soc_dapm_aif_in: |
395 | case snd_soc_dapm_aif_out: | 399 | case snd_soc_dapm_aif_out: |
396 | case snd_soc_dapm_dai: | 400 | case snd_soc_dapm_dai: |
@@ -764,6 +768,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, | |||
764 | switch (widget->id) { | 768 | switch (widget->id) { |
765 | case snd_soc_dapm_supply: | 769 | case snd_soc_dapm_supply: |
766 | case snd_soc_dapm_regulator_supply: | 770 | case snd_soc_dapm_regulator_supply: |
771 | case snd_soc_dapm_clock_supply: | ||
767 | return 0; | 772 | return 0; |
768 | default: | 773 | default: |
769 | break; | 774 | break; |
@@ -850,6 +855,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, | |||
850 | switch (widget->id) { | 855 | switch (widget->id) { |
851 | case snd_soc_dapm_supply: | 856 | case snd_soc_dapm_supply: |
852 | case snd_soc_dapm_regulator_supply: | 857 | case snd_soc_dapm_regulator_supply: |
858 | case snd_soc_dapm_clock_supply: | ||
853 | return 0; | 859 | return 0; |
854 | default: | 860 | default: |
855 | break; | 861 | break; |
@@ -996,6 +1002,26 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
996 | } | 1002 | } |
997 | EXPORT_SYMBOL_GPL(dapm_regulator_event); | 1003 | EXPORT_SYMBOL_GPL(dapm_regulator_event); |
998 | 1004 | ||
1005 | /* | ||
1006 | * Handler for clock supply widget. | ||
1007 | */ | ||
1008 | int dapm_clock_event(struct snd_soc_dapm_widget *w, | ||
1009 | struct snd_kcontrol *kcontrol, int event) | ||
1010 | { | ||
1011 | if (!w->clk) | ||
1012 | return -EIO; | ||
1013 | |||
1014 | #ifdef CONFIG_HAVE_CLK | ||
1015 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
1016 | return clk_enable(w->clk); | ||
1017 | } else { | ||
1018 | clk_disable(w->clk); | ||
1019 | return 0; | ||
1020 | } | ||
1021 | #endif | ||
1022 | } | ||
1023 | EXPORT_SYMBOL_GPL(dapm_clock_event); | ||
1024 | |||
999 | static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) | 1025 | static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) |
1000 | { | 1026 | { |
1001 | if (w->power_checked) | 1027 | if (w->power_checked) |
@@ -1487,6 +1513,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, | |||
1487 | switch (w->id) { | 1513 | switch (w->id) { |
1488 | case snd_soc_dapm_supply: | 1514 | case snd_soc_dapm_supply: |
1489 | case snd_soc_dapm_regulator_supply: | 1515 | case snd_soc_dapm_regulator_supply: |
1516 | case snd_soc_dapm_clock_supply: | ||
1490 | /* Supplies can't affect their outputs, only their inputs */ | 1517 | /* Supplies can't affect their outputs, only their inputs */ |
1491 | break; | 1518 | break; |
1492 | default: | 1519 | default: |
@@ -1587,6 +1614,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
1587 | break; | 1614 | break; |
1588 | case snd_soc_dapm_supply: | 1615 | case snd_soc_dapm_supply: |
1589 | case snd_soc_dapm_regulator_supply: | 1616 | case snd_soc_dapm_regulator_supply: |
1617 | case snd_soc_dapm_clock_supply: | ||
1590 | case snd_soc_dapm_micbias: | 1618 | case snd_soc_dapm_micbias: |
1591 | if (d->target_bias_level < SND_SOC_BIAS_STANDBY) | 1619 | if (d->target_bias_level < SND_SOC_BIAS_STANDBY) |
1592 | d->target_bias_level = SND_SOC_BIAS_STANDBY; | 1620 | d->target_bias_level = SND_SOC_BIAS_STANDBY; |
@@ -1941,6 +1969,7 @@ static ssize_t dapm_widget_show(struct device *dev, | |||
1941 | case snd_soc_dapm_mixer_named_ctl: | 1969 | case snd_soc_dapm_mixer_named_ctl: |
1942 | case snd_soc_dapm_supply: | 1970 | case snd_soc_dapm_supply: |
1943 | case snd_soc_dapm_regulator_supply: | 1971 | case snd_soc_dapm_regulator_supply: |
1972 | case snd_soc_dapm_clock_supply: | ||
1944 | if (w->name) | 1973 | if (w->name) |
1945 | count += sprintf(buf + count, "%s: %s\n", | 1974 | count += sprintf(buf + count, "%s: %s\n", |
1946 | w->name, w->power ? "On":"Off"); | 1975 | w->name, w->power ? "On":"Off"); |
@@ -2187,6 +2216,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2187 | case snd_soc_dapm_post: | 2216 | case snd_soc_dapm_post: |
2188 | case snd_soc_dapm_supply: | 2217 | case snd_soc_dapm_supply: |
2189 | case snd_soc_dapm_regulator_supply: | 2218 | case snd_soc_dapm_regulator_supply: |
2219 | case snd_soc_dapm_clock_supply: | ||
2190 | case snd_soc_dapm_aif_in: | 2220 | case snd_soc_dapm_aif_in: |
2191 | case snd_soc_dapm_aif_out: | 2221 | case snd_soc_dapm_aif_out: |
2192 | case snd_soc_dapm_dai: | 2222 | case snd_soc_dapm_dai: |
@@ -2873,6 +2903,19 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
2873 | return NULL; | 2903 | return NULL; |
2874 | } | 2904 | } |
2875 | break; | 2905 | break; |
2906 | case snd_soc_dapm_clock_supply: | ||
2907 | #ifdef CONFIG_CLKDEV_LOOKUP | ||
2908 | w->clk = devm_clk_get(dapm->dev, w->name); | ||
2909 | if (IS_ERR(w->clk)) { | ||
2910 | ret = PTR_ERR(w->clk); | ||
2911 | dev_err(dapm->dev, "Failed to request %s: %d\n", | ||
2912 | w->name, ret); | ||
2913 | return NULL; | ||
2914 | } | ||
2915 | #else | ||
2916 | return NULL; | ||
2917 | #endif | ||
2918 | break; | ||
2876 | default: | 2919 | default: |
2877 | break; | 2920 | break; |
2878 | } | 2921 | } |
@@ -2924,6 +2967,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
2924 | break; | 2967 | break; |
2925 | case snd_soc_dapm_supply: | 2968 | case snd_soc_dapm_supply: |
2926 | case snd_soc_dapm_regulator_supply: | 2969 | case snd_soc_dapm_regulator_supply: |
2970 | case snd_soc_dapm_clock_supply: | ||
2927 | w->power_check = dapm_supply_check_power; | 2971 | w->power_check = dapm_supply_check_power; |
2928 | break; | 2972 | break; |
2929 | case snd_soc_dapm_dai: | 2973 | case snd_soc_dapm_dai: |
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 4d8dc6a27d4d..44d0174b4d97 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
@@ -142,6 +142,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
142 | case SND_SOC_REGMAP: | 142 | case SND_SOC_REGMAP: |
143 | /* Device has made its own regmap arrangements */ | 143 | /* Device has made its own regmap arrangements */ |
144 | codec->using_regmap = true; | 144 | codec->using_regmap = true; |
145 | if (!codec->control_data) | ||
146 | codec->control_data = dev_get_regmap(codec->dev, NULL); | ||
145 | 147 | ||
146 | ret = regmap_get_val_bytes(codec->control_data); | 148 | ret = regmap_get_val_bytes(codec->control_data); |
147 | /* Errors are legitimate for non-integer byte multiples */ | 149 | /* Errors are legitimate for non-integer byte multiples */ |
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 0c7af63d444b..c5fc6b1404f6 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -46,18 +46,6 @@ | |||
46 | 46 | ||
47 | #define DRV_NAME "tegra20-i2s" | 47 | #define DRV_NAME "tegra20-i2s" |
48 | 48 | ||
49 | static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val) | ||
50 | { | ||
51 | regmap_write(i2s->regmap, reg, val); | ||
52 | } | ||
53 | |||
54 | static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg) | ||
55 | { | ||
56 | u32 val; | ||
57 | regmap_read(i2s->regmap, reg, &val); | ||
58 | return val; | ||
59 | } | ||
60 | |||
61 | static int tegra20_i2s_runtime_suspend(struct device *dev) | 49 | static int tegra20_i2s_runtime_suspend(struct device *dev) |
62 | { | 50 | { |
63 | struct tegra20_i2s *i2s = dev_get_drvdata(dev); | 51 | struct tegra20_i2s *i2s = dev_get_drvdata(dev); |
@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
85 | unsigned int fmt) | 73 | unsigned int fmt) |
86 | { | 74 | { |
87 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 75 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
76 | unsigned int mask, val; | ||
88 | 77 | ||
89 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 78 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
90 | case SND_SOC_DAIFMT_NB_NF: | 79 | case SND_SOC_DAIFMT_NB_NF: |
@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
93 | return -EINVAL; | 82 | return -EINVAL; |
94 | } | 83 | } |
95 | 84 | ||
96 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; | 85 | mask = TEGRA20_I2S_CTRL_MASTER_ENABLE; |
97 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 86 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
98 | case SND_SOC_DAIFMT_CBS_CFS: | 87 | case SND_SOC_DAIFMT_CBS_CFS: |
99 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; | 88 | val = TEGRA20_I2S_CTRL_MASTER_ENABLE; |
100 | break; | 89 | break; |
101 | case SND_SOC_DAIFMT_CBM_CFM: | 90 | case SND_SOC_DAIFMT_CBM_CFM: |
102 | break; | 91 | break; |
@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
104 | return -EINVAL; | 93 | return -EINVAL; |
105 | } | 94 | } |
106 | 95 | ||
107 | i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | | 96 | mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | |
108 | TEGRA20_I2S_CTRL_LRCK_MASK); | 97 | TEGRA20_I2S_CTRL_LRCK_MASK; |
109 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 98 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
110 | case SND_SOC_DAIFMT_DSP_A: | 99 | case SND_SOC_DAIFMT_DSP_A: |
111 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; | 100 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; |
112 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 101 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
113 | break; | 102 | break; |
114 | case SND_SOC_DAIFMT_DSP_B: | 103 | case SND_SOC_DAIFMT_DSP_B: |
115 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; | 104 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; |
116 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; | 105 | val |= TEGRA20_I2S_CTRL_LRCK_R_LOW; |
117 | break; | 106 | break; |
118 | case SND_SOC_DAIFMT_I2S: | 107 | case SND_SOC_DAIFMT_I2S: |
119 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; | 108 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; |
120 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 109 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
121 | break; | 110 | break; |
122 | case SND_SOC_DAIFMT_RIGHT_J: | 111 | case SND_SOC_DAIFMT_RIGHT_J: |
123 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; | 112 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; |
124 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 113 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
125 | break; | 114 | break; |
126 | case SND_SOC_DAIFMT_LEFT_J: | 115 | case SND_SOC_DAIFMT_LEFT_J: |
127 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; | 116 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; |
128 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 117 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
129 | break; | 118 | break; |
130 | default: | 119 | default: |
131 | return -EINVAL; | 120 | return -EINVAL; |
132 | } | 121 | } |
133 | 122 | ||
123 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); | ||
124 | |||
134 | return 0; | 125 | return 0; |
135 | } | 126 | } |
136 | 127 | ||
@@ -138,29 +129,34 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, | |||
138 | struct snd_pcm_hw_params *params, | 129 | struct snd_pcm_hw_params *params, |
139 | struct snd_soc_dai *dai) | 130 | struct snd_soc_dai *dai) |
140 | { | 131 | { |
141 | struct device *dev = substream->pcm->card->dev; | 132 | struct device *dev = dai->dev; |
142 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 133 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
143 | u32 reg; | 134 | unsigned int mask, val; |
144 | int ret, sample_size, srate, i2sclock, bitcnt; | 135 | int ret, sample_size, srate, i2sclock, bitcnt; |
145 | 136 | ||
146 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; | 137 | mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK; |
147 | switch (params_format(params)) { | 138 | switch (params_format(params)) { |
148 | case SNDRV_PCM_FORMAT_S16_LE: | 139 | case SNDRV_PCM_FORMAT_S16_LE: |
149 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; | 140 | val = TEGRA20_I2S_CTRL_BIT_SIZE_16; |
150 | sample_size = 16; | 141 | sample_size = 16; |
151 | break; | 142 | break; |
152 | case SNDRV_PCM_FORMAT_S24_LE: | 143 | case SNDRV_PCM_FORMAT_S24_LE: |
153 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; | 144 | val = TEGRA20_I2S_CTRL_BIT_SIZE_24; |
154 | sample_size = 24; | 145 | sample_size = 24; |
155 | break; | 146 | break; |
156 | case SNDRV_PCM_FORMAT_S32_LE: | 147 | case SNDRV_PCM_FORMAT_S32_LE: |
157 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; | 148 | val = TEGRA20_I2S_CTRL_BIT_SIZE_32; |
158 | sample_size = 32; | 149 | sample_size = 32; |
159 | break; | 150 | break; |
160 | default: | 151 | default: |
161 | return -EINVAL; | 152 | return -EINVAL; |
162 | } | 153 | } |
163 | 154 | ||
155 | mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK; | ||
156 | val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; | ||
157 | |||
158 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); | ||
159 | |||
164 | srate = params_rate(params); | 160 | srate = params_rate(params); |
165 | 161 | ||
166 | /* Final "* 2" required by Tegra hardware */ | 162 | /* Final "* 2" required by Tegra hardware */ |
@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, | |||
175 | bitcnt = (i2sclock / (2 * srate)) - 1; | 171 | bitcnt = (i2sclock / (2 * srate)) - 1; |
176 | if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) | 172 | if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) |
177 | return -EINVAL; | 173 | return -EINVAL; |
178 | reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; | 174 | val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; |
179 | 175 | ||
180 | if (i2sclock % (2 * srate)) | 176 | if (i2sclock % (2 * srate)) |
181 | reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; | 177 | val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; |
182 | 178 | ||
183 | tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); | 179 | regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val); |
184 | 180 | ||
185 | tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, | 181 | regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR, |
186 | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | | 182 | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | |
187 | TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); | 183 | TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); |
188 | 184 | ||
189 | return 0; | 185 | return 0; |
190 | } | 186 | } |
191 | 187 | ||
192 | static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) | 188 | static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) |
193 | { | 189 | { |
194 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; | 190 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
195 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 191 | TEGRA20_I2S_CTRL_FIFO1_ENABLE, |
192 | TEGRA20_I2S_CTRL_FIFO1_ENABLE); | ||
196 | } | 193 | } |
197 | 194 | ||
198 | static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) | 195 | static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) |
199 | { | 196 | { |
200 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; | 197 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
201 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 198 | TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0); |
202 | } | 199 | } |
203 | 200 | ||
204 | static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) | 201 | static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) |
205 | { | 202 | { |
206 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; | 203 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
207 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 204 | TEGRA20_I2S_CTRL_FIFO2_ENABLE, |
205 | TEGRA20_I2S_CTRL_FIFO2_ENABLE); | ||
208 | } | 206 | } |
209 | 207 | ||
210 | static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) | 208 | static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) |
211 | { | 209 | { |
212 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; | 210 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
213 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 211 | TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0); |
214 | } | 212 | } |
215 | 213 | ||
216 | static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | 214 | static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
@@ -261,12 +259,14 @@ static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = { | |||
261 | static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { | 259 | static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { |
262 | .probe = tegra20_i2s_probe, | 260 | .probe = tegra20_i2s_probe, |
263 | .playback = { | 261 | .playback = { |
262 | .stream_name = "Playback", | ||
264 | .channels_min = 2, | 263 | .channels_min = 2, |
265 | .channels_max = 2, | 264 | .channels_max = 2, |
266 | .rates = SNDRV_PCM_RATE_8000_96000, | 265 | .rates = SNDRV_PCM_RATE_8000_96000, |
267 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 266 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
268 | }, | 267 | }, |
269 | .capture = { | 268 | .capture = { |
269 | .stream_name = "Capture", | ||
270 | .channels_min = 2, | 270 | .channels_min = 2, |
271 | .channels_max = 2, | 271 | .channels_max = 2, |
272 | .rates = SNDRV_PCM_RATE_8000_96000, | 272 | .rates = SNDRV_PCM_RATE_8000_96000, |
@@ -412,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
412 | i2s->playback_dma_data.width = 32; | 412 | i2s->playback_dma_data.width = 32; |
413 | i2s->playback_dma_data.req_sel = dma_ch; | 413 | i2s->playback_dma_data.req_sel = dma_ch; |
414 | 414 | ||
415 | i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; | ||
416 | |||
417 | pm_runtime_enable(&pdev->dev); | 415 | pm_runtime_enable(&pdev->dev); |
418 | if (!pm_runtime_enabled(&pdev->dev)) { | 416 | if (!pm_runtime_enabled(&pdev->dev)) { |
419 | ret = tegra20_i2s_runtime_resume(&pdev->dev); | 417 | ret = tegra20_i2s_runtime_resume(&pdev->dev); |
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h index a57efc6a597e..c27069d24d77 100644 --- a/sound/soc/tegra/tegra20_i2s.h +++ b/sound/soc/tegra/tegra20_i2s.h | |||
@@ -158,7 +158,6 @@ struct tegra20_i2s { | |||
158 | struct tegra_pcm_dma_params capture_dma_data; | 158 | struct tegra_pcm_dma_params capture_dma_data; |
159 | struct tegra_pcm_dma_params playback_dma_data; | 159 | struct tegra_pcm_dma_params playback_dma_data; |
160 | struct regmap *regmap; | 160 | struct regmap *regmap; |
161 | u32 reg_ctrl; | ||
162 | }; | 161 | }; |
163 | 162 | ||
164 | #endif | 163 | #endif |
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index f9b57418bd08..5c33c618929d 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c | |||
@@ -37,19 +37,6 @@ | |||
37 | 37 | ||
38 | #define DRV_NAME "tegra20-spdif" | 38 | #define DRV_NAME "tegra20-spdif" |
39 | 39 | ||
40 | static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg, | ||
41 | u32 val) | ||
42 | { | ||
43 | regmap_write(spdif->regmap, reg, val); | ||
44 | } | ||
45 | |||
46 | static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg) | ||
47 | { | ||
48 | u32 val; | ||
49 | regmap_read(spdif->regmap, reg, &val); | ||
50 | return val; | ||
51 | } | ||
52 | |||
53 | static int tegra20_spdif_runtime_suspend(struct device *dev) | 40 | static int tegra20_spdif_runtime_suspend(struct device *dev) |
54 | { | 41 | { |
55 | struct tegra20_spdif *spdif = dev_get_drvdata(dev); | 42 | struct tegra20_spdif *spdif = dev_get_drvdata(dev); |
@@ -77,21 +64,24 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, | |||
77 | struct snd_pcm_hw_params *params, | 64 | struct snd_pcm_hw_params *params, |
78 | struct snd_soc_dai *dai) | 65 | struct snd_soc_dai *dai) |
79 | { | 66 | { |
80 | struct device *dev = substream->pcm->card->dev; | 67 | struct device *dev = dai->dev; |
81 | struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); | 68 | struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); |
69 | unsigned int mask, val; | ||
82 | int ret, spdifclock; | 70 | int ret, spdifclock; |
83 | 71 | ||
84 | spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; | 72 | mask = TEGRA20_SPDIF_CTRL_PACK | |
85 | spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; | 73 | TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; |
86 | switch (params_format(params)) { | 74 | switch (params_format(params)) { |
87 | case SNDRV_PCM_FORMAT_S16_LE: | 75 | case SNDRV_PCM_FORMAT_S16_LE: |
88 | spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; | 76 | val = TEGRA20_SPDIF_CTRL_PACK | |
89 | spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; | 77 | TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; |
90 | break; | 78 | break; |
91 | default: | 79 | default: |
92 | return -EINVAL; | 80 | return -EINVAL; |
93 | } | 81 | } |
94 | 82 | ||
83 | regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val); | ||
84 | |||
95 | switch (params_rate(params)) { | 85 | switch (params_rate(params)) { |
96 | case 32000: | 86 | case 32000: |
97 | spdifclock = 4096000; | 87 | spdifclock = 4096000; |
@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, | |||
129 | 119 | ||
130 | static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) | 120 | static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) |
131 | { | 121 | { |
132 | spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; | 122 | regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, |
133 | tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); | 123 | TEGRA20_SPDIF_CTRL_TX_EN, |
124 | TEGRA20_SPDIF_CTRL_TX_EN); | ||
134 | } | 125 | } |
135 | 126 | ||
136 | static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) | 127 | static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) |
137 | { | 128 | { |
138 | spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; | 129 | regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, |
139 | tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); | 130 | TEGRA20_SPDIF_CTRL_TX_EN, 0); |
140 | } | 131 | } |
141 | 132 | ||
142 | static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, | 133 | static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, |
@@ -181,6 +172,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { | |||
181 | .name = DRV_NAME, | 172 | .name = DRV_NAME, |
182 | .probe = tegra20_spdif_probe, | 173 | .probe = tegra20_spdif_probe, |
183 | .playback = { | 174 | .playback = { |
175 | .stream_name = "Playback", | ||
184 | .channels_min = 2, | 176 | .channels_min = 2, |
185 | .channels_max = 2, | 177 | .channels_max = 2, |
186 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | | 178 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | |
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h index ed756527efea..b48d699fd583 100644 --- a/sound/soc/tegra/tegra20_spdif.h +++ b/sound/soc/tegra/tegra20_spdif.h | |||
@@ -465,7 +465,6 @@ struct tegra20_spdif { | |||
465 | struct tegra_pcm_dma_params capture_dma_data; | 465 | struct tegra_pcm_dma_params capture_dma_data; |
466 | struct tegra_pcm_dma_params playback_dma_data; | 466 | struct tegra_pcm_dma_params playback_dma_data; |
467 | struct regmap *regmap; | 467 | struct regmap *regmap; |
468 | u32 reg_ctrl; | ||
469 | }; | 468 | }; |
470 | 469 | ||
471 | #endif | 470 | #endif |
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 8596032985dc..b68e27a14608 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c | |||
@@ -44,18 +44,6 @@ | |||
44 | 44 | ||
45 | #define DRV_NAME "tegra30-i2s" | 45 | #define DRV_NAME "tegra30-i2s" |
46 | 46 | ||
47 | static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val) | ||
48 | { | ||
49 | regmap_write(i2s->regmap, reg, val); | ||
50 | } | ||
51 | |||
52 | static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg) | ||
53 | { | ||
54 | u32 val; | ||
55 | regmap_read(i2s->regmap, reg, &val); | ||
56 | return val; | ||
57 | } | ||
58 | |||
59 | static int tegra30_i2s_runtime_suspend(struct device *dev) | 47 | static int tegra30_i2s_runtime_suspend(struct device *dev) |
60 | { | 48 | { |
61 | struct tegra30_i2s *i2s = dev_get_drvdata(dev); | 49 | struct tegra30_i2s *i2s = dev_get_drvdata(dev); |
@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, | |||
128 | unsigned int fmt) | 116 | unsigned int fmt) |
129 | { | 117 | { |
130 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 118 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
119 | unsigned int mask, val; | ||
131 | 120 | ||
132 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 121 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
133 | case SND_SOC_DAIFMT_NB_NF: | 122 | case SND_SOC_DAIFMT_NB_NF: |
@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, | |||
136 | return -EINVAL; | 125 | return -EINVAL; |
137 | } | 126 | } |
138 | 127 | ||
139 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; | 128 | mask = TEGRA30_I2S_CTRL_MASTER_ENABLE; |
140 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 129 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
141 | case SND_SOC_DAIFMT_CBS_CFS: | 130 | case SND_SOC_DAIFMT_CBS_CFS: |
142 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; | 131 | val = TEGRA30_I2S_CTRL_MASTER_ENABLE; |
143 | break; | 132 | break; |
144 | case SND_SOC_DAIFMT_CBM_CFM: | 133 | case SND_SOC_DAIFMT_CBM_CFM: |
145 | break; | 134 | break; |
@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, | |||
147 | return -EINVAL; | 136 | return -EINVAL; |
148 | } | 137 | } |
149 | 138 | ||
150 | i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | | 139 | mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | |
151 | TEGRA30_I2S_CTRL_LRCK_MASK); | 140 | TEGRA30_I2S_CTRL_LRCK_MASK; |
152 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 141 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
153 | case SND_SOC_DAIFMT_DSP_A: | 142 | case SND_SOC_DAIFMT_DSP_A: |
154 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; | 143 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; |
155 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 144 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
156 | break; | 145 | break; |
157 | case SND_SOC_DAIFMT_DSP_B: | 146 | case SND_SOC_DAIFMT_DSP_B: |
158 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; | 147 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; |
159 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; | 148 | val |= TEGRA30_I2S_CTRL_LRCK_R_LOW; |
160 | break; | 149 | break; |
161 | case SND_SOC_DAIFMT_I2S: | 150 | case SND_SOC_DAIFMT_I2S: |
162 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; | 151 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; |
163 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 152 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
164 | break; | 153 | break; |
165 | case SND_SOC_DAIFMT_RIGHT_J: | 154 | case SND_SOC_DAIFMT_RIGHT_J: |
166 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; | 155 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; |
167 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 156 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
168 | break; | 157 | break; |
169 | case SND_SOC_DAIFMT_LEFT_J: | 158 | case SND_SOC_DAIFMT_LEFT_J: |
170 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; | 159 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; |
171 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 160 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
172 | break; | 161 | break; |
173 | default: | 162 | default: |
174 | return -EINVAL; | 163 | return -EINVAL; |
175 | } | 164 | } |
176 | 165 | ||
166 | pm_runtime_get_sync(dai->dev); | ||
167 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); | ||
168 | pm_runtime_put(dai->dev); | ||
169 | |||
177 | return 0; | 170 | return 0; |
178 | } | 171 | } |
179 | 172 | ||
@@ -181,24 +174,26 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
181 | struct snd_pcm_hw_params *params, | 174 | struct snd_pcm_hw_params *params, |
182 | struct snd_soc_dai *dai) | 175 | struct snd_soc_dai *dai) |
183 | { | 176 | { |
184 | struct device *dev = substream->pcm->card->dev; | 177 | struct device *dev = dai->dev; |
185 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 178 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
186 | u32 val; | 179 | unsigned int mask, val, reg; |
187 | int ret, sample_size, srate, i2sclock, bitcnt; | 180 | int ret, sample_size, srate, i2sclock, bitcnt; |
188 | 181 | ||
189 | if (params_channels(params) != 2) | 182 | if (params_channels(params) != 2) |
190 | return -EINVAL; | 183 | return -EINVAL; |
191 | 184 | ||
192 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; | 185 | mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK; |
193 | switch (params_format(params)) { | 186 | switch (params_format(params)) { |
194 | case SNDRV_PCM_FORMAT_S16_LE: | 187 | case SNDRV_PCM_FORMAT_S16_LE: |
195 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; | 188 | val = TEGRA30_I2S_CTRL_BIT_SIZE_16; |
196 | sample_size = 16; | 189 | sample_size = 16; |
197 | break; | 190 | break; |
198 | default: | 191 | default: |
199 | return -EINVAL; | 192 | return -EINVAL; |
200 | } | 193 | } |
201 | 194 | ||
195 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); | ||
196 | |||
202 | srate = params_rate(params); | 197 | srate = params_rate(params); |
203 | 198 | ||
204 | /* Final "* 2" required by Tegra hardware */ | 199 | /* Final "* 2" required by Tegra hardware */ |
@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
219 | if (i2sclock % (2 * srate)) | 214 | if (i2sclock % (2 * srate)) |
220 | val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; | 215 | val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; |
221 | 216 | ||
222 | tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); | 217 | regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val); |
223 | 218 | ||
224 | val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | | 219 | val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | |
225 | (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | | 220 | (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | |
@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
229 | 224 | ||
230 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 225 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
231 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; | 226 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; |
232 | tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); | 227 | reg = TEGRA30_I2S_CIF_RX_CTRL; |
233 | } else { | 228 | } else { |
234 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; | 229 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; |
235 | tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); | 230 | reg = TEGRA30_I2S_CIF_RX_CTRL; |
236 | } | 231 | } |
237 | 232 | ||
233 | regmap_write(i2s->regmap, reg, val); | ||
234 | |||
238 | val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | | 235 | val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | |
239 | (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); | 236 | (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); |
240 | tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); | 237 | regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val); |
241 | 238 | ||
242 | return 0; | 239 | return 0; |
243 | } | 240 | } |
@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
245 | static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) | 242 | static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) |
246 | { | 243 | { |
247 | tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); | 244 | tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); |
248 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; | 245 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
249 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 246 | TEGRA30_I2S_CTRL_XFER_EN_TX, |
247 | TEGRA30_I2S_CTRL_XFER_EN_TX); | ||
250 | } | 248 | } |
251 | 249 | ||
252 | static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) | 250 | static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) |
253 | { | 251 | { |
254 | tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); | 252 | tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); |
255 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; | 253 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
256 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 254 | TEGRA30_I2S_CTRL_XFER_EN_TX, 0); |
257 | } | 255 | } |
258 | 256 | ||
259 | static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) | 257 | static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) |
260 | { | 258 | { |
261 | tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); | 259 | tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); |
262 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; | 260 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
263 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 261 | TEGRA30_I2S_CTRL_XFER_EN_RX, |
262 | TEGRA30_I2S_CTRL_XFER_EN_RX); | ||
264 | } | 263 | } |
265 | 264 | ||
266 | static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) | 265 | static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) |
267 | { | 266 | { |
268 | tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); | 267 | tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); |
269 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; | 268 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
270 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 269 | TEGRA30_I2S_CTRL_XFER_EN_RX, 0); |
271 | } | 270 | } |
272 | 271 | ||
273 | static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | 272 | static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
@@ -320,12 +319,14 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { | |||
320 | static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { | 319 | static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { |
321 | .probe = tegra30_i2s_probe, | 320 | .probe = tegra30_i2s_probe, |
322 | .playback = { | 321 | .playback = { |
322 | .stream_name = "Playback", | ||
323 | .channels_min = 2, | 323 | .channels_min = 2, |
324 | .channels_max = 2, | 324 | .channels_max = 2, |
325 | .rates = SNDRV_PCM_RATE_8000_96000, | 325 | .rates = SNDRV_PCM_RATE_8000_96000, |
326 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 326 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
327 | }, | 327 | }, |
328 | .capture = { | 328 | .capture = { |
329 | .stream_name = "Capture", | ||
329 | .channels_min = 2, | 330 | .channels_min = 2, |
330 | .channels_max = 2, | 331 | .channels_max = 2, |
331 | .rates = SNDRV_PCM_RATE_8000_96000, | 332 | .rates = SNDRV_PCM_RATE_8000_96000, |
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index 91adf29c7a87..34dc47b9581c 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h | |||
@@ -236,7 +236,6 @@ struct tegra30_i2s { | |||
236 | enum tegra30_ahub_txcif playback_fifo_cif; | 236 | enum tegra30_ahub_txcif playback_fifo_cif; |
237 | struct tegra_pcm_dma_params playback_dma_data; | 237 | struct tegra_pcm_dma_params playback_dma_data; |
238 | struct regmap *regmap; | 238 | struct regmap *regmap; |
239 | u32 reg_ctrl; | ||
240 | }; | 239 | }; |
241 | 240 | ||
242 | #endif | 241 | #endif |
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 32de7006daf0..d684df294c0c 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver | 2 | * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver |
3 | * | 3 | * |
4 | * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> | 4 | * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> |
5 | * Copyright (C) 2012 - NVIDIA, Inc. | 5 | * Copyright (C) 2012 - NVIDIA, Inc. |
@@ -33,11 +33,8 @@ | |||
33 | 33 | ||
34 | #define DRV_NAME "tegra-alc5632" | 34 | #define DRV_NAME "tegra-alc5632" |
35 | 35 | ||
36 | #define GPIO_HP_DET BIT(0) | ||
37 | |||
38 | struct tegra_alc5632 { | 36 | struct tegra_alc5632 { |
39 | struct tegra_asoc_utils_data util_data; | 37 | struct tegra_asoc_utils_data util_data; |
40 | int gpio_requested; | ||
41 | int gpio_hp_det; | 38 | int gpio_hp_det; |
42 | }; | 39 | }; |
43 | 40 | ||
@@ -46,7 +43,7 @@ static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, | |||
46 | { | 43 | { |
47 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 44 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
48 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 45 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
49 | struct snd_soc_codec *codec = rtd->codec; | 46 | struct snd_soc_codec *codec = codec_dai->codec; |
50 | struct snd_soc_card *card = codec->card; | 47 | struct snd_soc_card *card = codec->card; |
51 | struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); | 48 | struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); |
52 | int srate, mclk; | 49 | int srate, mclk; |
@@ -108,9 +105,9 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = { | |||
108 | 105 | ||
109 | static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | 106 | static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) |
110 | { | 107 | { |
111 | struct snd_soc_codec *codec = rtd->codec; | 108 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
109 | struct snd_soc_codec *codec = codec_dai->codec; | ||
112 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 110 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
113 | struct device_node *np = codec->card->dev->of_node; | ||
114 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); | 111 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); |
115 | 112 | ||
116 | snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, | 113 | snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, |
@@ -119,14 +116,11 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
119 | ARRAY_SIZE(tegra_alc5632_hs_jack_pins), | 116 | ARRAY_SIZE(tegra_alc5632_hs_jack_pins), |
120 | tegra_alc5632_hs_jack_pins); | 117 | tegra_alc5632_hs_jack_pins); |
121 | 118 | ||
122 | machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | ||
123 | |||
124 | if (gpio_is_valid(machine->gpio_hp_det)) { | 119 | if (gpio_is_valid(machine->gpio_hp_det)) { |
125 | tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; | 120 | tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; |
126 | snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, | 121 | snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, |
127 | 1, | 122 | 1, |
128 | &tegra_alc5632_hp_jack_gpio); | 123 | &tegra_alc5632_hp_jack_gpio); |
129 | machine->gpio_requested |= GPIO_HP_DET; | ||
130 | } | 124 | } |
131 | 125 | ||
132 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | 126 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); |
@@ -159,6 +153,7 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = { | |||
159 | 153 | ||
160 | static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | 154 | static __devinit int tegra_alc5632_probe(struct platform_device *pdev) |
161 | { | 155 | { |
156 | struct device_node *np = pdev->dev.of_node; | ||
162 | struct snd_soc_card *card = &snd_soc_tegra_alc5632; | 157 | struct snd_soc_card *card = &snd_soc_tegra_alc5632; |
163 | struct tegra_alc5632 *alc5632; | 158 | struct tegra_alc5632 *alc5632; |
164 | int ret; | 159 | int ret; |
@@ -181,6 +176,10 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | |||
181 | goto err; | 176 | goto err; |
182 | } | 177 | } |
183 | 178 | ||
179 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | ||
180 | if (alc5632->gpio_hp_det == -ENODEV) | ||
181 | return -EPROBE_DEFER; | ||
182 | |||
184 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | 183 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); |
185 | if (ret) | 184 | if (ret) |
186 | goto err; | 185 | goto err; |
@@ -199,16 +198,16 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | |||
199 | goto err; | 198 | goto err; |
200 | } | 199 | } |
201 | 200 | ||
202 | tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( | 201 | tegra_alc5632_dai.cpu_of_node = of_parse_phandle( |
203 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | 202 | pdev->dev.of_node, "nvidia,i2s-controller", 0); |
204 | if (!tegra_alc5632_dai.cpu_dai_of_node) { | 203 | if (!tegra_alc5632_dai.cpu_of_node) { |
205 | dev_err(&pdev->dev, | 204 | dev_err(&pdev->dev, |
206 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | 205 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
207 | ret = -EINVAL; | 206 | ret = -EINVAL; |
208 | goto err; | 207 | goto err; |
209 | } | 208 | } |
210 | 209 | ||
211 | tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node; | 210 | tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node; |
212 | 211 | ||
213 | ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); | 212 | ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); |
214 | if (ret) | 213 | if (ret) |
@@ -234,11 +233,8 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | |||
234 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 233 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
235 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); | 234 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); |
236 | 235 | ||
237 | if (machine->gpio_requested & GPIO_HP_DET) | 236 | snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1, |
238 | snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, | 237 | &tegra_alc5632_hp_jack_gpio); |
239 | 1, | ||
240 | &tegra_alc5632_hp_jack_gpio); | ||
241 | machine->gpio_requested = 0; | ||
242 | 238 | ||
243 | snd_soc_unregister_card(card); | 239 | snd_soc_unregister_card(card); |
244 | 240 | ||
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index 4e77026807a2..ea9166d5c4eb 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c | |||
@@ -57,7 +57,7 @@ static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream, | |||
57 | { | 57 | { |
58 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 58 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
59 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 59 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
60 | struct snd_soc_codec *codec = rtd->codec; | 60 | struct snd_soc_codec *codec = codec_dai->codec; |
61 | struct snd_soc_card *card = codec->card; | 61 | struct snd_soc_card *card = codec->card; |
62 | struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); | 62 | struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); |
63 | int srate, mclk; | 63 | int srate, mclk; |
@@ -157,9 +157,9 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) | |||
157 | goto err; | 157 | goto err; |
158 | } | 158 | } |
159 | 159 | ||
160 | tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle( | 160 | tegra_wm8753_dai.cpu_of_node = of_parse_phandle( |
161 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | 161 | pdev->dev.of_node, "nvidia,i2s-controller", 0); |
162 | if (!tegra_wm8753_dai.cpu_dai_of_node) { | 162 | if (!tegra_wm8753_dai.cpu_of_node) { |
163 | dev_err(&pdev->dev, | 163 | dev_err(&pdev->dev, |
164 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | 164 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
165 | ret = -EINVAL; | 165 | ret = -EINVAL; |
@@ -167,7 +167,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | tegra_wm8753_dai.platform_of_node = | 169 | tegra_wm8753_dai.platform_of_node = |
170 | tegra_wm8753_dai.cpu_dai_of_node; | 170 | tegra_wm8753_dai.cpu_of_node; |
171 | 171 | ||
172 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | 172 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); |
173 | if (ret) | 173 | if (ret) |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0b0df49d9d33..08b5fef67b31 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -28,8 +28,6 @@ | |||
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <asm/mach-types.h> | ||
32 | |||
33 | #include <linux/module.h> | 31 | #include <linux/module.h> |
34 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
35 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
@@ -50,16 +48,9 @@ | |||
50 | 48 | ||
51 | #define DRV_NAME "tegra-snd-wm8903" | 49 | #define DRV_NAME "tegra-snd-wm8903" |
52 | 50 | ||
53 | #define GPIO_SPKR_EN BIT(0) | ||
54 | #define GPIO_HP_MUTE BIT(1) | ||
55 | #define GPIO_INT_MIC_EN BIT(2) | ||
56 | #define GPIO_EXT_MIC_EN BIT(3) | ||
57 | #define GPIO_HP_DET BIT(4) | ||
58 | |||
59 | struct tegra_wm8903 { | 51 | struct tegra_wm8903 { |
60 | struct tegra_wm8903_platform_data pdata; | 52 | struct tegra_wm8903_platform_data pdata; |
61 | struct tegra_asoc_utils_data util_data; | 53 | struct tegra_asoc_utils_data util_data; |
62 | int gpio_requested; | ||
63 | }; | 54 | }; |
64 | 55 | ||
65 | static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, | 56 | static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, |
@@ -67,8 +58,7 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, | |||
67 | { | 58 | { |
68 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 59 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
69 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 60 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
70 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 61 | struct snd_soc_codec *codec = codec_dai->codec; |
71 | struct snd_soc_codec *codec = rtd->codec; | ||
72 | struct snd_soc_card *card = codec->card; | 62 | struct snd_soc_card *card = codec->card; |
73 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 63 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
74 | int srate, mclk; | 64 | int srate, mclk; |
@@ -95,24 +85,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, | |||
95 | return err; | 85 | return err; |
96 | } | 86 | } |
97 | 87 | ||
98 | err = snd_soc_dai_set_fmt(codec_dai, | ||
99 | SND_SOC_DAIFMT_I2S | | ||
100 | SND_SOC_DAIFMT_NB_NF | | ||
101 | SND_SOC_DAIFMT_CBS_CFS); | ||
102 | if (err < 0) { | ||
103 | dev_err(card->dev, "codec_dai fmt not set\n"); | ||
104 | return err; | ||
105 | } | ||
106 | |||
107 | err = snd_soc_dai_set_fmt(cpu_dai, | ||
108 | SND_SOC_DAIFMT_I2S | | ||
109 | SND_SOC_DAIFMT_NB_NF | | ||
110 | SND_SOC_DAIFMT_CBS_CFS); | ||
111 | if (err < 0) { | ||
112 | dev_err(card->dev, "cpu_dai fmt not set\n"); | ||
113 | return err; | ||
114 | } | ||
115 | |||
116 | err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, | 88 | err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, |
117 | SND_SOC_CLOCK_IN); | 89 | SND_SOC_CLOCK_IN); |
118 | if (err < 0) { | 90 | if (err < 0) { |
@@ -160,7 +132,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, | |||
160 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 132 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
161 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | 133 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; |
162 | 134 | ||
163 | if (!(machine->gpio_requested & GPIO_SPKR_EN)) | 135 | if (!gpio_is_valid(pdata->gpio_spkr_en)) |
164 | return 0; | 136 | return 0; |
165 | 137 | ||
166 | gpio_set_value_cansleep(pdata->gpio_spkr_en, | 138 | gpio_set_value_cansleep(pdata->gpio_spkr_en, |
@@ -177,7 +149,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, | |||
177 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 149 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
178 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | 150 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; |
179 | 151 | ||
180 | if (!(machine->gpio_requested & GPIO_HP_MUTE)) | 152 | if (!gpio_is_valid(pdata->gpio_hp_mute)) |
181 | return 0; | 153 | return 0; |
182 | 154 | ||
183 | gpio_set_value_cansleep(pdata->gpio_hp_mute, | 155 | gpio_set_value_cansleep(pdata->gpio_hp_mute, |
@@ -203,122 +175,18 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = { | |||
203 | {"IN1L", NULL, "Mic Jack"}, | 175 | {"IN1L", NULL, "Mic Jack"}, |
204 | }; | 176 | }; |
205 | 177 | ||
206 | static const struct snd_soc_dapm_route seaboard_audio_map[] = { | ||
207 | {"Headphone Jack", NULL, "HPOUTR"}, | ||
208 | {"Headphone Jack", NULL, "HPOUTL"}, | ||
209 | {"Int Spk", NULL, "ROP"}, | ||
210 | {"Int Spk", NULL, "RON"}, | ||
211 | {"Int Spk", NULL, "LOP"}, | ||
212 | {"Int Spk", NULL, "LON"}, | ||
213 | {"Mic Jack", NULL, "MICBIAS"}, | ||
214 | {"IN1R", NULL, "Mic Jack"}, | ||
215 | }; | ||
216 | |||
217 | static const struct snd_soc_dapm_route kaen_audio_map[] = { | ||
218 | {"Headphone Jack", NULL, "HPOUTR"}, | ||
219 | {"Headphone Jack", NULL, "HPOUTL"}, | ||
220 | {"Int Spk", NULL, "ROP"}, | ||
221 | {"Int Spk", NULL, "RON"}, | ||
222 | {"Int Spk", NULL, "LOP"}, | ||
223 | {"Int Spk", NULL, "LON"}, | ||
224 | {"Mic Jack", NULL, "MICBIAS"}, | ||
225 | {"IN2R", NULL, "Mic Jack"}, | ||
226 | }; | ||
227 | |||
228 | static const struct snd_soc_dapm_route aebl_audio_map[] = { | ||
229 | {"Headphone Jack", NULL, "HPOUTR"}, | ||
230 | {"Headphone Jack", NULL, "HPOUTL"}, | ||
231 | {"Int Spk", NULL, "LINEOUTR"}, | ||
232 | {"Int Spk", NULL, "LINEOUTL"}, | ||
233 | {"Mic Jack", NULL, "MICBIAS"}, | ||
234 | {"IN1R", NULL, "Mic Jack"}, | ||
235 | }; | ||
236 | |||
237 | static const struct snd_kcontrol_new tegra_wm8903_controls[] = { | 178 | static const struct snd_kcontrol_new tegra_wm8903_controls[] = { |
238 | SOC_DAPM_PIN_SWITCH("Int Spk"), | 179 | SOC_DAPM_PIN_SWITCH("Int Spk"), |
239 | }; | 180 | }; |
240 | 181 | ||
241 | static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) | 182 | static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) |
242 | { | 183 | { |
243 | struct snd_soc_codec *codec = rtd->codec; | 184 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
185 | struct snd_soc_codec *codec = codec_dai->codec; | ||
244 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 186 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
245 | struct snd_soc_card *card = codec->card; | 187 | struct snd_soc_card *card = codec->card; |
246 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 188 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
247 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | 189 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; |
248 | struct device_node *np = card->dev->of_node; | ||
249 | int ret; | ||
250 | |||
251 | if (card->dev->platform_data) { | ||
252 | memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); | ||
253 | } else if (np) { | ||
254 | /* | ||
255 | * This part must be in init() rather than probe() in order to | ||
256 | * guarantee that the WM8903 has been probed, and hence its | ||
257 | * GPIO controller registered, which is a pre-condition for | ||
258 | * of_get_named_gpio() to be able to map the phandles in the | ||
259 | * properties to the controller node. Given this, all | ||
260 | * pdata handling is in init() for consistency. | ||
261 | */ | ||
262 | pdata->gpio_spkr_en = of_get_named_gpio(np, | ||
263 | "nvidia,spkr-en-gpios", 0); | ||
264 | pdata->gpio_hp_mute = of_get_named_gpio(np, | ||
265 | "nvidia,hp-mute-gpios", 0); | ||
266 | pdata->gpio_hp_det = of_get_named_gpio(np, | ||
267 | "nvidia,hp-det-gpios", 0); | ||
268 | pdata->gpio_int_mic_en = of_get_named_gpio(np, | ||
269 | "nvidia,int-mic-en-gpios", 0); | ||
270 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, | ||
271 | "nvidia,ext-mic-en-gpios", 0); | ||
272 | } else { | ||
273 | dev_err(card->dev, "No platform data supplied\n"); | ||
274 | return -EINVAL; | ||
275 | } | ||
276 | |||
277 | if (gpio_is_valid(pdata->gpio_spkr_en)) { | ||
278 | ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); | ||
279 | if (ret) { | ||
280 | dev_err(card->dev, "cannot get spkr_en gpio\n"); | ||
281 | return ret; | ||
282 | } | ||
283 | machine->gpio_requested |= GPIO_SPKR_EN; | ||
284 | |||
285 | gpio_direction_output(pdata->gpio_spkr_en, 0); | ||
286 | } | ||
287 | |||
288 | if (gpio_is_valid(pdata->gpio_hp_mute)) { | ||
289 | ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); | ||
290 | if (ret) { | ||
291 | dev_err(card->dev, "cannot get hp_mute gpio\n"); | ||
292 | return ret; | ||
293 | } | ||
294 | machine->gpio_requested |= GPIO_HP_MUTE; | ||
295 | |||
296 | gpio_direction_output(pdata->gpio_hp_mute, 1); | ||
297 | } | ||
298 | |||
299 | if (gpio_is_valid(pdata->gpio_int_mic_en)) { | ||
300 | ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); | ||
301 | if (ret) { | ||
302 | dev_err(card->dev, "cannot get int_mic_en gpio\n"); | ||
303 | return ret; | ||
304 | } | ||
305 | machine->gpio_requested |= GPIO_INT_MIC_EN; | ||
306 | |||
307 | /* Disable int mic; enable signal is active-high */ | ||
308 | gpio_direction_output(pdata->gpio_int_mic_en, 0); | ||
309 | } | ||
310 | |||
311 | if (gpio_is_valid(pdata->gpio_ext_mic_en)) { | ||
312 | ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); | ||
313 | if (ret) { | ||
314 | dev_err(card->dev, "cannot get ext_mic_en gpio\n"); | ||
315 | return ret; | ||
316 | } | ||
317 | machine->gpio_requested |= GPIO_EXT_MIC_EN; | ||
318 | |||
319 | /* Enable ext mic; enable signal is active-low */ | ||
320 | gpio_direction_output(pdata->gpio_ext_mic_en, 0); | ||
321 | } | ||
322 | 190 | ||
323 | if (gpio_is_valid(pdata->gpio_hp_det)) { | 191 | if (gpio_is_valid(pdata->gpio_hp_det)) { |
324 | tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; | 192 | tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; |
@@ -330,7 +198,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) | |||
330 | snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, | 198 | snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, |
331 | 1, | 199 | 1, |
332 | &tegra_wm8903_hp_jack_gpio); | 200 | &tegra_wm8903_hp_jack_gpio); |
333 | machine->gpio_requested |= GPIO_HP_DET; | ||
334 | } | 201 | } |
335 | 202 | ||
336 | snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, | 203 | snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, |
@@ -355,6 +222,9 @@ static struct snd_soc_dai_link tegra_wm8903_dai = { | |||
355 | .codec_dai_name = "wm8903-hifi", | 222 | .codec_dai_name = "wm8903-hifi", |
356 | .init = tegra_wm8903_init, | 223 | .init = tegra_wm8903_init, |
357 | .ops = &tegra_wm8903_ops, | 224 | .ops = &tegra_wm8903_ops, |
225 | .dai_fmt = SND_SOC_DAIFMT_I2S | | ||
226 | SND_SOC_DAIFMT_NB_NF | | ||
227 | SND_SOC_DAIFMT_CBS_CFS, | ||
358 | }; | 228 | }; |
359 | 229 | ||
360 | static struct snd_soc_card snd_soc_tegra_wm8903 = { | 230 | static struct snd_soc_card snd_soc_tegra_wm8903 = { |
@@ -372,8 +242,10 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { | |||
372 | 242 | ||
373 | static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | 243 | static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) |
374 | { | 244 | { |
245 | struct device_node *np = pdev->dev.of_node; | ||
375 | struct snd_soc_card *card = &snd_soc_tegra_wm8903; | 246 | struct snd_soc_card *card = &snd_soc_tegra_wm8903; |
376 | struct tegra_wm8903 *machine; | 247 | struct tegra_wm8903 *machine; |
248 | struct tegra_wm8903_platform_data *pdata; | ||
377 | int ret; | 249 | int ret; |
378 | 250 | ||
379 | if (!pdev->dev.platform_data && !pdev->dev.of_node) { | 251 | if (!pdev->dev.platform_data && !pdev->dev.of_node) { |
@@ -388,12 +260,42 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
388 | ret = -ENOMEM; | 260 | ret = -ENOMEM; |
389 | goto err; | 261 | goto err; |
390 | } | 262 | } |
263 | pdata = &machine->pdata; | ||
391 | 264 | ||
392 | card->dev = &pdev->dev; | 265 | card->dev = &pdev->dev; |
393 | platform_set_drvdata(pdev, card); | 266 | platform_set_drvdata(pdev, card); |
394 | snd_soc_card_set_drvdata(card, machine); | 267 | snd_soc_card_set_drvdata(card, machine); |
395 | 268 | ||
396 | if (pdev->dev.of_node) { | 269 | if (pdev->dev.platform_data) { |
270 | memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); | ||
271 | } else if (np) { | ||
272 | pdata->gpio_spkr_en = of_get_named_gpio(np, | ||
273 | "nvidia,spkr-en-gpios", 0); | ||
274 | if (pdata->gpio_spkr_en == -ENODEV) | ||
275 | return -EPROBE_DEFER; | ||
276 | |||
277 | pdata->gpio_hp_mute = of_get_named_gpio(np, | ||
278 | "nvidia,hp-mute-gpios", 0); | ||
279 | if (pdata->gpio_hp_mute == -ENODEV) | ||
280 | return -EPROBE_DEFER; | ||
281 | |||
282 | pdata->gpio_hp_det = of_get_named_gpio(np, | ||
283 | "nvidia,hp-det-gpios", 0); | ||
284 | if (pdata->gpio_hp_det == -ENODEV) | ||
285 | return -EPROBE_DEFER; | ||
286 | |||
287 | pdata->gpio_int_mic_en = of_get_named_gpio(np, | ||
288 | "nvidia,int-mic-en-gpios", 0); | ||
289 | if (pdata->gpio_int_mic_en == -ENODEV) | ||
290 | return -EPROBE_DEFER; | ||
291 | |||
292 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, | ||
293 | "nvidia,ext-mic-en-gpios", 0); | ||
294 | if (pdata->gpio_ext_mic_en == -ENODEV) | ||
295 | return -EPROBE_DEFER; | ||
296 | } | ||
297 | |||
298 | if (np) { | ||
397 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | 299 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); |
398 | if (ret) | 300 | if (ret) |
399 | goto err; | 301 | goto err; |
@@ -404,8 +306,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
404 | goto err; | 306 | goto err; |
405 | 307 | ||
406 | tegra_wm8903_dai.codec_name = NULL; | 308 | tegra_wm8903_dai.codec_name = NULL; |
407 | tegra_wm8903_dai.codec_of_node = of_parse_phandle( | 309 | tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, |
408 | pdev->dev.of_node, "nvidia,audio-codec", 0); | 310 | "nvidia,audio-codec", 0); |
409 | if (!tegra_wm8903_dai.codec_of_node) { | 311 | if (!tegra_wm8903_dai.codec_of_node) { |
410 | dev_err(&pdev->dev, | 312 | dev_err(&pdev->dev, |
411 | "Property 'nvidia,audio-codec' missing or invalid\n"); | 313 | "Property 'nvidia,audio-codec' missing or invalid\n"); |
@@ -414,9 +316,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
414 | } | 316 | } |
415 | 317 | ||
416 | tegra_wm8903_dai.cpu_dai_name = NULL; | 318 | tegra_wm8903_dai.cpu_dai_name = NULL; |
417 | tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle( | 319 | tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, |
418 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | 320 | "nvidia,i2s-controller", 0); |
419 | if (!tegra_wm8903_dai.cpu_dai_of_node) { | 321 | if (!tegra_wm8903_dai.cpu_of_node) { |
420 | dev_err(&pdev->dev, | 322 | dev_err(&pdev->dev, |
421 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | 323 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
422 | ret = -EINVAL; | 324 | ret = -EINVAL; |
@@ -425,20 +327,47 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
425 | 327 | ||
426 | tegra_wm8903_dai.platform_name = NULL; | 328 | tegra_wm8903_dai.platform_name = NULL; |
427 | tegra_wm8903_dai.platform_of_node = | 329 | tegra_wm8903_dai.platform_of_node = |
428 | tegra_wm8903_dai.cpu_dai_of_node; | 330 | tegra_wm8903_dai.cpu_of_node; |
429 | } else { | 331 | } else { |
430 | if (machine_is_harmony()) { | 332 | card->dapm_routes = harmony_audio_map; |
431 | card->dapm_routes = harmony_audio_map; | 333 | card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); |
432 | card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); | 334 | } |
433 | } else if (machine_is_seaboard()) { | 335 | |
434 | card->dapm_routes = seaboard_audio_map; | 336 | if (gpio_is_valid(pdata->gpio_spkr_en)) { |
435 | card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); | 337 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en, |
436 | } else if (machine_is_kaen()) { | 338 | GPIOF_OUT_INIT_LOW, "spkr_en"); |
437 | card->dapm_routes = kaen_audio_map; | 339 | if (ret) { |
438 | card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); | 340 | dev_err(card->dev, "cannot get spkr_en gpio\n"); |
439 | } else { | 341 | return ret; |
440 | card->dapm_routes = aebl_audio_map; | 342 | } |
441 | card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); | 343 | } |
344 | |||
345 | if (gpio_is_valid(pdata->gpio_hp_mute)) { | ||
346 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute, | ||
347 | GPIOF_OUT_INIT_HIGH, "hp_mute"); | ||
348 | if (ret) { | ||
349 | dev_err(card->dev, "cannot get hp_mute gpio\n"); | ||
350 | return ret; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | if (gpio_is_valid(pdata->gpio_int_mic_en)) { | ||
355 | /* Disable int mic; enable signal is active-high */ | ||
356 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en, | ||
357 | GPIOF_OUT_INIT_LOW, "int_mic_en"); | ||
358 | if (ret) { | ||
359 | dev_err(card->dev, "cannot get int_mic_en gpio\n"); | ||
360 | return ret; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | if (gpio_is_valid(pdata->gpio_ext_mic_en)) { | ||
365 | /* Enable ext mic; enable signal is active-low */ | ||
366 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en, | ||
367 | GPIOF_OUT_INIT_LOW, "ext_mic_en"); | ||
368 | if (ret) { | ||
369 | dev_err(card->dev, "cannot get ext_mic_en gpio\n"); | ||
370 | return ret; | ||
442 | } | 371 | } |
443 | } | 372 | } |
444 | 373 | ||
@@ -465,21 +394,9 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) | |||
465 | { | 394 | { |
466 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 395 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
467 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 396 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
468 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
469 | 397 | ||
470 | if (machine->gpio_requested & GPIO_HP_DET) | 398 | snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1, |
471 | snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, | 399 | &tegra_wm8903_hp_jack_gpio); |
472 | 1, | ||
473 | &tegra_wm8903_hp_jack_gpio); | ||
474 | if (machine->gpio_requested & GPIO_EXT_MIC_EN) | ||
475 | gpio_free(pdata->gpio_ext_mic_en); | ||
476 | if (machine->gpio_requested & GPIO_INT_MIC_EN) | ||
477 | gpio_free(pdata->gpio_int_mic_en); | ||
478 | if (machine->gpio_requested & GPIO_HP_MUTE) | ||
479 | gpio_free(pdata->gpio_hp_mute); | ||
480 | if (machine->gpio_requested & GPIO_SPKR_EN) | ||
481 | gpio_free(pdata->gpio_spkr_en); | ||
482 | machine->gpio_requested = 0; | ||
483 | 400 | ||
484 | snd_soc_unregister_card(card); | 401 | snd_soc_unregister_card(card); |
485 | 402 | ||
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 4a8d5b672c9f..e69a4f7000d6 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c | |||
@@ -52,8 +52,7 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream, | |||
52 | { | 52 | { |
53 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 53 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
54 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 54 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
55 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 55 | struct snd_soc_codec *codec = codec_dai->codec; |
56 | struct snd_soc_codec *codec = rtd->codec; | ||
57 | struct snd_soc_card *card = codec->card; | 56 | struct snd_soc_card *card = codec->card; |
58 | struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); | 57 | struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); |
59 | int srate, mclk; | 58 | int srate, mclk; |
@@ -68,24 +67,6 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream, | |||
68 | return err; | 67 | return err; |
69 | } | 68 | } |
70 | 69 | ||
71 | err = snd_soc_dai_set_fmt(codec_dai, | ||
72 | SND_SOC_DAIFMT_I2S | | ||
73 | SND_SOC_DAIFMT_NB_NF | | ||
74 | SND_SOC_DAIFMT_CBS_CFS); | ||
75 | if (err < 0) { | ||
76 | dev_err(card->dev, "codec_dai fmt not set\n"); | ||
77 | return err; | ||
78 | } | ||
79 | |||
80 | err = snd_soc_dai_set_fmt(cpu_dai, | ||
81 | SND_SOC_DAIFMT_I2S | | ||
82 | SND_SOC_DAIFMT_NB_NF | | ||
83 | SND_SOC_DAIFMT_CBS_CFS); | ||
84 | if (err < 0) { | ||
85 | dev_err(card->dev, "cpu_dai fmt not set\n"); | ||
86 | return err; | ||
87 | } | ||
88 | |||
89 | err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, | 70 | err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, |
90 | SND_SOC_CLOCK_IN); | 71 | SND_SOC_CLOCK_IN); |
91 | if (err < 0) { | 72 | if (err < 0) { |
@@ -121,6 +102,9 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { | |||
121 | .cpu_dai_name = "tegra20-i2s.0", | 102 | .cpu_dai_name = "tegra20-i2s.0", |
122 | .codec_dai_name = "tlv320aic23-hifi", | 103 | .codec_dai_name = "tlv320aic23-hifi", |
123 | .ops = &trimslice_asoc_ops, | 104 | .ops = &trimslice_asoc_ops, |
105 | .dai_fmt = SND_SOC_DAIFMT_I2S | | ||
106 | SND_SOC_DAIFMT_NB_NF | | ||
107 | SND_SOC_DAIFMT_CBS_CFS, | ||
124 | }; | 108 | }; |
125 | 109 | ||
126 | static struct snd_soc_card snd_soc_trimslice = { | 110 | static struct snd_soc_card snd_soc_trimslice = { |
@@ -162,9 +146,9 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) | |||
162 | } | 146 | } |
163 | 147 | ||
164 | trimslice_tlv320aic23_dai.cpu_dai_name = NULL; | 148 | trimslice_tlv320aic23_dai.cpu_dai_name = NULL; |
165 | trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle( | 149 | trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle( |
166 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | 150 | pdev->dev.of_node, "nvidia,i2s-controller", 0); |
167 | if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) { | 151 | if (!trimslice_tlv320aic23_dai.cpu_of_node) { |
168 | dev_err(&pdev->dev, | 152 | dev_err(&pdev->dev, |
169 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | 153 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
170 | ret = -EINVAL; | 154 | ret = -EINVAL; |
@@ -173,7 +157,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) | |||
173 | 157 | ||
174 | trimslice_tlv320aic23_dai.platform_name = NULL; | 158 | trimslice_tlv320aic23_dai.platform_name = NULL; |
175 | trimslice_tlv320aic23_dai.platform_of_node = | 159 | trimslice_tlv320aic23_dai.platform_of_node = |
176 | trimslice_tlv320aic23_dai.cpu_dai_of_node; | 160 | trimslice_tlv320aic23_dai.cpu_of_node; |
177 | } | 161 | } |
178 | 162 | ||
179 | ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); | 163 | ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); |
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig index 44cf43404cd9..1d385150064f 100644 --- a/sound/soc/ux500/Kconfig +++ b/sound/soc/ux500/Kconfig | |||
@@ -12,3 +12,10 @@ menuconfig SND_SOC_UX500 | |||
12 | config SND_SOC_UX500_PLAT_MSP_I2S | 12 | config SND_SOC_UX500_PLAT_MSP_I2S |
13 | tristate | 13 | tristate |
14 | depends on SND_SOC_UX500 | 14 | depends on SND_SOC_UX500 |
15 | |||
16 | config SND_SOC_UX500_PLAT_DMA | ||
17 | tristate "Platform - DB8500 (DMA)" | ||
18 | depends on SND_SOC_UX500 | ||
19 | select SND_SOC_DMAENGINE_PCM | ||
20 | help | ||
21 | Say Y if you want to enable the Ux500 platform-driver. | ||
diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile index 19974c5a2ea1..4634bf015f62 100644 --- a/sound/soc/ux500/Makefile +++ b/sound/soc/ux500/Makefile | |||
@@ -2,3 +2,6 @@ | |||
2 | 2 | ||
3 | snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o | 3 | snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o |
4 | obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o | 4 | obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o |
5 | |||
6 | snd-soc-ux500-plat-dma-objs := ux500_pcm.o | ||
7 | obj-$(CONFIG_SND_SOC_UX500_PLAT_DMA) += snd-soc-ux500-plat-dma.o | ||
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c new file mode 100644 index 000000000000..66b080e5de96 --- /dev/null +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2012 | ||
3 | * | ||
4 | * Author: Ola Lilja <ola.o.lilja@stericsson.com>, | ||
5 | * Roger Nilsson <roger.xr.nilsson@stericsson.com> | ||
6 | * for ST-Ericsson. | ||
7 | * | ||
8 | * License terms: | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as published | ||
12 | * by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <asm/page.h> | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <linux/dmaengine.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | #include <plat/ste_dma40.h> | ||
23 | |||
24 | #include <sound/pcm.h> | ||
25 | #include <sound/pcm_params.h> | ||
26 | #include <sound/soc.h> | ||
27 | #include <sound/dmaengine_pcm.h> | ||
28 | |||
29 | #include "ux500_msp_i2s.h" | ||
30 | #include "ux500_pcm.h" | ||
31 | |||
32 | static struct snd_pcm_hardware ux500_pcm_hw_playback = { | ||
33 | .info = SNDRV_PCM_INFO_INTERLEAVED | | ||
34 | SNDRV_PCM_INFO_MMAP | | ||
35 | SNDRV_PCM_INFO_RESUME | | ||
36 | SNDRV_PCM_INFO_PAUSE, | ||
37 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
38 | SNDRV_PCM_FMTBIT_U16_LE | | ||
39 | SNDRV_PCM_FMTBIT_S16_BE | | ||
40 | SNDRV_PCM_FMTBIT_U16_BE, | ||
41 | .rates = SNDRV_PCM_RATE_KNOT, | ||
42 | .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK, | ||
43 | .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK, | ||
44 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, | ||
45 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, | ||
46 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, | ||
47 | .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, | ||
48 | .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, | ||
49 | .periods_min = UX500_PLATFORM_PERIODS_MIN, | ||
50 | .periods_max = UX500_PLATFORM_PERIODS_MAX, | ||
51 | }; | ||
52 | |||
53 | static struct snd_pcm_hardware ux500_pcm_hw_capture = { | ||
54 | .info = SNDRV_PCM_INFO_INTERLEAVED | | ||
55 | SNDRV_PCM_INFO_MMAP | | ||
56 | SNDRV_PCM_INFO_RESUME | | ||
57 | SNDRV_PCM_INFO_PAUSE, | ||
58 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
59 | SNDRV_PCM_FMTBIT_U16_LE | | ||
60 | SNDRV_PCM_FMTBIT_S16_BE | | ||
61 | SNDRV_PCM_FMTBIT_U16_BE, | ||
62 | .rates = SNDRV_PCM_RATE_KNOT, | ||
63 | .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE, | ||
64 | .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE, | ||
65 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, | ||
66 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, | ||
67 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, | ||
68 | .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, | ||
69 | .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, | ||
70 | .periods_min = UX500_PLATFORM_PERIODS_MIN, | ||
71 | .periods_max = UX500_PLATFORM_PERIODS_MAX, | ||
72 | }; | ||
73 | |||
74 | static void ux500_pcm_dma_hw_free(struct device *dev, | ||
75 | struct snd_pcm_substream *substream) | ||
76 | { | ||
77 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
78 | struct snd_dma_buffer *buf = runtime->dma_buffer_p; | ||
79 | |||
80 | if (runtime->dma_area == NULL) | ||
81 | return; | ||
82 | |||
83 | if (buf != &substream->dma_buffer) { | ||
84 | dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, | ||
85 | buf->addr); | ||
86 | kfree(runtime->dma_buffer_p); | ||
87 | } | ||
88 | |||
89 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
90 | } | ||
91 | |||
92 | static int ux500_pcm_open(struct snd_pcm_substream *substream) | ||
93 | { | ||
94 | int stream_id = substream->pstr->stream; | ||
95 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
96 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
97 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
98 | struct device *dev = dai->dev; | ||
99 | int ret; | ||
100 | struct ux500_msp_dma_params *dma_params; | ||
101 | u16 per_data_width, mem_data_width; | ||
102 | struct stedma40_chan_cfg *dma_cfg; | ||
103 | |||
104 | dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, | ||
105 | snd_pcm_stream_str(substream)); | ||
106 | |||
107 | dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); | ||
108 | if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) | ||
109 | snd_soc_set_runtime_hwparams(substream, | ||
110 | &ux500_pcm_hw_playback); | ||
111 | else | ||
112 | snd_soc_set_runtime_hwparams(substream, | ||
113 | &ux500_pcm_hw_capture); | ||
114 | |||
115 | /* ensure that buffer size is a multiple of period size */ | ||
116 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
117 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
118 | if (ret < 0) { | ||
119 | dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", | ||
120 | __func__, ret); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, | ||
125 | snd_pcm_stream_str(substream)); | ||
126 | runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
127 | ux500_pcm_hw_playback : ux500_pcm_hw_capture; | ||
128 | |||
129 | mem_data_width = STEDMA40_HALFWORD_WIDTH; | ||
130 | |||
131 | dma_params = snd_soc_dai_get_dma_data(dai, substream); | ||
132 | switch (dma_params->data_size) { | ||
133 | case 32: | ||
134 | per_data_width = STEDMA40_WORD_WIDTH; | ||
135 | break; | ||
136 | case 16: | ||
137 | per_data_width = STEDMA40_HALFWORD_WIDTH; | ||
138 | break; | ||
139 | case 8: | ||
140 | per_data_width = STEDMA40_BYTE_WIDTH; | ||
141 | break; | ||
142 | default: | ||
143 | per_data_width = STEDMA40_WORD_WIDTH; | ||
144 | dev_warn(rtd->platform->dev, | ||
145 | "%s: Unknown data-size (%d)! Assuming 32 bits.\n", | ||
146 | __func__, dma_params->data_size); | ||
147 | } | ||
148 | |||
149 | dma_cfg = dma_params->dma_cfg; | ||
150 | |||
151 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
152 | dma_cfg->src_info.data_width = mem_data_width; | ||
153 | dma_cfg->dst_info.data_width = per_data_width; | ||
154 | } else { | ||
155 | dma_cfg->src_info.data_width = per_data_width; | ||
156 | dma_cfg->dst_info.data_width = mem_data_width; | ||
157 | } | ||
158 | |||
159 | |||
160 | ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg); | ||
161 | if (ret) { | ||
162 | dev_dbg(dai->dev, | ||
163 | "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n", | ||
164 | __func__, ret); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | snd_dmaengine_pcm_set_data(substream, dma_cfg); | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int ux500_pcm_close(struct snd_pcm_substream *substream) | ||
174 | { | ||
175 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
176 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
177 | |||
178 | dev_dbg(dai->dev, "%s: Enter\n", __func__); | ||
179 | |||
180 | snd_dmaengine_pcm_close(substream); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, | ||
186 | struct snd_pcm_hw_params *hw_params) | ||
187 | { | ||
188 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
189 | struct snd_dma_buffer *buf = runtime->dma_buffer_p; | ||
190 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
191 | int ret = 0; | ||
192 | int size; | ||
193 | |||
194 | dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); | ||
195 | |||
196 | size = params_buffer_bytes(hw_params); | ||
197 | |||
198 | if (buf) { | ||
199 | if (buf->bytes >= size) | ||
200 | goto out; | ||
201 | ux500_pcm_dma_hw_free(NULL, substream); | ||
202 | } | ||
203 | |||
204 | if (substream->dma_buffer.area != NULL && | ||
205 | substream->dma_buffer.bytes >= size) { | ||
206 | buf = &substream->dma_buffer; | ||
207 | } else { | ||
208 | buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL); | ||
209 | if (!buf) | ||
210 | goto nomem; | ||
211 | |||
212 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
213 | buf->dev.dev = NULL; | ||
214 | buf->area = dma_alloc_coherent(NULL, size, &buf->addr, | ||
215 | GFP_KERNEL); | ||
216 | buf->bytes = size; | ||
217 | buf->private_data = NULL; | ||
218 | |||
219 | if (!buf->area) | ||
220 | goto free; | ||
221 | } | ||
222 | snd_pcm_set_runtime_buffer(substream, buf); | ||
223 | ret = 1; | ||
224 | out: | ||
225 | runtime->dma_bytes = size; | ||
226 | return ret; | ||
227 | |||
228 | free: | ||
229 | kfree(buf); | ||
230 | nomem: | ||
231 | return -ENOMEM; | ||
232 | } | ||
233 | |||
234 | static int ux500_pcm_hw_free(struct snd_pcm_substream *substream) | ||
235 | { | ||
236 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
237 | |||
238 | dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); | ||
239 | |||
240 | ux500_pcm_dma_hw_free(NULL, substream); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int ux500_pcm_mmap(struct snd_pcm_substream *substream, | ||
246 | struct vm_area_struct *vma) | ||
247 | { | ||
248 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
249 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
250 | |||
251 | dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__); | ||
252 | |||
253 | return dma_mmap_coherent(NULL, vma, runtime->dma_area, | ||
254 | runtime->dma_addr, runtime->dma_bytes); | ||
255 | } | ||
256 | |||
257 | static struct snd_pcm_ops ux500_pcm_ops = { | ||
258 | .open = ux500_pcm_open, | ||
259 | .close = ux500_pcm_close, | ||
260 | .ioctl = snd_pcm_lib_ioctl, | ||
261 | .hw_params = ux500_pcm_hw_params, | ||
262 | .hw_free = ux500_pcm_hw_free, | ||
263 | .trigger = snd_dmaengine_pcm_trigger, | ||
264 | .pointer = snd_dmaengine_pcm_pointer, | ||
265 | .mmap = ux500_pcm_mmap | ||
266 | }; | ||
267 | |||
268 | int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
269 | { | ||
270 | struct snd_pcm *pcm = rtd->pcm; | ||
271 | |||
272 | dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__, | ||
273 | pcm->id); | ||
274 | |||
275 | pcm->info_flags = 0; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static struct snd_soc_platform_driver ux500_pcm_soc_drv = { | ||
281 | .ops = &ux500_pcm_ops, | ||
282 | .pcm_new = ux500_pcm_new, | ||
283 | }; | ||
284 | |||
285 | static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) | ||
286 | { | ||
287 | int ret; | ||
288 | |||
289 | ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv); | ||
290 | if (ret < 0) { | ||
291 | dev_err(&pdev->dev, | ||
292 | "%s: ERROR: Failed to register platform '%s' (%d)!\n", | ||
293 | __func__, pdev->name, ret); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev) | ||
301 | { | ||
302 | snd_soc_unregister_platform(&pdev->dev); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static struct platform_driver ux500_pcm_driver = { | ||
308 | .driver = { | ||
309 | .name = "ux500-pcm", | ||
310 | .owner = THIS_MODULE, | ||
311 | }, | ||
312 | |||
313 | .probe = ux500_pcm_drv_probe, | ||
314 | .remove = __devexit_p(ux500_pcm_drv_remove), | ||
315 | }; | ||
316 | module_platform_driver(ux500_pcm_driver); | ||
317 | |||
318 | MODULE_LICENSE("GPLv2"); | ||
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h new file mode 100644 index 000000000000..77ed44d371e9 --- /dev/null +++ b/sound/soc/ux500/ux500_pcm.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2012 | ||
3 | * | ||
4 | * Author: Ola Lilja <ola.o.lilja@stericsson.com>, | ||
5 | * Roger Nilsson <roger.xr.nilsson@stericsson.com> | ||
6 | * for ST-Ericsson. | ||
7 | * | ||
8 | * License terms: | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as published | ||
12 | * by the Free Software Foundation. | ||
13 | */ | ||
14 | #ifndef UX500_PCM_H | ||
15 | #define UX500_PCM_H | ||
16 | |||
17 | #include <asm/page.h> | ||
18 | |||
19 | #include <linux/workqueue.h> | ||
20 | |||
21 | #define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000 | ||
22 | #define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000 | ||
23 | #define UX500_PLATFORM_MIN_RATE_CAPTURE 8000 | ||
24 | #define UX500_PLATFORM_MAX_RATE_CAPTURE 48000 | ||
25 | |||
26 | #define UX500_PLATFORM_MIN_CHANNELS 1 | ||
27 | #define UX500_PLATFORM_MAX_CHANNELS 8 | ||
28 | |||
29 | #define UX500_PLATFORM_PERIODS_BYTES_MIN 128 | ||
30 | #define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) | ||
31 | #define UX500_PLATFORM_PERIODS_MIN 2 | ||
32 | #define UX500_PLATFORM_PERIODS_MAX 48 | ||
33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | ||
34 | |||
35 | #endif | ||