Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000', 'asoc/topic/sh', 'asoc/topic/simple', 'asoc/topic/sirf', 'asoc/topic/sn95031', 'asoc/topic/ssm2602' and 'asoc/topic/stac9766' into asoc-next

+1566 -435
+15 -2
Documentation/devicetree/bindings/sound/simple-card.txt
··· 8 8 9 9 Optional properties: 10 10 11 + - simple-audio-card,name : User specified audio sound card name, one string 12 + property. 11 13 - simple-audio-card,format : CPU/CODEC common audio format. 12 14 "i2s", "right_j", "left_j" , "dsp_a" 13 15 "dsp_b", "ac97", "pdm", "msb", "lsb" 16 + - simple-audio-card,widgets : Please refer to widgets.txt. 14 17 - simple-audio-card,routing : A list of the connections between audio components. 15 18 Each entry is a pair of strings, the first being the 16 19 connection's sink, the second being the connection's 17 20 source. 21 + - dai-tdm-slot-num : Please refer to tdm-slot.txt. 22 + - dai-tdm-slot-width : Please refer to tdm-slot.txt. 18 23 19 24 Required subnodes: 20 25 ··· 47 42 48 43 sound { 49 44 compatible = "simple-audio-card"; 45 + simple-audio-card,name = "VF610-Tower-Sound-Card"; 50 46 simple-audio-card,format = "left_j"; 47 + simple-audio-card,widgets = 48 + "Microphone", "Microphone Jack", 49 + "Headphone", "Headphone Jack", 50 + "Speaker", "External Speaker"; 51 51 simple-audio-card,routing = 52 - "MIC_IN", "Mic Jack", 52 + "MIC_IN", "Microphone Jack", 53 53 "Headphone Jack", "HP_OUT", 54 - "Ext Spk", "LINE_OUT"; 54 + "External Speaker", "LINE_OUT"; 55 + 56 + dai-tdm-slot-num = <2>; 57 + dai-tdm-slot-width = <8>; 55 58 56 59 simple-audio-card,cpu { 57 60 sound-dai = <&sh_fsi2 0>;
+17
Documentation/devicetree/bindings/sound/sirf-audio-codec.txt
··· 1 + SiRF internal audio CODEC 2 + 3 + Required properties: 4 + 5 + - compatible : "sirf,atlas6-audio-codec" or "sirf,prima2-audio-codec" 6 + 7 + - reg : the register address of the device. 8 + 9 + - clocks: the clock of SiRF internal audio codec 10 + 11 + Example: 12 + 13 + audiocodec: audiocodec@b0040000 { 14 + compatible = "sirf,atlas6-audio-codec"; 15 + reg = <0xb0040000 0x10000>; 16 + clocks = <&clks 27>; 17 + };
+20
Documentation/devicetree/bindings/sound/sirf-audio-port.txt
··· 1 + * SiRF SoC audio port 2 + 3 + Required properties: 4 + - compatible: "sirf,audio-port" 5 + - reg: Base address and size entries: 6 + - dmas: List of DMA controller phandle and DMA request line ordered pairs. 7 + - dma-names: Identifier string for each DMA request line in the dmas property. 8 + These strings correspond 1:1 with the ordered pairs in dmas. 9 + 10 + One of the DMA channels will be responsible for transmission (should be 11 + named "tx") and one for reception (should be named "rx"). 12 + 13 + Example: 14 + 15 + audioport: audioport@b0040000 { 16 + compatible = "sirf,audio-port"; 17 + reg = <0xb0040000 0x10000>; 18 + dmas = <&dmac1 3>, <&dmac1 8>; 19 + dma-names = "rx", "tx"; 20 + };
+41
Documentation/devicetree/bindings/sound/sirf-audio.txt
··· 1 + * SiRF atlas6 and prima2 internal audio codec and port based audio setups 2 + 3 + Required properties: 4 + - compatible: "sirf,sirf-audio-card" 5 + - sirf,audio-platform: phandle for the platform node 6 + - sirf,audio-codec: phandle for the SiRF internal codec node 7 + 8 + Optional properties: 9 + - hp-pa-gpios: Need to be present if the board need control external 10 + headphone amplifier. 11 + - spk-pa-gpios: Need to be present if the board need control external 12 + speaker amplifier. 13 + - hp-switch-gpios: Need to be present if the board capable to detect jack 14 + insertion, removal. 15 + 16 + Available audio endpoints for the audio-routing table: 17 + 18 + Board connectors: 19 + * Headset Stereophone 20 + * Ext Spk 21 + * Line In 22 + * Mic 23 + 24 + SiRF internal audio codec pins: 25 + * HPOUTL 26 + * HPOUTR 27 + * SPKOUT 28 + * Ext Mic 29 + * Mic Bias 30 + 31 + Example: 32 + 33 + sound { 34 + compatible = "sirf,sirf-audio-card"; 35 + sirf,audio-codec = <&audiocodec>; 36 + sirf,audio-platform = <&audioport>; 37 + hp-pa-gpios = <&gpio 44 0>; 38 + spk-pa-gpios = <&gpio 46 0>; 39 + hp-switch-gpios = <&gpio 45 0>; 40 + }; 41 +
+1 -2
include/linux/platform_data/asoc-s3c.h
··· 1 - /* arch/arm/plat-samsung/include/plat/audio.h 2 - * 1 + /* 3 2 * Copyright (c) 2009 Samsung Electronics Co. Ltd 4 3 * Author: Jaswinder Singh <jassi.brar@samsung.com> 5 4 *
+1 -2
include/linux/platform_data/asoc-s3c24xx_simtec.h
··· 1 - /* arch/arm/plat-samsung/include/plat/audio-simtec.h 2 - * 1 + /* 3 2 * Copyright 2008 Simtec Electronics 4 3 * http://armlinux.simtec.co.uk/ 5 4 * Ben Dooks <ben@simtec.co.uk>
+2 -4
include/sound/simple_card.h
··· 18 18 const char *name; 19 19 unsigned int fmt; 20 20 unsigned int sysclk; 21 + int slots; 22 + int slot_width; 21 23 }; 22 24 23 25 struct asoc_simple_card_info { ··· 31 29 unsigned int daifmt; 32 30 struct asoc_simple_dai cpu_dai; 33 31 struct asoc_simple_dai codec_dai; 34 - 35 - /* used in simple-card.c */ 36 - struct snd_soc_dai_link snd_link; 37 - struct snd_soc_card snd_card; 38 32 }; 39 33 40 34 #endif /* __SIMPLE_CARD_H */
+1
sound/soc/Kconfig
··· 50 50 source "sound/soc/samsung/Kconfig" 51 51 source "sound/soc/s6000/Kconfig" 52 52 source "sound/soc/sh/Kconfig" 53 + source "sound/soc/sirf/Kconfig" 53 54 source "sound/soc/spear/Kconfig" 54 55 source "sound/soc/tegra/Kconfig" 55 56 source "sound/soc/txx9/Kconfig"
+1
sound/soc/Makefile
··· 27 27 obj-$(CONFIG_SND_SOC) += samsung/ 28 28 obj-$(CONFIG_SND_SOC) += s6000/ 29 29 obj-$(CONFIG_SND_SOC) += sh/ 30 + obj-$(CONFIG_SND_SOC) += sirf/ 30 31 obj-$(CONFIG_SND_SOC) += spear/ 31 32 obj-$(CONFIG_SND_SOC) += tegra/ 32 33 obj-$(CONFIG_SND_SOC) += txx9/
+2 -1
sound/soc/blackfin/Kconfig
··· 14 14 depends on SND_BF5XX_I2S && SND_SOC_I2C_AND_SPI 15 15 select SND_BF5XX_SOC_I2S if !BF60x 16 16 select SND_BF6XX_SOC_I2S if BF60x 17 - select SND_SOC_SSM2602 17 + select SND_SOC_SSM2602_SPI if SPI_MASTER 18 + select SND_SOC_SSM2602_I2C if I2C 18 19 help 19 20 Say Y if you want to add support for the Analog Devices 20 21 SSM2602 Audio Codec Add-On Card.
+15 -1
sound/soc/codecs/Kconfig
··· 72 72 select SND_SOC_RT5640 if I2C 73 73 select SND_SOC_SGTL5000 if I2C 74 74 select SND_SOC_SI476X if MFD_SI476X_CORE 75 + select SND_SOC_SIRF_AUDIO_CODEC 75 76 select SND_SOC_SN95031 if INTEL_SCU_IPC 76 77 select SND_SOC_SPDIF 77 78 select SND_SOC_SSM2518 if I2C 78 - select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI 79 + select SND_SOC_SSM2602_SPI if SPI_MASTER 80 + select SND_SOC_SSM2602_I2C if I2C 79 81 select SND_SOC_STA32X if I2C 80 82 select SND_SOC_STA529 if I2C 81 83 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS ··· 397 395 tristate 398 396 select CRC32 399 397 398 + config SND_SOC_SIRF_AUDIO_CODEC 399 + tristate "SiRF SoC internal audio codec" 400 + select REGMAP_MMIO 401 + 400 402 config SND_SOC_SN95031 401 403 tristate 402 404 ··· 411 405 tristate 412 406 413 407 config SND_SOC_SSM2602 408 + tristate 409 + 410 + config SND_SOC_SSM2602_SPI 411 + select SND_SOC_SSM2602 412 + tristate 413 + 414 + config SND_SOC_SSM2602_I2C 415 + select SND_SOC_SSM2602 414 416 tristate 415 417 416 418 config SND_SOC_STA32X
+5
sound/soc/codecs/Makefile
··· 63 63 snd-soc-alc5632-objs := alc5632.o 64 64 snd-soc-sigmadsp-objs := sigmadsp.o 65 65 snd-soc-si476x-objs := si476x.o 66 + snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o 66 67 snd-soc-sn95031-objs := sn95031.o 67 68 snd-soc-spdif-tx-objs := spdif_transmitter.o 68 69 snd-soc-spdif-rx-objs := spdif_receiver.o 69 70 snd-soc-ssm2518-objs := ssm2518.o 70 71 snd-soc-ssm2602-objs := ssm2602.o 72 + snd-soc-ssm2602-spi-objs := ssm2602-spi.o 73 + snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o 71 74 snd-soc-sta32x-objs := sta32x.o 72 75 snd-soc-sta529-objs := sta529.o 73 76 snd-soc-stac9766-objs := stac9766.o ··· 213 210 obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o 214 211 obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o 215 212 obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 213 + obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o 214 + obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o 216 215 obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o 217 216 obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o 218 217 obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
+6 -4
sound/soc/codecs/sgtl5000.c
··· 187 187 "MIC_IN", "LINE_IN" 188 188 }; 189 189 190 - static const struct soc_enum adc_enum = 191 - SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text); 190 + static SOC_ENUM_SINGLE_DECL(adc_enum, 191 + SGTL5000_CHIP_ANA_CTRL, 2, 192 + adc_mux_text); 192 193 193 194 static const struct snd_kcontrol_new adc_mux = 194 195 SOC_DAPM_ENUM("Capture Mux", adc_enum); ··· 199 198 "DAC", "LINE_IN" 200 199 }; 201 200 202 - static const struct soc_enum dac_enum = 203 - SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text); 201 + static SOC_ENUM_SINGLE_DECL(dac_enum, 202 + SGTL5000_CHIP_ANA_CTRL, 6, 203 + dac_mux_text); 204 204 205 205 static const struct snd_kcontrol_new dac_mux = 206 206 SOC_DAPM_ENUM("Headphone Mux", dac_enum);
+533
sound/soc/codecs/sirf-audio-codec.c
··· 1 + /* 2 + * SiRF audio codec driver 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/pm_runtime.h> 12 + #include <linux/of.h> 13 + #include <linux/of_device.h> 14 + #include <linux/clk.h> 15 + #include <linux/delay.h> 16 + #include <linux/io.h> 17 + #include <linux/regmap.h> 18 + #include <sound/core.h> 19 + #include <sound/pcm.h> 20 + #include <sound/pcm_params.h> 21 + #include <sound/initval.h> 22 + #include <sound/tlv.h> 23 + #include <sound/soc.h> 24 + #include <sound/dmaengine_pcm.h> 25 + 26 + #include "sirf-audio-codec.h" 27 + 28 + struct sirf_audio_codec { 29 + struct clk *clk; 30 + struct regmap *regmap; 31 + u32 reg_ctrl0, reg_ctrl1; 32 + }; 33 + 34 + static const char * const input_mode_mux[] = {"Single-ended", 35 + "Differential"}; 36 + 37 + static const struct soc_enum input_mode_mux_enum = 38 + SOC_ENUM_SINGLE(AUDIO_IC_CODEC_CTRL1, 4, 2, input_mode_mux); 39 + 40 + static const struct snd_kcontrol_new sirf_audio_codec_input_mode_control = 41 + SOC_DAPM_ENUM("Route", input_mode_mux_enum); 42 + 43 + static const DECLARE_TLV_DB_SCALE(playback_vol_tlv, -12400, 100, 0); 44 + static const DECLARE_TLV_DB_SCALE(capture_vol_tlv_prima2, 500, 100, 0); 45 + static const DECLARE_TLV_DB_RANGE(capture_vol_tlv_atlas6, 46 + 0, 7, TLV_DB_SCALE_ITEM(-100, 100, 0), 47 + 0x22, 0x3F, TLV_DB_SCALE_ITEM(700, 100, 0), 48 + ); 49 + 50 + static struct snd_kcontrol_new volume_controls_atlas6[] = { 51 + SOC_DOUBLE_TLV("Playback Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, 52 + 0x7F, 0, playback_vol_tlv), 53 + SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 16, 10, 54 + 0x3F, 0, capture_vol_tlv_atlas6), 55 + }; 56 + 57 + static struct snd_kcontrol_new volume_controls_prima2[] = { 58 + SOC_DOUBLE_TLV("Speaker Volume", AUDIO_IC_CODEC_CTRL0, 21, 14, 59 + 0x7F, 0, playback_vol_tlv), 60 + SOC_DOUBLE_TLV("Capture Volume", AUDIO_IC_CODEC_CTRL1, 15, 10, 61 + 0x1F, 0, capture_vol_tlv_prima2), 62 + }; 63 + 64 + static struct snd_kcontrol_new left_input_path_controls[] = { 65 + SOC_DAPM_SINGLE("Line Left Switch", AUDIO_IC_CODEC_CTRL1, 6, 1, 0), 66 + SOC_DAPM_SINGLE("Mic Left Switch", AUDIO_IC_CODEC_CTRL1, 3, 1, 0), 67 + }; 68 + 69 + static struct snd_kcontrol_new right_input_path_controls[] = { 70 + SOC_DAPM_SINGLE("Line Right Switch", AUDIO_IC_CODEC_CTRL1, 5, 1, 0), 71 + SOC_DAPM_SINGLE("Mic Right Switch", AUDIO_IC_CODEC_CTRL1, 2, 1, 0), 72 + }; 73 + 74 + static struct snd_kcontrol_new left_dac_to_hp_left_amp_switch_control = 75 + SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 9, 1, 0); 76 + 77 + static struct snd_kcontrol_new left_dac_to_hp_right_amp_switch_control = 78 + SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 8, 1, 0); 79 + 80 + static struct snd_kcontrol_new right_dac_to_hp_left_amp_switch_control = 81 + SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 7, 1, 0); 82 + 83 + static struct snd_kcontrol_new right_dac_to_hp_right_amp_switch_control = 84 + SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 6, 1, 0); 85 + 86 + static struct snd_kcontrol_new left_dac_to_speaker_lineout_switch_control = 87 + SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 11, 1, 0); 88 + 89 + static struct snd_kcontrol_new right_dac_to_speaker_lineout_switch_control = 90 + SOC_DAPM_SINGLE("Switch", AUDIO_IC_CODEC_CTRL0, 10, 1, 0); 91 + 92 + /* After enable adc, Delay 200ms to avoid pop noise */ 93 + static int adc_enable_delay_event(struct snd_soc_dapm_widget *w, 94 + struct snd_kcontrol *kcontrol, int event) 95 + { 96 + switch (event) { 97 + case SND_SOC_DAPM_POST_PMU: 98 + msleep(200); 99 + break; 100 + default: 101 + break; 102 + } 103 + 104 + return 0; 105 + } 106 + 107 + static void enable_and_reset_codec(struct regmap *regmap, 108 + u32 codec_enable_bits, u32 codec_reset_bits) 109 + { 110 + regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, 111 + codec_enable_bits | codec_reset_bits, 112 + codec_enable_bits | ~codec_reset_bits); 113 + msleep(20); 114 + regmap_update_bits(regmap, AUDIO_IC_CODEC_CTRL1, 115 + codec_reset_bits, codec_reset_bits); 116 + } 117 + 118 + static int atlas6_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, 119 + struct snd_kcontrol *kcontrol, int event) 120 + { 121 + #define ATLAS6_CODEC_ENABLE_BITS (1 << 29) 122 + #define ATLAS6_CODEC_RESET_BITS (1 << 28) 123 + struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev); 124 + switch (event) { 125 + case SND_SOC_DAPM_PRE_PMU: 126 + enable_and_reset_codec(sirf_audio_codec->regmap, 127 + ATLAS6_CODEC_ENABLE_BITS, ATLAS6_CODEC_RESET_BITS); 128 + break; 129 + case SND_SOC_DAPM_POST_PMD: 130 + regmap_update_bits(sirf_audio_codec->regmap, 131 + AUDIO_IC_CODEC_CTRL1, ATLAS6_CODEC_ENABLE_BITS, 132 + ~ATLAS6_CODEC_ENABLE_BITS); 133 + break; 134 + default: 135 + break; 136 + } 137 + 138 + return 0; 139 + } 140 + 141 + static int prima2_codec_enable_and_reset_event(struct snd_soc_dapm_widget *w, 142 + struct snd_kcontrol *kcontrol, int event) 143 + { 144 + #define PRIMA2_CODEC_ENABLE_BITS (1 << 27) 145 + #define PRIMA2_CODEC_RESET_BITS (1 << 26) 146 + struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(w->codec->dev); 147 + switch (event) { 148 + case SND_SOC_DAPM_POST_PMU: 149 + enable_and_reset_codec(sirf_audio_codec->regmap, 150 + PRIMA2_CODEC_ENABLE_BITS, PRIMA2_CODEC_RESET_BITS); 151 + break; 152 + case SND_SOC_DAPM_POST_PMD: 153 + regmap_update_bits(sirf_audio_codec->regmap, 154 + AUDIO_IC_CODEC_CTRL1, PRIMA2_CODEC_ENABLE_BITS, 155 + ~PRIMA2_CODEC_ENABLE_BITS); 156 + break; 157 + default: 158 + break; 159 + } 160 + 161 + return 0; 162 + } 163 + 164 + static const struct snd_soc_dapm_widget atlas6_output_driver_dapm_widgets[] = { 165 + SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, 166 + 25, 0, NULL, 0), 167 + SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, 168 + 26, 0, NULL, 0), 169 + SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, 170 + 27, 0, NULL, 0), 171 + }; 172 + 173 + static const struct snd_soc_dapm_widget prima2_output_driver_dapm_widgets[] = { 174 + SND_SOC_DAPM_OUT_DRV("HP Left Driver", AUDIO_IC_CODEC_CTRL1, 175 + 23, 0, NULL, 0), 176 + SND_SOC_DAPM_OUT_DRV("HP Right Driver", AUDIO_IC_CODEC_CTRL1, 177 + 24, 0, NULL, 0), 178 + SND_SOC_DAPM_OUT_DRV("Speaker Driver", AUDIO_IC_CODEC_CTRL1, 179 + 25, 0, NULL, 0), 180 + }; 181 + 182 + static const struct snd_soc_dapm_widget atlas6_codec_clock_dapm_widget = 183 + SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, 184 + atlas6_codec_enable_and_reset_event, 185 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); 186 + 187 + static const struct snd_soc_dapm_widget prima2_codec_clock_dapm_widget = 188 + SND_SOC_DAPM_SUPPLY("codecclk", SND_SOC_NOPM, 0, 0, 189 + prima2_codec_enable_and_reset_event, 190 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD); 191 + 192 + static const struct snd_soc_dapm_widget sirf_audio_codec_dapm_widgets[] = { 193 + SND_SOC_DAPM_DAC("DAC left", NULL, AUDIO_IC_CODEC_CTRL0, 1, 0), 194 + SND_SOC_DAPM_DAC("DAC right", NULL, AUDIO_IC_CODEC_CTRL0, 0, 0), 195 + SND_SOC_DAPM_SWITCH("Left dac to hp left amp", SND_SOC_NOPM, 0, 0, 196 + &left_dac_to_hp_left_amp_switch_control), 197 + SND_SOC_DAPM_SWITCH("Left dac to hp right amp", SND_SOC_NOPM, 0, 0, 198 + &left_dac_to_hp_right_amp_switch_control), 199 + SND_SOC_DAPM_SWITCH("Right dac to hp left amp", SND_SOC_NOPM, 0, 0, 200 + &right_dac_to_hp_left_amp_switch_control), 201 + SND_SOC_DAPM_SWITCH("Right dac to hp right amp", SND_SOC_NOPM, 0, 0, 202 + &right_dac_to_hp_right_amp_switch_control), 203 + SND_SOC_DAPM_OUT_DRV("HP amp left driver", AUDIO_IC_CODEC_CTRL0, 3, 0, 204 + NULL, 0), 205 + SND_SOC_DAPM_OUT_DRV("HP amp right driver", AUDIO_IC_CODEC_CTRL0, 3, 0, 206 + NULL, 0), 207 + 208 + SND_SOC_DAPM_SWITCH("Left dac to speaker lineout", SND_SOC_NOPM, 0, 0, 209 + &left_dac_to_speaker_lineout_switch_control), 210 + SND_SOC_DAPM_SWITCH("Right dac to speaker lineout", SND_SOC_NOPM, 0, 0, 211 + &right_dac_to_speaker_lineout_switch_control), 212 + SND_SOC_DAPM_OUT_DRV("Speaker amp driver", AUDIO_IC_CODEC_CTRL0, 4, 0, 213 + NULL, 0), 214 + 215 + SND_SOC_DAPM_OUTPUT("HPOUTL"), 216 + SND_SOC_DAPM_OUTPUT("HPOUTR"), 217 + SND_SOC_DAPM_OUTPUT("SPKOUT"), 218 + 219 + SND_SOC_DAPM_ADC_E("ADC left", NULL, AUDIO_IC_CODEC_CTRL1, 8, 0, 220 + adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), 221 + SND_SOC_DAPM_ADC_E("ADC right", NULL, AUDIO_IC_CODEC_CTRL1, 7, 0, 222 + adc_enable_delay_event, SND_SOC_DAPM_POST_PMU), 223 + SND_SOC_DAPM_MIXER("Left PGA mixer", AUDIO_IC_CODEC_CTRL1, 1, 0, 224 + &left_input_path_controls[0], 225 + ARRAY_SIZE(left_input_path_controls)), 226 + SND_SOC_DAPM_MIXER("Right PGA mixer", AUDIO_IC_CODEC_CTRL1, 0, 0, 227 + &right_input_path_controls[0], 228 + ARRAY_SIZE(right_input_path_controls)), 229 + 230 + SND_SOC_DAPM_MUX("Mic input mode mux", SND_SOC_NOPM, 0, 0, 231 + &sirf_audio_codec_input_mode_control), 232 + SND_SOC_DAPM_MICBIAS("Mic Bias", AUDIO_IC_CODEC_PWR, 3, 0), 233 + SND_SOC_DAPM_INPUT("MICIN1"), 234 + SND_SOC_DAPM_INPUT("MICIN2"), 235 + SND_SOC_DAPM_INPUT("LINEIN1"), 236 + SND_SOC_DAPM_INPUT("LINEIN2"), 237 + 238 + SND_SOC_DAPM_SUPPLY("HSL Phase Opposite", AUDIO_IC_CODEC_CTRL0, 239 + 30, 0, NULL, 0), 240 + }; 241 + 242 + static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { 243 + {"SPKOUT", NULL, "Speaker Driver"}, 244 + {"Speaker Driver", NULL, "Speaker amp driver"}, 245 + {"Speaker amp driver", NULL, "Left dac to speaker lineout"}, 246 + {"Speaker amp driver", NULL, "Right dac to speaker lineout"}, 247 + {"Left dac to speaker lineout", "Switch", "DAC left"}, 248 + {"Right dac to speaker lineout", "Switch", "DAC right"}, 249 + {"HPOUTL", NULL, "HP Left Driver"}, 250 + {"HPOUTR", NULL, "HP Right Driver"}, 251 + {"HP Left Driver", NULL, "HP amp left driver"}, 252 + {"HP Right Driver", NULL, "HP amp right driver"}, 253 + {"HP amp left driver", NULL, "Right dac to hp left amp"}, 254 + {"HP amp right driver", NULL , "Right dac to hp right amp"}, 255 + {"HP amp left driver", NULL, "Left dac to hp left amp"}, 256 + {"HP amp right driver", NULL , "Right dac to hp right amp"}, 257 + {"Right dac to hp left amp", "Switch", "DAC left"}, 258 + {"Right dac to hp right amp", "Switch", "DAC right"}, 259 + {"Left dac to hp left amp", "Switch", "DAC left"}, 260 + {"Left dac to hp right amp", "Switch", "DAC right"}, 261 + {"DAC left", NULL, "codecclk"}, 262 + {"DAC right", NULL, "codecclk"}, 263 + {"DAC left", NULL, "Playback"}, 264 + {"DAC right", NULL, "Playback"}, 265 + {"DAC left", NULL, "HSL Phase Opposite"}, 266 + {"DAC right", NULL, "HSL Phase Opposite"}, 267 + 268 + {"Capture", NULL, "ADC left"}, 269 + {"Capture", NULL, "ADC right"}, 270 + {"ADC left", NULL, "codecclk"}, 271 + {"ADC right", NULL, "codecclk"}, 272 + {"ADC left", NULL, "Left PGA mixer"}, 273 + {"ADC right", NULL, "Right PGA mixer"}, 274 + {"Left PGA mixer", "Line Left Switch", "LINEIN2"}, 275 + {"Right PGA mixer", "Line Right Switch", "LINEIN1"}, 276 + {"Left PGA mixer", "Mic Left Switch", "MICIN2"}, 277 + {"Right PGA mixer", "Mic Right Switch", "Mic input mode mux"}, 278 + {"Mic input mode mux", "Single-ended", "MICIN1"}, 279 + {"Mic input mode mux", "Differential", "MICIN1"}, 280 + }; 281 + 282 + static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, 283 + int cmd, 284 + struct snd_soc_dai *dai) 285 + { 286 + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 287 + struct snd_soc_codec *codec = dai->codec; 288 + u32 val = 0; 289 + 290 + /* 291 + * This is a workaround, When stop playback, 292 + * need disable HP amp, avoid the current noise. 293 + */ 294 + switch (cmd) { 295 + case SNDRV_PCM_TRIGGER_STOP: 296 + case SNDRV_PCM_TRIGGER_SUSPEND: 297 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 298 + break; 299 + case SNDRV_PCM_TRIGGER_START: 300 + case SNDRV_PCM_TRIGGER_RESUME: 301 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 302 + if (playback) 303 + val = IC_HSLEN | IC_HSREN; 304 + break; 305 + default: 306 + return -EINVAL; 307 + } 308 + 309 + if (playback) 310 + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, 311 + IC_HSLEN | IC_HSREN, val); 312 + return 0; 313 + } 314 + 315 + struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { 316 + .trigger = sirf_audio_codec_trigger, 317 + }; 318 + 319 + struct snd_soc_dai_driver sirf_audio_codec_dai = { 320 + .name = "sirf-audio-codec", 321 + .playback = { 322 + .stream_name = "Playback", 323 + .channels_min = 2, 324 + .channels_max = 2, 325 + .rates = SNDRV_PCM_RATE_48000, 326 + .formats = SNDRV_PCM_FMTBIT_S16_LE, 327 + }, 328 + .capture = { 329 + .stream_name = "Capture", 330 + .channels_min = 1, 331 + .channels_max = 2, 332 + .rates = SNDRV_PCM_RATE_48000, 333 + .formats = SNDRV_PCM_FMTBIT_S16_LE, 334 + }, 335 + .ops = &sirf_audio_codec_dai_ops, 336 + }; 337 + 338 + static int sirf_audio_codec_probe(struct snd_soc_codec *codec) 339 + { 340 + int ret; 341 + struct snd_soc_dapm_context *dapm = &codec->dapm; 342 + struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); 343 + 344 + pm_runtime_enable(codec->dev); 345 + codec->control_data = sirf_audio_codec->regmap; 346 + 347 + ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); 348 + if (ret != 0) { 349 + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 350 + return ret; 351 + } 352 + 353 + if (of_device_is_compatible(codec->dev->of_node, "sirf,prima2-audio-codec")) { 354 + snd_soc_dapm_new_controls(dapm, 355 + prima2_output_driver_dapm_widgets, 356 + ARRAY_SIZE(prima2_output_driver_dapm_widgets)); 357 + snd_soc_dapm_new_controls(dapm, 358 + &prima2_codec_clock_dapm_widget, 1); 359 + return snd_soc_add_codec_controls(codec, 360 + volume_controls_prima2, 361 + ARRAY_SIZE(volume_controls_prima2)); 362 + } 363 + if (of_device_is_compatible(codec->dev->of_node, "sirf,atlas6-audio-codec")) { 364 + snd_soc_dapm_new_controls(dapm, 365 + atlas6_output_driver_dapm_widgets, 366 + ARRAY_SIZE(atlas6_output_driver_dapm_widgets)); 367 + snd_soc_dapm_new_controls(dapm, 368 + &atlas6_codec_clock_dapm_widget, 1); 369 + return snd_soc_add_codec_controls(codec, 370 + volume_controls_atlas6, 371 + ARRAY_SIZE(volume_controls_atlas6)); 372 + } 373 + 374 + return -EINVAL; 375 + } 376 + 377 + static int sirf_audio_codec_remove(struct snd_soc_codec *codec) 378 + { 379 + pm_runtime_disable(codec->dev); 380 + return 0; 381 + } 382 + 383 + static struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = { 384 + .probe = sirf_audio_codec_probe, 385 + .remove = sirf_audio_codec_remove, 386 + .dapm_widgets = sirf_audio_codec_dapm_widgets, 387 + .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), 388 + .dapm_routes = sirf_audio_codec_map, 389 + .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), 390 + .idle_bias_off = true, 391 + }; 392 + 393 + static const struct of_device_id sirf_audio_codec_of_match[] = { 394 + { .compatible = "sirf,prima2-audio-codec" }, 395 + { .compatible = "sirf,atlas6-audio-codec" }, 396 + {} 397 + }; 398 + MODULE_DEVICE_TABLE(of, sirf_audio_codec_of_match); 399 + 400 + static const struct regmap_config sirf_audio_codec_regmap_config = { 401 + .reg_bits = 32, 402 + .reg_stride = 4, 403 + .val_bits = 32, 404 + .max_register = AUDIO_IC_CODEC_CTRL3, 405 + .cache_type = REGCACHE_NONE, 406 + }; 407 + 408 + static int sirf_audio_codec_driver_probe(struct platform_device *pdev) 409 + { 410 + int ret; 411 + struct sirf_audio_codec *sirf_audio_codec; 412 + void __iomem *base; 413 + struct resource *mem_res; 414 + const struct of_device_id *match; 415 + 416 + match = of_match_node(sirf_audio_codec_of_match, pdev->dev.of_node); 417 + 418 + sirf_audio_codec = devm_kzalloc(&pdev->dev, 419 + sizeof(struct sirf_audio_codec), GFP_KERNEL); 420 + if (!sirf_audio_codec) 421 + return -ENOMEM; 422 + 423 + platform_set_drvdata(pdev, sirf_audio_codec); 424 + 425 + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 426 + base = devm_ioremap_resource(&pdev->dev, mem_res); 427 + if (base == NULL) 428 + return -ENOMEM; 429 + 430 + sirf_audio_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, 431 + &sirf_audio_codec_regmap_config); 432 + if (IS_ERR(sirf_audio_codec->regmap)) 433 + return PTR_ERR(sirf_audio_codec->regmap); 434 + 435 + sirf_audio_codec->clk = devm_clk_get(&pdev->dev, NULL); 436 + if (IS_ERR(sirf_audio_codec->clk)) { 437 + dev_err(&pdev->dev, "Get clock failed.\n"); 438 + return PTR_ERR(sirf_audio_codec->clk); 439 + } 440 + 441 + ret = clk_prepare_enable(sirf_audio_codec->clk); 442 + if (ret) { 443 + dev_err(&pdev->dev, "Enable clock failed.\n"); 444 + return ret; 445 + } 446 + 447 + ret = snd_soc_register_codec(&(pdev->dev), 448 + &soc_codec_device_sirf_audio_codec, 449 + &sirf_audio_codec_dai, 1); 450 + if (ret) { 451 + dev_err(&pdev->dev, "Register Audio Codec dai failed.\n"); 452 + goto err_clk_put; 453 + } 454 + 455 + /* 456 + * Always open charge pump, if not, when the charge pump closed the 457 + * adc will not stable 458 + */ 459 + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, 460 + IC_CPFREQ, IC_CPFREQ); 461 + 462 + if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas6-audio-codec")) 463 + regmap_update_bits(sirf_audio_codec->regmap, 464 + AUDIO_IC_CODEC_CTRL0, IC_CPEN, IC_CPEN); 465 + return 0; 466 + 467 + err_clk_put: 468 + clk_disable_unprepare(sirf_audio_codec->clk); 469 + return ret; 470 + } 471 + 472 + static int sirf_audio_codec_driver_remove(struct platform_device *pdev) 473 + { 474 + struct sirf_audio_codec *sirf_audio_codec = platform_get_drvdata(pdev); 475 + 476 + clk_disable_unprepare(sirf_audio_codec->clk); 477 + snd_soc_unregister_codec(&(pdev->dev)); 478 + 479 + return 0; 480 + } 481 + 482 + #ifdef CONFIG_PM_SLEEP 483 + static int sirf_audio_codec_suspend(struct device *dev) 484 + { 485 + struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); 486 + 487 + regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, 488 + &sirf_audio_codec->reg_ctrl0); 489 + regmap_read(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, 490 + &sirf_audio_codec->reg_ctrl1); 491 + clk_disable_unprepare(sirf_audio_codec->clk); 492 + 493 + return 0; 494 + } 495 + 496 + static int sirf_audio_codec_resume(struct device *dev) 497 + { 498 + struct sirf_audio_codec *sirf_audio_codec = dev_get_drvdata(dev); 499 + int ret; 500 + 501 + ret = clk_prepare_enable(sirf_audio_codec->clk); 502 + if (ret) 503 + return ret; 504 + 505 + regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL0, 506 + sirf_audio_codec->reg_ctrl0); 507 + regmap_write(sirf_audio_codec->regmap, AUDIO_IC_CODEC_CTRL1, 508 + sirf_audio_codec->reg_ctrl1); 509 + 510 + return 0; 511 + } 512 + #endif 513 + 514 + static const struct dev_pm_ops sirf_audio_codec_pm_ops = { 515 + SET_SYSTEM_SLEEP_PM_OPS(sirf_audio_codec_suspend, sirf_audio_codec_resume) 516 + }; 517 + 518 + static struct platform_driver sirf_audio_codec_driver = { 519 + .driver = { 520 + .name = "sirf-audio-codec", 521 + .owner = THIS_MODULE, 522 + .of_match_table = sirf_audio_codec_of_match, 523 + .pm = &sirf_audio_codec_pm_ops, 524 + }, 525 + .probe = sirf_audio_codec_driver_probe, 526 + .remove = sirf_audio_codec_driver_remove, 527 + }; 528 + 529 + module_platform_driver(sirf_audio_codec_driver); 530 + 531 + MODULE_DESCRIPTION("SiRF audio codec driver"); 532 + MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); 533 + MODULE_LICENSE("GPL v2");
+75
sound/soc/codecs/sirf-audio-codec.h
··· 1 + /* 2 + * SiRF inner codec controllers define 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + 9 + #ifndef _SIRF_AUDIO_CODEC_H 10 + #define _SIRF_AUDIO_CODEC_H 11 + 12 + 13 + #define AUDIO_IC_CODEC_PWR (0x00E0) 14 + #define AUDIO_IC_CODEC_CTRL0 (0x00E4) 15 + #define AUDIO_IC_CODEC_CTRL1 (0x00E8) 16 + #define AUDIO_IC_CODEC_CTRL2 (0x00EC) 17 + #define AUDIO_IC_CODEC_CTRL3 (0x00F0) 18 + 19 + #define MICBIASEN (1 << 3) 20 + 21 + #define IC_RDACEN (1 << 0) 22 + #define IC_LDACEN (1 << 1) 23 + #define IC_HSREN (1 << 2) 24 + #define IC_HSLEN (1 << 3) 25 + #define IC_SPEN (1 << 4) 26 + #define IC_CPEN (1 << 5) 27 + 28 + #define IC_HPRSELR (1 << 6) 29 + #define IC_HPLSELR (1 << 7) 30 + #define IC_HPRSELL (1 << 8) 31 + #define IC_HPLSELL (1 << 9) 32 + #define IC_SPSELR (1 << 10) 33 + #define IC_SPSELL (1 << 11) 34 + 35 + #define IC_MONOR (1 << 12) 36 + #define IC_MONOL (1 << 13) 37 + 38 + #define IC_RXOSRSEL (1 << 28) 39 + #define IC_CPFREQ (1 << 29) 40 + #define IC_HSINVEN (1 << 30) 41 + 42 + #define IC_MICINREN (1 << 0) 43 + #define IC_MICINLEN (1 << 1) 44 + #define IC_MICIN1SEL (1 << 2) 45 + #define IC_MICIN2SEL (1 << 3) 46 + #define IC_MICDIFSEL (1 << 4) 47 + #define IC_LINEIN1SEL (1 << 5) 48 + #define IC_LINEIN2SEL (1 << 6) 49 + #define IC_RADCEN (1 << 7) 50 + #define IC_LADCEN (1 << 8) 51 + #define IC_ALM (1 << 9) 52 + 53 + #define IC_DIGMICEN (1 << 22) 54 + #define IC_DIGMICFREQ (1 << 23) 55 + #define IC_ADC14B_12 (1 << 24) 56 + #define IC_FIRDAC_HSL_EN (1 << 25) 57 + #define IC_FIRDAC_HSR_EN (1 << 26) 58 + #define IC_FIRDAC_LOUT_EN (1 << 27) 59 + #define IC_POR (1 << 28) 60 + #define IC_CODEC_CLK_EN (1 << 29) 61 + #define IC_HP_3DB_BOOST (1 << 30) 62 + 63 + #define IC_ADC_LEFT_GAIN_SHIFT 16 64 + #define IC_ADC_RIGHT_GAIN_SHIFT 10 65 + #define IC_ADC_GAIN_MASK 0x3F 66 + #define IC_MIC_MAX_GAIN 0x39 67 + 68 + #define IC_RXPGAR_MASK 0x3F 69 + #define IC_RXPGAR_SHIFT 14 70 + #define IC_RXPGAL_MASK 0x3F 71 + #define IC_RXPGAL_SHIFT 21 72 + #define IC_RXPGAR 0x7B 73 + #define IC_RXPGAL 0x7B 74 + 75 + #endif /*__SIRF_AUDIO_CODEC_H*/
+22 -22
sound/soc/codecs/sn95031.c
··· 312 312 /* mux controls */ 313 313 static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" }; 314 314 315 - static const struct soc_enum sn95031_micl_enum = 316 - SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts); 315 + static SOC_ENUM_SINGLE_DECL(sn95031_micl_enum, 316 + SN95031_ADCCONFIG, 1, sn95031_mic_texts); 317 317 318 318 static const struct snd_kcontrol_new sn95031_micl_mux_control = 319 319 SOC_DAPM_ENUM("Route", sn95031_micl_enum); 320 320 321 - static const struct soc_enum sn95031_micr_enum = 322 - SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts); 321 + static SOC_ENUM_SINGLE_DECL(sn95031_micr_enum, 322 + SN95031_ADCCONFIG, 3, sn95031_mic_texts); 323 323 324 324 static const struct snd_kcontrol_new sn95031_micr_mux_control = 325 325 SOC_DAPM_ENUM("Route", sn95031_micr_enum); ··· 328 328 "DMIC4", "DMIC5", "DMIC6", 329 329 "ADC Left", "ADC Right" }; 330 330 331 - static const struct soc_enum sn95031_input1_enum = 332 - SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts); 331 + static SOC_ENUM_SINGLE_DECL(sn95031_input1_enum, 332 + SN95031_AUDIOMUX12, 0, sn95031_input_texts); 333 333 334 334 static const struct snd_kcontrol_new sn95031_input1_mux_control = 335 335 SOC_DAPM_ENUM("Route", sn95031_input1_enum); 336 336 337 - static const struct soc_enum sn95031_input2_enum = 338 - SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts); 337 + static SOC_ENUM_SINGLE_DECL(sn95031_input2_enum, 338 + SN95031_AUDIOMUX12, 4, sn95031_input_texts); 339 339 340 340 static const struct snd_kcontrol_new sn95031_input2_mux_control = 341 341 SOC_DAPM_ENUM("Route", sn95031_input2_enum); 342 342 343 - static const struct soc_enum sn95031_input3_enum = 344 - SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts); 343 + static SOC_ENUM_SINGLE_DECL(sn95031_input3_enum, 344 + SN95031_AUDIOMUX34, 0, sn95031_input_texts); 345 345 346 346 static const struct snd_kcontrol_new sn95031_input3_mux_control = 347 347 SOC_DAPM_ENUM("Route", sn95031_input3_enum); 348 348 349 - static const struct soc_enum sn95031_input4_enum = 350 - SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts); 349 + static SOC_ENUM_SINGLE_DECL(sn95031_input4_enum, 350 + SN95031_AUDIOMUX34, 4, sn95031_input_texts); 351 351 352 352 static const struct snd_kcontrol_new sn95031_input4_mux_control = 353 353 SOC_DAPM_ENUM("Route", sn95031_input4_enum); ··· 359 359 /* 0dB to 30dB in 10dB steps */ 360 360 static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0); 361 361 362 - static const struct soc_enum sn95031_micmode1_enum = 363 - SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text); 364 - static const struct soc_enum sn95031_micmode2_enum = 365 - SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text); 362 + static SOC_ENUM_SINGLE_DECL(sn95031_micmode1_enum, 363 + SN95031_MICAMP1, 1, sn95031_micmode_text); 364 + static SOC_ENUM_SINGLE_DECL(sn95031_micmode2_enum, 365 + SN95031_MICAMP2, 1, sn95031_micmode_text); 366 366 367 367 static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"}; 368 368 369 - static const struct soc_enum sn95031_dmic12_cfg_enum = 370 - SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text); 371 - static const struct soc_enum sn95031_dmic34_cfg_enum = 372 - SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text); 373 - static const struct soc_enum sn95031_dmic56_cfg_enum = 374 - SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text); 369 + static SOC_ENUM_SINGLE_DECL(sn95031_dmic12_cfg_enum, 370 + SN95031_DMICMUX, 0, sn95031_dmic_cfg_text); 371 + static SOC_ENUM_SINGLE_DECL(sn95031_dmic34_cfg_enum, 372 + SN95031_DMICMUX, 1, sn95031_dmic_cfg_text); 373 + static SOC_ENUM_SINGLE_DECL(sn95031_dmic56_cfg_enum, 374 + SN95031_DMICMUX, 2, sn95031_dmic_cfg_text); 375 375 376 376 static const struct snd_kcontrol_new sn95031_snd_controls[] = { 377 377 SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
+57
sound/soc/codecs/ssm2602-i2c.c
··· 1 + /* 2 + * SSM2602/SSM2603/SSM2604 I2C audio driver 3 + * 4 + * Copyright 2014 Analog Devices Inc. 5 + * 6 + * Licensed under the GPL-2. 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/i2c.h> 11 + #include <linux/regmap.h> 12 + 13 + #include <sound/soc.h> 14 + 15 + #include "ssm2602.h" 16 + 17 + /* 18 + * ssm2602 2 wire address is determined by GPIO5 19 + * state during powerup. 20 + * low = 0x1a 21 + * high = 0x1b 22 + */ 23 + static int ssm2602_i2c_probe(struct i2c_client *client, 24 + const struct i2c_device_id *id) 25 + { 26 + return ssm2602_probe(&client->dev, id->driver_data, 27 + devm_regmap_init_i2c(client, &ssm2602_regmap_config)); 28 + } 29 + 30 + static int ssm2602_i2c_remove(struct i2c_client *client) 31 + { 32 + snd_soc_unregister_codec(&client->dev); 33 + return 0; 34 + } 35 + 36 + static const struct i2c_device_id ssm2602_i2c_id[] = { 37 + { "ssm2602", SSM2602 }, 38 + { "ssm2603", SSM2602 }, 39 + { "ssm2604", SSM2604 }, 40 + { } 41 + }; 42 + MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 43 + 44 + static struct i2c_driver ssm2602_i2c_driver = { 45 + .driver = { 46 + .name = "ssm2602", 47 + .owner = THIS_MODULE, 48 + }, 49 + .probe = ssm2602_i2c_probe, 50 + .remove = ssm2602_i2c_remove, 51 + .id_table = ssm2602_i2c_id, 52 + }; 53 + module_i2c_driver(ssm2602_i2c_driver); 54 + 55 + MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 I2C driver"); 56 + MODULE_AUTHOR("Cliff Cai"); 57 + MODULE_LICENSE("GPL");
+41
sound/soc/codecs/ssm2602-spi.c
··· 1 + /* 2 + * SSM2602 SPI audio driver 3 + * 4 + * Copyright 2014 Analog Devices Inc. 5 + * 6 + * Licensed under the GPL-2. 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/spi/spi.h> 11 + #include <linux/regmap.h> 12 + 13 + #include <sound/soc.h> 14 + 15 + #include "ssm2602.h" 16 + 17 + static int ssm2602_spi_probe(struct spi_device *spi) 18 + { 19 + return ssm2602_probe(&spi->dev, SSM2602, 20 + devm_regmap_init_spi(spi, &ssm2602_regmap_config)); 21 + } 22 + 23 + static int ssm2602_spi_remove(struct spi_device *spi) 24 + { 25 + snd_soc_unregister_codec(&spi->dev); 26 + return 0; 27 + } 28 + 29 + static struct spi_driver ssm2602_spi_driver = { 30 + .driver = { 31 + .name = "ssm2602", 32 + .owner = THIS_MODULE, 33 + }, 34 + .probe = ssm2602_spi_probe, 35 + .remove = ssm2602_spi_remove, 36 + }; 37 + module_spi_driver(ssm2602_spi_driver); 38 + 39 + MODULE_DESCRIPTION("ASoC SSM2602 SPI driver"); 40 + MODULE_AUTHOR("Cliff Cai"); 41 + MODULE_LICENSE("GPL");
+28 -145
sound/soc/codecs/ssm2602.c
··· 27 27 */ 28 28 29 29 #include <linux/module.h> 30 - #include <linux/moduleparam.h> 31 - #include <linux/init.h> 32 - #include <linux/delay.h> 33 - #include <linux/pm.h> 34 - #include <linux/i2c.h> 35 - #include <linux/spi/spi.h> 36 30 #include <linux/regmap.h> 37 31 #include <linux/slab.h> 38 - #include <sound/core.h> 32 + 39 33 #include <sound/pcm.h> 40 34 #include <sound/pcm_params.h> 41 35 #include <sound/soc.h> 42 - #include <sound/initval.h> 43 36 #include <sound/tlv.h> 44 37 45 38 #include "ssm2602.h" 46 39 47 - enum ssm2602_type { 48 - SSM2602, 49 - SSM2604, 50 - }; 51 - 52 40 /* codec private data */ 53 41 struct ssm2602_priv { 54 42 unsigned int sysclk; 55 - struct snd_pcm_hw_constraint_list *sysclk_constraints; 43 + const struct snd_pcm_hw_constraint_list *sysclk_constraints; 56 44 57 45 struct regmap *regmap; 58 46 ··· 63 75 64 76 /*Appending several "None"s just for OSS mixer use*/ 65 77 static const char *ssm2602_input_select[] = { 66 - "Line", "Mic", "None", "None", "None", 67 - "None", "None", "None", 78 + "Line", "Mic", 68 79 }; 69 80 70 81 static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 71 82 72 83 static const struct soc_enum ssm2602_enum[] = { 73 - SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select), 74 - SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph), 84 + SOC_ENUM_SINGLE(SSM2602_APANA, 2, ARRAY_SIZE(ssm2602_input_select), 85 + ssm2602_input_select), 86 + SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, ARRAY_SIZE(ssm2602_deemph), 87 + ssm2602_deemph), 75 88 }; 76 89 77 90 static const unsigned int ssm260x_outmix_tlv[] = { ··· 186 197 8000, 16000, 32000, 48000, 96000, 187 198 }; 188 199 189 - static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { 200 + static const struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { 190 201 .list = ssm2602_rates_12288000, 191 202 .count = ARRAY_SIZE(ssm2602_rates_12288000), 192 203 }; ··· 195 206 8000, 44100, 88200, 196 207 }; 197 208 198 - static struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { 209 + static const struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { 199 210 .list = ssm2602_rates_11289600, 200 211 .count = ARRAY_SIZE(ssm2602_rates_11289600), 201 212 }; ··· 518 529 return 0; 519 530 } 520 531 521 - static int ssm2602_probe(struct snd_soc_codec *codec) 532 + static int ssm2602_codec_probe(struct snd_soc_codec *codec) 522 533 { 523 534 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 524 535 struct snd_soc_dapm_context *dapm = &codec->dapm; ··· 543 554 ARRAY_SIZE(ssm2602_routes)); 544 555 } 545 556 546 - static int ssm2604_probe(struct snd_soc_codec *codec) 557 + static int ssm2604_codec_probe(struct snd_soc_codec *codec) 547 558 { 548 559 struct snd_soc_dapm_context *dapm = &codec->dapm; 549 560 int ret; ··· 557 568 ARRAY_SIZE(ssm2604_routes)); 558 569 } 559 570 560 - static int ssm260x_probe(struct snd_soc_codec *codec) 571 + static int ssm260x_codec_probe(struct snd_soc_codec *codec) 561 572 { 562 573 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 563 574 int ret; ··· 586 597 587 598 switch (ssm2602->type) { 588 599 case SSM2602: 589 - ret = ssm2602_probe(codec); 600 + ret = ssm2602_codec_probe(codec); 590 601 break; 591 602 case SSM2604: 592 - ret = ssm2604_probe(codec); 603 + ret = ssm2604_codec_probe(codec); 593 604 break; 594 605 } 595 606 ··· 609 620 } 610 621 611 622 static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { 612 - .probe = ssm260x_probe, 623 + .probe = ssm260x_codec_probe, 613 624 .remove = ssm2602_remove, 614 625 .suspend = ssm2602_suspend, 615 626 .resume = ssm2602_resume, ··· 628 639 return reg == SSM2602_RESET; 629 640 } 630 641 631 - static const struct regmap_config ssm2602_regmap_config = { 642 + const struct regmap_config ssm2602_regmap_config = { 632 643 .val_bits = 9, 633 644 .reg_bits = 7, 634 645 ··· 639 650 .reg_defaults_raw = ssm2602_reg, 640 651 .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), 641 652 }; 653 + EXPORT_SYMBOL_GPL(ssm2602_regmap_config); 642 654 643 - #if defined(CONFIG_SPI_MASTER) 644 - static int ssm2602_spi_probe(struct spi_device *spi) 655 + int ssm2602_probe(struct device *dev, enum ssm2602_type type, 656 + struct regmap *regmap) 645 657 { 646 658 struct ssm2602_priv *ssm2602; 647 - int ret; 648 659 649 - ssm2602 = devm_kzalloc(&spi->dev, sizeof(struct ssm2602_priv), 650 - GFP_KERNEL); 660 + if (IS_ERR(regmap)) 661 + return PTR_ERR(regmap); 662 + 663 + ssm2602 = devm_kzalloc(dev, sizeof(*ssm2602), GFP_KERNEL); 651 664 if (ssm2602 == NULL) 652 665 return -ENOMEM; 653 666 654 - spi_set_drvdata(spi, ssm2602); 667 + dev_set_drvdata(dev, ssm2602); 655 668 ssm2602->type = SSM2602; 669 + ssm2602->regmap = regmap; 656 670 657 - ssm2602->regmap = devm_regmap_init_spi(spi, &ssm2602_regmap_config); 658 - if (IS_ERR(ssm2602->regmap)) 659 - return PTR_ERR(ssm2602->regmap); 660 - 661 - ret = snd_soc_register_codec(&spi->dev, 662 - &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 663 - return ret; 671 + return snd_soc_register_codec(dev, &soc_codec_dev_ssm2602, 672 + &ssm2602_dai, 1); 664 673 } 665 - 666 - static int ssm2602_spi_remove(struct spi_device *spi) 667 - { 668 - snd_soc_unregister_codec(&spi->dev); 669 - return 0; 670 - } 671 - 672 - static struct spi_driver ssm2602_spi_driver = { 673 - .driver = { 674 - .name = "ssm2602", 675 - .owner = THIS_MODULE, 676 - }, 677 - .probe = ssm2602_spi_probe, 678 - .remove = ssm2602_spi_remove, 679 - }; 680 - #endif 681 - 682 - #if IS_ENABLED(CONFIG_I2C) 683 - /* 684 - * ssm2602 2 wire address is determined by GPIO5 685 - * state during powerup. 686 - * low = 0x1a 687 - * high = 0x1b 688 - */ 689 - static int ssm2602_i2c_probe(struct i2c_client *i2c, 690 - const struct i2c_device_id *id) 691 - { 692 - struct ssm2602_priv *ssm2602; 693 - int ret; 694 - 695 - ssm2602 = devm_kzalloc(&i2c->dev, sizeof(struct ssm2602_priv), 696 - GFP_KERNEL); 697 - if (ssm2602 == NULL) 698 - return -ENOMEM; 699 - 700 - i2c_set_clientdata(i2c, ssm2602); 701 - ssm2602->type = id->driver_data; 702 - 703 - ssm2602->regmap = devm_regmap_init_i2c(i2c, &ssm2602_regmap_config); 704 - if (IS_ERR(ssm2602->regmap)) 705 - return PTR_ERR(ssm2602->regmap); 706 - 707 - ret = snd_soc_register_codec(&i2c->dev, 708 - &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 709 - return ret; 710 - } 711 - 712 - static int ssm2602_i2c_remove(struct i2c_client *client) 713 - { 714 - snd_soc_unregister_codec(&client->dev); 715 - return 0; 716 - } 717 - 718 - static const struct i2c_device_id ssm2602_i2c_id[] = { 719 - { "ssm2602", SSM2602 }, 720 - { "ssm2603", SSM2602 }, 721 - { "ssm2604", SSM2604 }, 722 - { } 723 - }; 724 - MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 725 - 726 - /* corgi i2c codec control layer */ 727 - static struct i2c_driver ssm2602_i2c_driver = { 728 - .driver = { 729 - .name = "ssm2602", 730 - .owner = THIS_MODULE, 731 - }, 732 - .probe = ssm2602_i2c_probe, 733 - .remove = ssm2602_i2c_remove, 734 - .id_table = ssm2602_i2c_id, 735 - }; 736 - #endif 737 - 738 - 739 - static int __init ssm2602_modinit(void) 740 - { 741 - int ret = 0; 742 - 743 - #if defined(CONFIG_SPI_MASTER) 744 - ret = spi_register_driver(&ssm2602_spi_driver); 745 - if (ret) 746 - return ret; 747 - #endif 748 - 749 - #if IS_ENABLED(CONFIG_I2C) 750 - ret = i2c_add_driver(&ssm2602_i2c_driver); 751 - if (ret) 752 - return ret; 753 - #endif 754 - 755 - return ret; 756 - } 757 - module_init(ssm2602_modinit); 758 - 759 - static void __exit ssm2602_exit(void) 760 - { 761 - #if defined(CONFIG_SPI_MASTER) 762 - spi_unregister_driver(&ssm2602_spi_driver); 763 - #endif 764 - 765 - #if IS_ENABLED(CONFIG_I2C) 766 - i2c_del_driver(&ssm2602_i2c_driver); 767 - #endif 768 - } 769 - module_exit(ssm2602_exit); 674 + EXPORT_SYMBOL_GPL(ssm2602_probe); 770 675 771 676 MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver"); 772 677 MODULE_AUTHOR("Cliff Cai");
+14
sound/soc/codecs/ssm2602.h
··· 28 28 #ifndef _SSM2602_H 29 29 #define _SSM2602_H 30 30 31 + #include <linux/regmap.h> 32 + 33 + struct device; 34 + 35 + enum ssm2602_type { 36 + SSM2602, 37 + SSM2604, 38 + }; 39 + 40 + extern const struct regmap_config ssm2602_regmap_config; 41 + 42 + int ssm2602_probe(struct device *dev, enum ssm2602_type type, 43 + struct regmap *regmap); 44 + 31 45 /* SSM2602 Codec Register definitions */ 32 46 33 47 #define SSM2602_LINVOL 0x00
+19 -19
sound/soc/codecs/stac9766.c
··· 62 62 static const char *stac9766_boost2[] = {"0dB", "20dB"}; 63 63 static const char *stac9766_stereo_mic[] = {"Off", "On"}; 64 64 65 - static const struct soc_enum stac9766_record_enum = 66 - SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, stac9766_record_mux); 67 - static const struct soc_enum stac9766_mono_enum = 68 - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, stac9766_mono_mux); 69 - static const struct soc_enum stac9766_mic_enum = 70 - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, stac9766_mic_mux); 71 - static const struct soc_enum stac9766_SPDIF_enum = 72 - SOC_ENUM_SINGLE(AC97_STAC_DA_CONTROL, 1, 2, stac9766_SPDIF_mux); 73 - static const struct soc_enum stac9766_popbypass_enum = 74 - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, stac9766_popbypass_mux); 75 - static const struct soc_enum stac9766_record_all_enum = 76 - SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 12, 2, 77 - stac9766_record_all_mux); 78 - static const struct soc_enum stac9766_boost1_enum = 79 - SOC_ENUM_SINGLE(AC97_MIC, 6, 2, stac9766_boost1); /* 0/10dB */ 80 - static const struct soc_enum stac9766_boost2_enum = 81 - SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 2, 2, stac9766_boost2); /* 0/20dB */ 82 - static const struct soc_enum stac9766_stereo_mic_enum = 83 - SOC_ENUM_SINGLE(AC97_STAC_STEREO_MIC, 2, 1, stac9766_stereo_mic); 65 + static SOC_ENUM_DOUBLE_DECL(stac9766_record_enum, 66 + AC97_REC_SEL, 8, 0, stac9766_record_mux); 67 + static SOC_ENUM_SINGLE_DECL(stac9766_mono_enum, 68 + AC97_GENERAL_PURPOSE, 9, stac9766_mono_mux); 69 + static SOC_ENUM_SINGLE_DECL(stac9766_mic_enum, 70 + AC97_GENERAL_PURPOSE, 8, stac9766_mic_mux); 71 + static SOC_ENUM_SINGLE_DECL(stac9766_SPDIF_enum, 72 + AC97_STAC_DA_CONTROL, 1, stac9766_SPDIF_mux); 73 + static SOC_ENUM_SINGLE_DECL(stac9766_popbypass_enum, 74 + AC97_GENERAL_PURPOSE, 15, stac9766_popbypass_mux); 75 + static SOC_ENUM_SINGLE_DECL(stac9766_record_all_enum, 76 + AC97_STAC_ANALOG_SPECIAL, 12, 77 + stac9766_record_all_mux); 78 + static SOC_ENUM_SINGLE_DECL(stac9766_boost1_enum, 79 + AC97_MIC, 6, stac9766_boost1); /* 0/10dB */ 80 + static SOC_ENUM_SINGLE_DECL(stac9766_boost2_enum, 81 + AC97_STAC_ANALOG_SPECIAL, 2, stac9766_boost2); /* 0/20dB */ 82 + static SOC_ENUM_SINGLE_DECL(stac9766_stereo_mic_enum, 83 + AC97_STAC_STEREO_MIC, 2, stac9766_stereo_mic); 84 84 85 85 static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); 86 86 static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250);
+153 -96
sound/soc/generic/simple-card.c
··· 9 9 * published by the Free Software Foundation. 10 10 */ 11 11 #include <linux/clk.h> 12 + #include <linux/device.h> 12 13 #include <linux/module.h> 13 14 #include <linux/of.h> 14 15 #include <linux/platform_device.h> 15 16 #include <linux/string.h> 16 17 #include <sound/simple_card.h> 18 + #include <sound/soc-dai.h> 19 + #include <sound/soc.h> 20 + 21 + struct simple_card_data { 22 + struct snd_soc_card snd_card; 23 + unsigned int daifmt; 24 + struct asoc_simple_dai cpu_dai; 25 + struct asoc_simple_dai codec_dai; 26 + struct snd_soc_dai_link snd_link; 27 + }; 17 28 18 29 static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, 19 - struct asoc_simple_dai *set, 20 - unsigned int daifmt) 30 + struct asoc_simple_dai *set) 21 31 { 22 - int ret = 0; 32 + int ret; 23 33 24 - daifmt |= set->fmt; 25 - 26 - if (daifmt) 27 - ret = snd_soc_dai_set_fmt(dai, daifmt); 28 - 29 - if (ret == -ENOTSUPP) { 30 - dev_dbg(dai->dev, "ASoC: set_fmt is not supported\n"); 31 - ret = 0; 34 + if (set->fmt) { 35 + ret = snd_soc_dai_set_fmt(dai, set->fmt); 36 + if (ret && ret != -ENOTSUPP) { 37 + dev_err(dai->dev, "simple-card: set_fmt error\n"); 38 + goto err; 39 + } 32 40 } 33 41 34 - if (!ret && set->sysclk) 42 + if (set->sysclk) { 35 43 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); 44 + if (ret && ret != -ENOTSUPP) { 45 + dev_err(dai->dev, "simple-card: set_sysclk error\n"); 46 + goto err; 47 + } 48 + } 36 49 50 + if (set->slots) { 51 + ret = snd_soc_dai_set_tdm_slot(dai, 0, 0, 52 + set->slots, 53 + set->slot_width); 54 + if (ret && ret != -ENOTSUPP) { 55 + dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); 56 + goto err; 57 + } 58 + } 59 + 60 + ret = 0; 61 + 62 + err: 37 63 return ret; 38 64 } 39 65 40 66 static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 41 67 { 42 - struct asoc_simple_card_info *info = 68 + struct simple_card_data *priv = 43 69 snd_soc_card_get_drvdata(rtd->card); 44 70 struct snd_soc_dai *codec = rtd->codec_dai; 45 71 struct snd_soc_dai *cpu = rtd->cpu_dai; 46 - unsigned int daifmt = info->daifmt; 47 72 int ret; 48 73 49 - ret = __asoc_simple_card_dai_init(codec, &info->codec_dai, daifmt); 74 + ret = __asoc_simple_card_dai_init(codec, &priv->codec_dai); 50 75 if (ret < 0) 51 76 return ret; 52 77 53 - ret = __asoc_simple_card_dai_init(cpu, &info->cpu_dai, daifmt); 78 + ret = __asoc_simple_card_dai_init(cpu, &priv->cpu_dai); 54 79 if (ret < 0) 55 80 return ret; 56 81 ··· 84 59 85 60 static int 86 61 asoc_simple_card_sub_parse_of(struct device_node *np, 62 + unsigned int daifmt, 87 63 struct asoc_simple_dai *dai, 88 - struct device_node **node) 64 + const struct device_node **p_node, 65 + const char **name) 89 66 { 67 + struct device_node *node; 90 68 struct clk *clk; 91 69 int ret; 92 70 ··· 97 69 * get node via "sound-dai = <&phandle port>" 98 70 * it will be used as xxx_of_node on soc_bind_dai_link() 99 71 */ 100 - *node = of_parse_phandle(np, "sound-dai", 0); 101 - if (!*node) 72 + node = of_parse_phandle(np, "sound-dai", 0); 73 + if (!node) 102 74 return -ENODEV; 75 + *p_node = node; 103 76 104 77 /* get dai->name */ 105 - ret = snd_soc_of_get_dai_name(np, &dai->name); 78 + ret = snd_soc_of_get_dai_name(np, name); 106 79 if (ret < 0) 80 + goto parse_error; 81 + 82 + /* parse TDM slot */ 83 + ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 84 + if (ret) 107 85 goto parse_error; 108 86 109 87 /* ··· 118 84 * and specific "format" if it has 119 85 */ 120 86 dai->fmt = snd_soc_of_parse_daifmt(np, NULL); 87 + dai->fmt |= daifmt; 121 88 122 89 /* 123 90 * dai->sysclk come from ··· 139 104 "system-clock-frequency", 140 105 &dai->sysclk); 141 106 } else { 142 - clk = of_clk_get(*node, 0); 107 + clk = of_clk_get(node, 0); 143 108 if (!IS_ERR(clk)) 144 109 dai->sysclk = clk_get_rate(clk); 145 110 } ··· 147 112 ret = 0; 148 113 149 114 parse_error: 150 - of_node_put(*node); 115 + of_node_put(node); 151 116 152 117 return ret; 153 118 } 154 119 155 120 static int asoc_simple_card_parse_of(struct device_node *node, 156 - struct asoc_simple_card_info *info, 157 - struct device *dev, 158 - struct device_node **of_cpu, 159 - struct device_node **of_codec, 160 - struct device_node **of_platform) 121 + struct simple_card_data *priv, 122 + struct device *dev) 161 123 { 124 + struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; 162 125 struct device_node *np; 163 126 char *name; 164 127 int ret; 165 128 129 + /* parsing the card name from DT */ 130 + snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); 131 + 166 132 /* get CPU/CODEC common format via simple-audio-card,format */ 167 - info->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & 133 + priv->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & 168 134 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); 135 + 136 + /* off-codec widgets */ 137 + if (of_property_read_bool(node, "simple-audio-card,widgets")) { 138 + ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, 139 + "simple-audio-card,widgets"); 140 + if (ret) 141 + return ret; 142 + } 169 143 170 144 /* DAPM routes */ 171 145 if (of_property_read_bool(node, "simple-audio-card,routing")) { 172 - ret = snd_soc_of_parse_audio_routing(&info->snd_card, 146 + ret = snd_soc_of_parse_audio_routing(&priv->snd_card, 173 147 "simple-audio-card,routing"); 174 148 if (ret) 175 149 return ret; ··· 188 144 ret = -EINVAL; 189 145 np = of_get_child_by_name(node, "simple-audio-card,cpu"); 190 146 if (np) 191 - ret = asoc_simple_card_sub_parse_of(np, 192 - &info->cpu_dai, 193 - of_cpu); 147 + ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 148 + &priv->cpu_dai, 149 + &dai_link->cpu_of_node, 150 + &dai_link->cpu_dai_name); 194 151 if (ret < 0) 195 152 return ret; 196 153 ··· 199 154 ret = -EINVAL; 200 155 np = of_get_child_by_name(node, "simple-audio-card,codec"); 201 156 if (np) 202 - ret = asoc_simple_card_sub_parse_of(np, 203 - &info->codec_dai, 204 - of_codec); 157 + ret = asoc_simple_card_sub_parse_of(np, priv->daifmt, 158 + &priv->codec_dai, 159 + &dai_link->codec_of_node, 160 + &dai_link->codec_dai_name); 205 161 if (ret < 0) 206 162 return ret; 207 163 208 - if (!info->cpu_dai.name || !info->codec_dai.name) 164 + if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) 209 165 return -EINVAL; 210 166 211 167 /* card name is created from CPU/CODEC dai name */ 212 168 name = devm_kzalloc(dev, 213 - strlen(info->cpu_dai.name) + 214 - strlen(info->codec_dai.name) + 2, 169 + strlen(dai_link->cpu_dai_name) + 170 + strlen(dai_link->codec_dai_name) + 2, 215 171 GFP_KERNEL); 216 - sprintf(name, "%s-%s", info->cpu_dai.name, info->codec_dai.name); 217 - info->name = info->card = name; 172 + sprintf(name, "%s-%s", dai_link->cpu_dai_name, 173 + dai_link->codec_dai_name); 174 + if (!priv->snd_card.name) 175 + priv->snd_card.name = name; 176 + dai_link->name = dai_link->stream_name = name; 218 177 219 178 /* simple-card assumes platform == cpu */ 220 - *of_platform = *of_cpu; 179 + dai_link->platform_of_node = dai_link->cpu_of_node; 221 180 222 - dev_dbg(dev, "card-name : %s\n", info->card); 223 - dev_dbg(dev, "platform : %04x\n", info->daifmt); 181 + dev_dbg(dev, "card-name : %s\n", name); 182 + dev_dbg(dev, "platform : %04x\n", priv->daifmt); 224 183 dev_dbg(dev, "cpu : %s / %04x / %d\n", 225 - info->cpu_dai.name, 226 - info->cpu_dai.fmt, 227 - info->cpu_dai.sysclk); 184 + dai_link->cpu_dai_name, 185 + priv->cpu_dai.fmt, 186 + priv->cpu_dai.sysclk); 228 187 dev_dbg(dev, "codec : %s / %04x / %d\n", 229 - info->codec_dai.name, 230 - info->codec_dai.fmt, 231 - info->codec_dai.sysclk); 188 + dai_link->codec_dai_name, 189 + priv->codec_dai.fmt, 190 + priv->codec_dai.sysclk); 191 + 192 + /* 193 + * soc_bind_dai_link() will check cpu name 194 + * after of_node matching if dai_link has cpu_dai_name. 195 + * but, it will never match if name was created by fmt_single_name() 196 + * remove cpu_dai_name to escape name matching. 197 + * see 198 + * fmt_single_name() 199 + * fmt_multiple_name() 200 + */ 201 + dai_link->cpu_dai_name = NULL; 232 202 233 203 return 0; 234 204 } 235 205 236 206 static int asoc_simple_card_probe(struct platform_device *pdev) 237 207 { 238 - struct asoc_simple_card_info *cinfo; 208 + struct simple_card_data *priv; 209 + struct snd_soc_dai_link *dai_link; 239 210 struct device_node *np = pdev->dev.of_node; 240 - struct device_node *of_cpu, *of_codec, *of_platform; 241 211 struct device *dev = &pdev->dev; 242 212 int ret; 243 213 244 - cinfo = NULL; 245 - of_cpu = NULL; 246 - of_codec = NULL; 247 - of_platform = NULL; 248 - 249 - cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL); 250 - if (!cinfo) 214 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 215 + if (!priv) 251 216 return -ENOMEM; 252 217 253 - if (np && of_device_is_available(np)) { 254 - cinfo->snd_card.dev = dev; 218 + /* 219 + * init snd_soc_card 220 + */ 221 + priv->snd_card.owner = THIS_MODULE; 222 + priv->snd_card.dev = dev; 223 + dai_link = &priv->snd_link; 224 + priv->snd_card.dai_link = dai_link; 225 + priv->snd_card.num_links = 1; 255 226 256 - ret = asoc_simple_card_parse_of(np, cinfo, dev, 257 - &of_cpu, 258 - &of_codec, 259 - &of_platform); 227 + if (np && of_device_is_available(np)) { 228 + 229 + ret = asoc_simple_card_parse_of(np, priv, dev); 260 230 if (ret < 0) { 261 231 if (ret != -EPROBE_DEFER) 262 232 dev_err(dev, "parse error %d\n", ret); 263 233 return ret; 264 234 } 265 235 } else { 266 - if (!dev->platform_data) { 236 + struct asoc_simple_card_info *cinfo; 237 + 238 + cinfo = dev->platform_data; 239 + if (!cinfo) { 267 240 dev_err(dev, "no info for asoc-simple-card\n"); 268 241 return -EINVAL; 269 242 } 270 243 271 - memcpy(cinfo, dev->platform_data, sizeof(*cinfo)); 272 - cinfo->snd_card.dev = dev; 273 - } 244 + if (!cinfo->name || 245 + !cinfo->codec_dai.name || 246 + !cinfo->codec || 247 + !cinfo->platform || 248 + !cinfo->cpu_dai.name) { 249 + dev_err(dev, "insufficient asoc_simple_card_info settings\n"); 250 + return -EINVAL; 251 + } 274 252 275 - if (!cinfo->name || 276 - !cinfo->card || 277 - !cinfo->codec_dai.name || 278 - !(cinfo->codec || of_codec) || 279 - !(cinfo->platform || of_platform) || 280 - !(cinfo->cpu_dai.name || of_cpu)) { 281 - dev_err(dev, "insufficient asoc_simple_card_info settings\n"); 282 - return -EINVAL; 253 + priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name; 254 + dai_link->name = cinfo->name; 255 + dai_link->stream_name = cinfo->name; 256 + dai_link->platform_name = cinfo->platform; 257 + dai_link->codec_name = cinfo->codec; 258 + dai_link->cpu_dai_name = cinfo->cpu_dai.name; 259 + dai_link->codec_dai_name = cinfo->codec_dai.name; 260 + memcpy(&priv->cpu_dai, &cinfo->cpu_dai, 261 + sizeof(priv->cpu_dai)); 262 + memcpy(&priv->codec_dai, &cinfo->codec_dai, 263 + sizeof(priv->codec_dai)); 264 + 265 + priv->cpu_dai.fmt |= cinfo->daifmt; 266 + priv->codec_dai.fmt |= cinfo->daifmt; 283 267 } 284 268 285 269 /* 286 270 * init snd_soc_dai_link 287 271 */ 288 - cinfo->snd_link.name = cinfo->name; 289 - cinfo->snd_link.stream_name = cinfo->name; 290 - cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai.name; 291 - cinfo->snd_link.platform_name = cinfo->platform; 292 - cinfo->snd_link.codec_name = cinfo->codec; 293 - cinfo->snd_link.codec_dai_name = cinfo->codec_dai.name; 294 - cinfo->snd_link.cpu_of_node = of_cpu; 295 - cinfo->snd_link.codec_of_node = of_codec; 296 - cinfo->snd_link.platform_of_node = of_platform; 297 - cinfo->snd_link.init = asoc_simple_card_dai_init; 272 + dai_link->init = asoc_simple_card_dai_init; 298 273 299 - /* 300 - * init snd_soc_card 301 - */ 302 - cinfo->snd_card.name = cinfo->card; 303 - cinfo->snd_card.owner = THIS_MODULE; 304 - cinfo->snd_card.dai_link = &cinfo->snd_link; 305 - cinfo->snd_card.num_links = 1; 274 + snd_soc_card_set_drvdata(&priv->snd_card, priv); 306 275 307 - snd_soc_card_set_drvdata(&cinfo->snd_card, cinfo); 308 - 309 - return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card); 276 + return devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 310 277 } 311 278 312 279 static const struct of_device_id asoc_simple_of_match[] = {
+1 -6
sound/soc/samsung/h1940_uda1380.c
··· 66 66 { 67 67 struct snd_pcm_runtime *runtime = substream->runtime; 68 68 69 - runtime->hw.rate_min = hw_rates.list[0]; 70 - runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1]; 71 - runtime->hw.rates = SNDRV_PCM_RATE_KNOT; 72 - 73 69 return snd_pcm_hw_constraint_list(runtime, 0, 74 70 SNDRV_PCM_HW_PARAM_RATE, 75 71 &hw_rates); ··· 90 94 div++; 91 95 break; 92 96 default: 93 - dev_err(&rtd->dev, "%s: rate %d is not supported\n", 97 + dev_err(rtd->dev, "%s: rate %d is not supported\n", 94 98 __func__, rate); 95 99 return -EINVAL; 96 100 } ··· 177 181 { 178 182 struct snd_soc_codec *codec = rtd->codec; 179 183 struct snd_soc_dapm_context *dapm = &codec->dapm; 180 - int err; 181 184 182 185 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 183 186 snd_soc_dapm_enable_pin(dapm, "Speaker");
+57 -111
sound/soc/samsung/neo1973_wm8753.c
··· 192 192 .hw_free = neo1973_voice_hw_free, 193 193 }; 194 194 195 - /* Shared routes and controls */ 196 - 197 - static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = { 198 - SND_SOC_DAPM_LINE("GSM Line Out", NULL), 199 - SND_SOC_DAPM_LINE("GSM Line In", NULL), 200 - SND_SOC_DAPM_MIC("Headset Mic", NULL), 201 - SND_SOC_DAPM_MIC("Handset Mic", NULL), 202 - }; 203 - 204 - static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = { 205 - /* Connections to the GSM Module */ 206 - {"GSM Line Out", NULL, "MONO1"}, 207 - {"GSM Line Out", NULL, "MONO2"}, 208 - {"RXP", NULL, "GSM Line In"}, 209 - {"RXN", NULL, "GSM Line In"}, 210 - 211 - /* Connections to Headset */ 212 - {"MIC1", NULL, "Mic Bias"}, 213 - {"Mic Bias", NULL, "Headset Mic"}, 214 - 215 - /* Call Mic */ 216 - {"MIC2", NULL, "Mic Bias"}, 217 - {"MIC2N", NULL, "Mic Bias"}, 218 - {"Mic Bias", NULL, "Handset Mic"}, 219 - 220 - /* Connect the ALC pins */ 221 - {"ACIN", NULL, "ACOP"}, 222 - }; 223 - 224 - static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { 225 - SOC_DAPM_PIN_SWITCH("GSM Line Out"), 226 - SOC_DAPM_PIN_SWITCH("GSM Line In"), 227 - SOC_DAPM_PIN_SWITCH("Headset Mic"), 228 - SOC_DAPM_PIN_SWITCH("Handset Mic"), 229 - }; 230 - 231 - /* GTA02 specific routes and controls */ 232 - 233 195 static int gta02_speaker_enabled; 234 196 235 197 static int lm4853_set_spk(struct snd_kcontrol *kcontrol, ··· 219 257 return 0; 220 258 } 221 259 222 - static const struct snd_soc_dapm_route neo1973_gta02_routes[] = { 260 + static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = { 261 + SND_SOC_DAPM_LINE("GSM Line Out", NULL), 262 + SND_SOC_DAPM_LINE("GSM Line In", NULL), 263 + SND_SOC_DAPM_MIC("Headset Mic", NULL), 264 + SND_SOC_DAPM_MIC("Handset Mic", NULL), 265 + SND_SOC_DAPM_SPK("Handset Spk", NULL), 266 + SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), 267 + }; 268 + 269 + static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = { 270 + /* Connections to the GSM Module */ 271 + {"GSM Line Out", NULL, "MONO1"}, 272 + {"GSM Line Out", NULL, "MONO2"}, 273 + {"RXP", NULL, "GSM Line In"}, 274 + {"RXN", NULL, "GSM Line In"}, 275 + 276 + /* Connections to Headset */ 277 + {"MIC1", NULL, "Mic Bias"}, 278 + {"Mic Bias", NULL, "Headset Mic"}, 279 + 280 + /* Call Mic */ 281 + {"MIC2", NULL, "Mic Bias"}, 282 + {"MIC2N", NULL, "Mic Bias"}, 283 + {"Mic Bias", NULL, "Handset Mic"}, 284 + 285 + /* Connect the ALC pins */ 286 + {"ACIN", NULL, "ACOP"}, 287 + 223 288 /* Connections to the amp */ 224 289 {"Stereo Out", NULL, "LOUT1"}, 225 290 {"Stereo Out", NULL, "ROUT1"}, ··· 256 267 {"Handset Spk", NULL, "ROUT2"}, 257 268 }; 258 269 259 - static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = { 270 + static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { 271 + SOC_DAPM_PIN_SWITCH("GSM Line Out"), 272 + SOC_DAPM_PIN_SWITCH("GSM Line In"), 273 + SOC_DAPM_PIN_SWITCH("Headset Mic"), 274 + SOC_DAPM_PIN_SWITCH("Handset Mic"), 260 275 SOC_DAPM_PIN_SWITCH("Handset Spk"), 261 276 SOC_DAPM_PIN_SWITCH("Stereo Out"), 262 277 ··· 269 276 lm4853_set_spk), 270 277 }; 271 278 272 - static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = { 273 - SND_SOC_DAPM_SPK("Handset Spk", NULL), 274 - SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), 275 - }; 276 - 277 - static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) 278 - { 279 - struct snd_soc_dapm_context *dapm = &codec->dapm; 280 - int ret; 281 - 282 - ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets, 283 - ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets)); 284 - if (ret) 285 - return ret; 286 - 287 - ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes, 288 - ARRAY_SIZE(neo1973_gta02_routes)); 289 - if (ret) 290 - return ret; 291 - 292 - ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls, 293 - ARRAY_SIZE(neo1973_gta02_wm8753_controls)); 294 - if (ret) 295 - return ret; 296 - 297 - snd_soc_dapm_disable_pin(dapm, "Stereo Out"); 298 - snd_soc_dapm_disable_pin(dapm, "Handset Spk"); 299 - snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); 300 - snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); 301 - 302 - return 0; 303 - } 304 - 305 279 static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) 306 280 { 307 281 struct snd_soc_codec *codec = rtd->codec; 308 - struct snd_soc_dapm_context *dapm = &codec->dapm; 309 - int ret; 282 + struct snd_soc_card *card = rtd->card; 310 283 311 284 /* set up NC codec pins */ 312 - snd_soc_dapm_nc_pin(dapm, "OUT3"); 313 - snd_soc_dapm_nc_pin(dapm, "OUT4"); 314 - snd_soc_dapm_nc_pin(dapm, "LINE1"); 315 - snd_soc_dapm_nc_pin(dapm, "LINE2"); 316 - 317 - /* Add neo1973 specific widgets */ 318 - ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets, 319 - ARRAY_SIZE(neo1973_wm8753_dapm_widgets)); 320 - if (ret) 321 - return ret; 322 - 323 - /* add neo1973 specific controls */ 324 - ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls, 325 - ARRAY_SIZE(neo1973_wm8753_controls)); 326 - if (ret) 327 - return ret; 328 - 329 - /* set up neo1973 specific audio routes */ 330 - ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes, 331 - ARRAY_SIZE(neo1973_wm8753_routes)); 332 - if (ret) 333 - return ret; 285 + snd_soc_dapm_nc_pin(&codec->dapm, "OUT3"); 286 + snd_soc_dapm_nc_pin(&codec->dapm, "OUT4"); 287 + snd_soc_dapm_nc_pin(&codec->dapm, "LINE1"); 288 + snd_soc_dapm_nc_pin(&codec->dapm, "LINE2"); 334 289 335 290 /* set endpoints to default off mode */ 336 - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); 337 - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); 338 - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); 339 - snd_soc_dapm_disable_pin(dapm, "Handset Mic"); 291 + snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out"); 292 + snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In"); 293 + snd_soc_dapm_disable_pin(&card->dapm, "Headset Mic"); 294 + snd_soc_dapm_disable_pin(&card->dapm, "Handset Mic"); 295 + snd_soc_dapm_disable_pin(&card->dapm, "Stereo Out"); 296 + snd_soc_dapm_disable_pin(&card->dapm, "Handset Spk"); 340 297 341 298 /* allow audio paths from the GSM modem to run during suspend */ 342 - snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); 343 - snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); 344 - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); 345 - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); 346 - 347 - if (machine_is_neo1973_gta02()) { 348 - ret = neo1973_gta02_wm8753_init(codec); 349 - if (ret) 350 - return ret; 351 - } 299 + snd_soc_dapm_ignore_suspend(&card->dapm, "GSM Line Out"); 300 + snd_soc_dapm_ignore_suspend(&card->dapm, "GSM Line In"); 301 + snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); 302 + snd_soc_dapm_ignore_suspend(&card->dapm, "Handset Mic"); 303 + snd_soc_dapm_ignore_suspend(&card->dapm, "Stereo Out"); 304 + snd_soc_dapm_ignore_suspend(&card->dapm, "Handset Spk"); 352 305 353 306 return 0; 354 307 } ··· 348 409 .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs), 349 410 .codec_conf = neo1973_codec_conf, 350 411 .num_configs = ARRAY_SIZE(neo1973_codec_conf), 412 + 413 + .controls = neo1973_wm8753_controls, 414 + .num_controls = ARRAY_SIZE(neo1973_wm8753_controls), 415 + .dapm_widgets = neo1973_wm8753_dapm_widgets, 416 + .num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets), 417 + .dapm_routes = neo1973_wm8753_routes, 418 + .num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes), 351 419 }; 352 420 353 421 static struct platform_device *neo1973_snd_device;
-5
sound/soc/samsung/rx1950_uda1380.c
··· 131 131 { 132 132 struct snd_pcm_runtime *runtime = substream->runtime; 133 133 134 - runtime->hw.rate_min = hw_rates.list[0]; 135 - runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1]; 136 - runtime->hw.rates = SNDRV_PCM_RATE_KNOT; 137 - 138 134 return snd_pcm_hw_constraint_list(runtime, 0, 139 135 SNDRV_PCM_HW_PARAM_RATE, 140 136 &hw_rates); ··· 222 226 { 223 227 struct snd_soc_codec *codec = rtd->codec; 224 228 struct snd_soc_dapm_context *dapm = &codec->dapm; 225 - int err; 226 229 227 230 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 228 231 snd_soc_dapm_enable_pin(dapm, "Speaker");
+1 -1
sound/soc/samsung/smdk_wm8994.c
··· 202 202 203 203 static struct platform_driver smdk_audio_driver = { 204 204 .driver = { 205 - .name = "smdk-audio-wm8894", 205 + .name = "smdk-audio-wm8994", 206 206 .owner = THIS_MODULE, 207 207 .of_match_table = of_match_ptr(samsung_wm8994_of_match), 208 208 .pm = &snd_soc_pm_ops,
+2
sound/soc/samsung/tobermory.c
··· 44 44 SND_SOC_CLOCK_IN); 45 45 if (ret < 0) { 46 46 pr_err("Failed to set SYSCLK: %d\n", ret); 47 + snd_soc_dai_set_pll(codec_dai, WM8962_FLL, 48 + 0, 0, 0); 47 49 return ret; 48 50 } 49 51 }
+5 -14
sound/soc/sh/migor.c
··· 136 136 { "Mic Bias", NULL, "External Microphone" }, 137 137 }; 138 138 139 - static int migor_dai_init(struct snd_soc_pcm_runtime *rtd) 140 - { 141 - struct snd_soc_codec *codec = rtd->codec; 142 - struct snd_soc_dapm_context *dapm = &codec->dapm; 143 - 144 - snd_soc_dapm_new_controls(dapm, migor_dapm_widgets, 145 - ARRAY_SIZE(migor_dapm_widgets)); 146 - 147 - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 148 - 149 - return 0; 150 - } 151 - 152 139 /* migor digital audio interface glue - connects codec <--> CPU */ 153 140 static struct snd_soc_dai_link migor_dai = { 154 141 .name = "wm8978", ··· 145 158 .platform_name = "siu-pcm-audio", 146 159 .codec_name = "wm8978.0-001a", 147 160 .ops = &migor_dai_ops, 148 - .init = migor_dai_init, 149 161 }; 150 162 151 163 /* migor audio machine driver */ ··· 153 167 .owner = THIS_MODULE, 154 168 .dai_link = &migor_dai, 155 169 .num_links = 1, 170 + 171 + .dapm_widgets = migor_dapm_widgets, 172 + .num_dapm_widgets = ARRAY_SIZE(migor_dapm_widgets), 173 + .dapm_routes = audio_map, 174 + .num_dapm_routes = ARRAY_SIZE(audio_map), 156 175 }; 157 176 158 177 static struct platform_device *migor_snd_device;
+14
sound/soc/sirf/Kconfig
··· 1 + config SND_SOC_SIRF 2 + tristate "SoC Audio for the SiRF SoC chips" 3 + depends on ARCH_SIRF || COMPILE_TEST 4 + select SND_SOC_GENERIC_DMAENGINE_PCM 5 + 6 + config SND_SOC_SIRF_AUDIO 7 + tristate "SoC Audio support for SiRF internal audio codec" 8 + depends on SND_SOC_SIRF 9 + select SND_SOC_SIRF_AUDIO_CODEC 10 + select SND_SOC_SIRF_AUDIO_PORT 11 + 12 + config SND_SOC_SIRF_AUDIO_PORT 13 + select REGMAP_MMIO 14 + tristate
+5
sound/soc/sirf/Makefile
··· 1 + snd-soc-sirf-audio-objs := sirf-audio.o 2 + snd-soc-sirf-audio-port-objs := sirf-audio-port.o 3 + 4 + obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o 5 + obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o
+194
sound/soc/sirf/sirf-audio-port.c
··· 1 + /* 2 + * SiRF Audio port driver 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + #include <linux/module.h> 9 + #include <linux/io.h> 10 + #include <linux/regmap.h> 11 + #include <sound/soc.h> 12 + #include <sound/dmaengine_pcm.h> 13 + 14 + #include "sirf-audio-port.h" 15 + 16 + struct sirf_audio_port { 17 + struct regmap *regmap; 18 + struct snd_dmaengine_dai_dma_data playback_dma_data; 19 + struct snd_dmaengine_dai_dma_data capture_dma_data; 20 + }; 21 + 22 + static void sirf_audio_port_tx_enable(struct sirf_audio_port *port) 23 + { 24 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 25 + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); 26 + regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); 27 + regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); 28 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 29 + AUDIO_FIFO_START, AUDIO_FIFO_START); 30 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, 31 + IC_TX_ENABLE, IC_TX_ENABLE); 32 + } 33 + 34 + static void sirf_audio_port_tx_disable(struct sirf_audio_port *port) 35 + { 36 + regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); 37 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, 38 + IC_TX_ENABLE, ~IC_TX_ENABLE); 39 + } 40 + 41 + static void sirf_audio_port_rx_enable(struct sirf_audio_port *port, 42 + int channels) 43 + { 44 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 45 + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); 46 + regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); 47 + regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); 48 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 49 + AUDIO_FIFO_START, AUDIO_FIFO_START); 50 + if (channels == 1) 51 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, 52 + IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); 53 + else 54 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, 55 + IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); 56 + } 57 + 58 + static void sirf_audio_port_rx_disable(struct sirf_audio_port *port) 59 + { 60 + regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, 61 + IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); 62 + } 63 + 64 + static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) 65 + { 66 + struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); 67 + snd_soc_dai_init_dma_data(dai, &port->playback_dma_data, 68 + &port->capture_dma_data); 69 + return 0; 70 + } 71 + 72 + static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd, 73 + struct snd_soc_dai *dai) 74 + { 75 + struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); 76 + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 77 + 78 + switch (cmd) { 79 + case SNDRV_PCM_TRIGGER_STOP: 80 + case SNDRV_PCM_TRIGGER_SUSPEND: 81 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 82 + if (playback) 83 + sirf_audio_port_tx_disable(port); 84 + else 85 + sirf_audio_port_rx_disable(port); 86 + break; 87 + case SNDRV_PCM_TRIGGER_START: 88 + case SNDRV_PCM_TRIGGER_RESUME: 89 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 90 + if (playback) 91 + sirf_audio_port_tx_enable(port); 92 + else 93 + sirf_audio_port_rx_enable(port, 94 + substream->runtime->channels); 95 + break; 96 + default: 97 + return -EINVAL; 98 + } 99 + 100 + return 0; 101 + } 102 + 103 + static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = { 104 + .trigger = sirf_audio_port_trigger, 105 + }; 106 + 107 + static struct snd_soc_dai_driver sirf_audio_port_dai = { 108 + .probe = sirf_audio_port_dai_probe, 109 + .name = "sirf-audio-port", 110 + .id = 0, 111 + .playback = { 112 + .channels_min = 2, 113 + .channels_max = 2, 114 + .rates = SNDRV_PCM_RATE_48000, 115 + .formats = SNDRV_PCM_FMTBIT_S16_LE, 116 + }, 117 + .capture = { 118 + .channels_min = 1, 119 + .channels_max = 2, 120 + .rates = SNDRV_PCM_RATE_48000, 121 + .formats = SNDRV_PCM_FMTBIT_S16_LE, 122 + }, 123 + .ops = &sirf_audio_port_dai_ops, 124 + }; 125 + 126 + static const struct snd_soc_component_driver sirf_audio_port_component = { 127 + .name = "sirf-audio-port", 128 + }; 129 + 130 + static const struct regmap_config sirf_audio_port_regmap_config = { 131 + .reg_bits = 32, 132 + .reg_stride = 4, 133 + .val_bits = 32, 134 + .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, 135 + .cache_type = REGCACHE_NONE, 136 + }; 137 + 138 + static int sirf_audio_port_probe(struct platform_device *pdev) 139 + { 140 + int ret; 141 + struct sirf_audio_port *port; 142 + void __iomem *base; 143 + struct resource *mem_res; 144 + 145 + port = devm_kzalloc(&pdev->dev, 146 + sizeof(struct sirf_audio_port), GFP_KERNEL); 147 + if (!port) 148 + return -ENOMEM; 149 + 150 + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 151 + if (!mem_res) { 152 + dev_err(&pdev->dev, "no mem resource?\n"); 153 + return -ENODEV; 154 + } 155 + 156 + base = devm_ioremap(&pdev->dev, mem_res->start, 157 + resource_size(mem_res)); 158 + if (base == NULL) 159 + return -ENOMEM; 160 + 161 + port->regmap = devm_regmap_init_mmio(&pdev->dev, base, 162 + &sirf_audio_port_regmap_config); 163 + if (IS_ERR(port->regmap)) 164 + return PTR_ERR(port->regmap); 165 + 166 + ret = devm_snd_soc_register_component(&pdev->dev, 167 + &sirf_audio_port_component, &sirf_audio_port_dai, 1); 168 + if (ret) 169 + return ret; 170 + 171 + platform_set_drvdata(pdev, port); 172 + return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 173 + } 174 + 175 + static const struct of_device_id sirf_audio_port_of_match[] = { 176 + { .compatible = "sirf,audio-port", }, 177 + {} 178 + }; 179 + MODULE_DEVICE_TABLE(of, sirf_audio_port_of_match); 180 + 181 + static struct platform_driver sirf_audio_port_driver = { 182 + .driver = { 183 + .name = "sirf-audio-port", 184 + .owner = THIS_MODULE, 185 + .of_match_table = sirf_audio_port_of_match, 186 + }, 187 + .probe = sirf_audio_port_probe, 188 + }; 189 + 190 + module_platform_driver(sirf_audio_port_driver); 191 + 192 + MODULE_DESCRIPTION("SiRF Audio Port driver"); 193 + MODULE_AUTHOR("RongJun Ying <Rongjun.Ying@csr.com>"); 194 + MODULE_LICENSE("GPL v2");
+62
sound/soc/sirf/sirf-audio-port.h
··· 1 + /* 2 + * SiRF Audio port controllers define 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + 9 + #ifndef _SIRF_AUDIO_PORT_H 10 + #define _SIRF_AUDIO_PORT_H 11 + 12 + #define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F 13 + #define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 14 + #define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 15 + #define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 16 + 17 + #define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ 18 + << AUDIO_PORT_TX_FIFO_SC_OFFSET) 19 + #define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ 20 + << AUDIO_PORT_TX_FIFO_LC_OFFSET) 21 + #define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ 22 + << AUDIO_PORT_TX_FIFO_HC_OFFSET) 23 + 24 + #define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F 25 + #define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 26 + #define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 27 + #define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 28 + 29 + #define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ 30 + << AUDIO_PORT_RX_FIFO_SC_OFFSET) 31 + #define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ 32 + << AUDIO_PORT_RX_FIFO_LC_OFFSET) 33 + #define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ 34 + << AUDIO_PORT_RX_FIFO_HC_OFFSET) 35 + #define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) 36 + #define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) 37 + 38 + #define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) 39 + #define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) 40 + #define AUDIO_PORT_IC_TXFIFO_STS (0x0104) 41 + #define AUDIO_PORT_IC_TXFIFO_INT (0x0108) 42 + #define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) 43 + 44 + #define AUDIO_PORT_IC_RXFIFO_OP (0x0110) 45 + #define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) 46 + #define AUDIO_PORT_IC_RXFIFO_STS (0x0118) 47 + #define AUDIO_PORT_IC_RXFIFO_INT (0x011C) 48 + #define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) 49 + 50 + #define AUDIO_FIFO_START (1 << 0) 51 + #define AUDIO_FIFO_RESET (1 << 1) 52 + 53 + #define AUDIO_FIFO_FULL (1 << 0) 54 + #define AUDIO_FIFO_EMPTY (1 << 1) 55 + #define AUDIO_FIFO_OFLOW (1 << 2) 56 + #define AUDIO_FIFO_UFLOW (1 << 3) 57 + 58 + #define IC_TX_ENABLE (0x03) 59 + #define IC_RX_ENABLE_MONO (0x01) 60 + #define IC_RX_ENABLE_STEREO (0x03) 61 + 62 + #endif /*__SIRF_AUDIO_PORT_H*/
+156
sound/soc/sirf/sirf-audio.c
··· 1 + /* 2 + * SiRF audio card driver 3 + * 4 + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 5 + * 6 + * Licensed under GPLv2 or later. 7 + */ 8 + 9 + #include <linux/platform_device.h> 10 + #include <linux/module.h> 11 + #include <linux/of.h> 12 + #include <linux/gpio.h> 13 + #include <linux/of_gpio.h> 14 + #include <sound/core.h> 15 + #include <sound/pcm.h> 16 + #include <sound/soc.h> 17 + 18 + struct sirf_audio_card { 19 + unsigned int gpio_hp_pa; 20 + unsigned int gpio_spk_pa; 21 + }; 22 + 23 + static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w, 24 + struct snd_kcontrol *ctrl, int event) 25 + { 26 + struct snd_soc_dapm_context *dapm = w->dapm; 27 + struct snd_soc_card *card = dapm->card; 28 + struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); 29 + int on = !SND_SOC_DAPM_EVENT_OFF(event); 30 + if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) 31 + gpio_set_value(sirf_audio_card->gpio_hp_pa, on); 32 + return 0; 33 + } 34 + 35 + static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w, 36 + struct snd_kcontrol *ctrl, int event) 37 + { 38 + struct snd_soc_dapm_context *dapm = w->dapm; 39 + struct snd_soc_card *card = dapm->card; 40 + struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); 41 + int on = !SND_SOC_DAPM_EVENT_OFF(event); 42 + 43 + if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) 44 + gpio_set_value(sirf_audio_card->gpio_spk_pa, on); 45 + 46 + return 0; 47 + } 48 + static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = { 49 + SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event), 50 + SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event), 51 + SND_SOC_DAPM_MIC("Ext Mic", NULL), 52 + }; 53 + 54 + static const struct snd_soc_dapm_route intercon[] = { 55 + {"Hp", NULL, "HPOUTL"}, 56 + {"Hp", NULL, "HPOUTR"}, 57 + {"Ext Spk", NULL, "SPKOUT"}, 58 + {"MICIN1", NULL, "Mic Bias"}, 59 + {"Mic Bias", NULL, "Ext Mic"}, 60 + }; 61 + 62 + /* Digital audio interface glue - connects codec <--> CPU */ 63 + static struct snd_soc_dai_link sirf_audio_dai_link[] = { 64 + { 65 + .name = "SiRF audio card", 66 + .stream_name = "SiRF audio HiFi", 67 + .codec_dai_name = "sirf-audio-codec", 68 + }, 69 + }; 70 + 71 + /* Audio machine driver */ 72 + static struct snd_soc_card snd_soc_sirf_audio_card = { 73 + .name = "SiRF audio card", 74 + .owner = THIS_MODULE, 75 + .dai_link = sirf_audio_dai_link, 76 + .num_links = ARRAY_SIZE(sirf_audio_dai_link), 77 + .dapm_widgets = sirf_audio_dapm_widgets, 78 + .num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets), 79 + .dapm_routes = intercon, 80 + .num_dapm_routes = ARRAY_SIZE(intercon), 81 + }; 82 + 83 + static int sirf_audio_probe(struct platform_device *pdev) 84 + { 85 + struct snd_soc_card *card = &snd_soc_sirf_audio_card; 86 + struct sirf_audio_card *sirf_audio_card; 87 + int ret; 88 + 89 + sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card), 90 + GFP_KERNEL); 91 + if (sirf_audio_card == NULL) 92 + return -ENOMEM; 93 + 94 + sirf_audio_dai_link[0].cpu_of_node = 95 + of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); 96 + sirf_audio_dai_link[0].platform_of_node = 97 + of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); 98 + sirf_audio_dai_link[0].codec_of_node = 99 + of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0); 100 + sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node, 101 + "spk-pa-gpios", 0); 102 + sirf_audio_card->gpio_hp_pa = of_get_named_gpio(pdev->dev.of_node, 103 + "hp-pa-gpios", 0); 104 + if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) { 105 + ret = devm_gpio_request_one(&pdev->dev, 106 + sirf_audio_card->gpio_spk_pa, 107 + GPIOF_OUT_INIT_LOW, "SPA_PA_SD"); 108 + if (ret) { 109 + dev_err(&pdev->dev, 110 + "Failed to request GPIO_%d for reset: %d\n", 111 + sirf_audio_card->gpio_spk_pa, ret); 112 + return ret; 113 + } 114 + } 115 + if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) { 116 + ret = devm_gpio_request_one(&pdev->dev, 117 + sirf_audio_card->gpio_hp_pa, 118 + GPIOF_OUT_INIT_LOW, "HP_PA_SD"); 119 + if (ret) { 120 + dev_err(&pdev->dev, 121 + "Failed to request GPIO_%d for reset: %d\n", 122 + sirf_audio_card->gpio_hp_pa, ret); 123 + return ret; 124 + } 125 + } 126 + 127 + card->dev = &pdev->dev; 128 + snd_soc_card_set_drvdata(card, sirf_audio_card); 129 + 130 + ret = devm_snd_soc_register_card(&pdev->dev, card); 131 + if (ret) 132 + dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); 133 + 134 + return ret; 135 + } 136 + 137 + static const struct of_device_id sirf_audio_of_match[] = { 138 + {.compatible = "sirf,sirf-audio-card", }, 139 + { }, 140 + }; 141 + MODULE_DEVICE_TABLE(of, sirf_audio_of_match); 142 + 143 + static struct platform_driver sirf_audio_driver = { 144 + .driver = { 145 + .name = "sirf-audio-card", 146 + .owner = THIS_MODULE, 147 + .pm = &snd_soc_pm_ops, 148 + .of_match_table = sirf_audio_of_match, 149 + }, 150 + .probe = sirf_audio_probe, 151 + }; 152 + module_platform_driver(sirf_audio_driver); 153 + 154 + MODULE_AUTHOR("RongJun Ying <RongJun.Ying@csr.com>"); 155 + MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver"); 156 + MODULE_LICENSE("GPL v2");