aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/adi,ssm2602.txt19
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/ssm4567.txt15
-rw-r--r--sound/soc/codecs/Kconfig13
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ssm2602-i2c.c9
-rw-r--r--sound/soc/codecs/ssm2602-spi.c7
-rw-r--r--sound/soc/codecs/ssm2602.c15
-rw-r--r--sound/soc/codecs/ssm4567.c343
-rw-r--r--sound/soc/fsl/fsl_spdif.c1
-rw-r--r--sound/soc/generic/simple-card.c226
-rw-r--r--sound/soc/sirf/sirf-usp.c24
12 files changed, 601 insertions, 77 deletions
diff --git a/Documentation/devicetree/bindings/sound/adi,ssm2602.txt b/Documentation/devicetree/bindings/sound/adi,ssm2602.txt
new file mode 100644
index 000000000000..3b3302fe399b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/adi,ssm2602.txt
@@ -0,0 +1,19 @@
1Analog Devices SSM2602, SSM2603 and SSM2604 I2S audio CODEC devices
2
3SSM2602 support both I2C and SPI as the configuration interface,
4the selection is made by the MODE strap-in pin.
5SSM2603 and SSM2604 only support I2C as the configuration interface.
6
7Required properties:
8
9 - compatible : One of "adi,ssm2602", "adi,ssm2603" or "adi,ssm2604"
10
11 - reg : the I2C address of the device for I2C, the chip select
12 number for SPI.
13
14 Example:
15
16 ssm2602: ssm2602@1a {
17 compatible = "adi,ssm2602";
18 reg = <0x1a>;
19 };
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index c2e9841dfce4..c3cba600bf11 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -17,6 +17,10 @@ Optional properties:
17 source. 17 source.
18- simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec 18- simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec
19 mclk. 19 mclk.
20- simple-audio-card,hp-det-gpio : Reference to GPIO that signals when
21 headphones are attached.
22- simple-audio-card,mic-det-gpio : Reference to GPIO that signals when
23 a microphone is attached.
20 24
21Optional subnodes: 25Optional subnodes:
22 26
diff --git a/Documentation/devicetree/bindings/sound/ssm4567.txt b/Documentation/devicetree/bindings/sound/ssm4567.txt
new file mode 100644
index 000000000000..ec3d9e7004b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ssm4567.txt
@@ -0,0 +1,15 @@
1Analog Devices SSM4567 audio amplifier
2
3This device supports I2C only.
4
5Required properties:
6 - compatible : Must be "adi,ssm4567"
7 - reg : the I2C address of the device. This will either be 0x34 (LR_SEL/ADDR connected to AGND),
8 0x35 (LR_SEL/ADDR connected to IOVDD) or 0x36 (LR_SEL/ADDR open).
9
10Example:
11
12 ssm4567: ssm4567@34 {
13 compatible = "adi,ssm4567";
14 reg = <0x34>;
15 };
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0563cc6cd4d0..5b47c550bb89 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -94,6 +94,7 @@ config SND_SOC_ALL_CODECS
94 select SND_SOC_SSM2518 if I2C 94 select SND_SOC_SSM2518 if I2C
95 select SND_SOC_SSM2602_SPI if SPI_MASTER 95 select SND_SOC_SSM2602_SPI if SPI_MASTER
96 select SND_SOC_SSM2602_I2C if I2C 96 select SND_SOC_SSM2602_I2C if I2C
97 select SND_SOC_SSM4567 if I2C
97 select SND_SOC_STA32X if I2C 98 select SND_SOC_STA32X if I2C
98 select SND_SOC_STA350 if I2C 99 select SND_SOC_STA350 if I2C
99 select SND_SOC_STA529 if I2C 100 select SND_SOC_STA529 if I2C
@@ -540,12 +541,20 @@ config SND_SOC_SSM2602
540 tristate 541 tristate
541 542
542config SND_SOC_SSM2602_SPI 543config SND_SOC_SSM2602_SPI
544 tristate "Analog Devices SSM2602 CODEC - SPI"
545 depends on SPI_MASTER
543 select SND_SOC_SSM2602 546 select SND_SOC_SSM2602
544 tristate 547 select REGMAP_SPI
545 548
546config SND_SOC_SSM2602_I2C 549config SND_SOC_SSM2602_I2C
550 tristate "Analog Devices SSM2602 CODEC - I2C"
551 depends on I2C
547 select SND_SOC_SSM2602 552 select SND_SOC_SSM2602
548 tristate 553 select REGMAP_I2C
554
555config SND_SOC_SSM4567
556 tristate "Analog Devices ssm4567 amplifier driver support"
557 depends on I2C
549 558
550config SND_SOC_STA32X 559config SND_SOC_STA32X
551 tristate 560 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index afba944657bc..5dce451661e4 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -95,6 +95,7 @@ snd-soc-ssm2518-objs := ssm2518.o
95snd-soc-ssm2602-objs := ssm2602.o 95snd-soc-ssm2602-objs := ssm2602.o
96snd-soc-ssm2602-spi-objs := ssm2602-spi.o 96snd-soc-ssm2602-spi-objs := ssm2602-spi.o
97snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o 97snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o
98snd-soc-ssm4567-objs := ssm4567.o
98snd-soc-sta32x-objs := sta32x.o 99snd-soc-sta32x-objs := sta32x.o
99snd-soc-sta350-objs := sta350.o 100snd-soc-sta350-objs := sta350.o
100snd-soc-sta529-objs := sta529.o 101snd-soc-sta529-objs := sta529.o
@@ -266,6 +267,7 @@ obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
266obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 267obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
267obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o 268obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o
268obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o 269obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o
270obj-$(CONFIG_SND_SOC_SSM4567) += snd-soc-ssm4567.o
269obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o 271obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
270obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o 272obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o
271obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o 273obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
diff --git a/sound/soc/codecs/ssm2602-i2c.c b/sound/soc/codecs/ssm2602-i2c.c
index abd63d537173..0d9779d6bfda 100644
--- a/sound/soc/codecs/ssm2602-i2c.c
+++ b/sound/soc/codecs/ssm2602-i2c.c
@@ -41,10 +41,19 @@ static const struct i2c_device_id ssm2602_i2c_id[] = {
41}; 41};
42MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 42MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
43 43
44static const struct of_device_id ssm2602_of_match[] = {
45 { .compatible = "adi,ssm2602", },
46 { .compatible = "adi,ssm2603", },
47 { .compatible = "adi,ssm2604", },
48 { }
49};
50MODULE_DEVICE_TABLE(of, ssm2602_of_match);
51
44static struct i2c_driver ssm2602_i2c_driver = { 52static struct i2c_driver ssm2602_i2c_driver = {
45 .driver = { 53 .driver = {
46 .name = "ssm2602", 54 .name = "ssm2602",
47 .owner = THIS_MODULE, 55 .owner = THIS_MODULE,
56 .of_match_table = ssm2602_of_match,
48 }, 57 },
49 .probe = ssm2602_i2c_probe, 58 .probe = ssm2602_i2c_probe,
50 .remove = ssm2602_i2c_remove, 59 .remove = ssm2602_i2c_remove,
diff --git a/sound/soc/codecs/ssm2602-spi.c b/sound/soc/codecs/ssm2602-spi.c
index 2bf55e24a7bb..b5df14fbe3ad 100644
--- a/sound/soc/codecs/ssm2602-spi.c
+++ b/sound/soc/codecs/ssm2602-spi.c
@@ -26,10 +26,17 @@ static int ssm2602_spi_remove(struct spi_device *spi)
26 return 0; 26 return 0;
27} 27}
28 28
29static const struct of_device_id ssm2602_of_match[] = {
30 { .compatible = "adi,ssm2602", },
31 { }
32};
33MODULE_DEVICE_TABLE(of, ssm2602_of_match);
34
29static struct spi_driver ssm2602_spi_driver = { 35static struct spi_driver ssm2602_spi_driver = {
30 .driver = { 36 .driver = {
31 .name = "ssm2602", 37 .name = "ssm2602",
32 .owner = THIS_MODULE, 38 .owner = THIS_MODULE,
39 .of_match_table = ssm2602_of_match,
33 }, 40 },
34 .probe = ssm2602_spi_probe, 41 .probe = ssm2602_spi_probe,
35 .remove = ssm2602_spi_remove, 42 .remove = ssm2602_spi_remove,
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 527de0463548..314eaece1b7d 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -192,7 +192,7 @@ static const struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = {
192}; 192};
193 193
194static const unsigned int ssm2602_rates_11289600[] = { 194static const unsigned int ssm2602_rates_11289600[] = {
195 8000, 44100, 88200, 195 8000, 11025, 22050, 44100, 88200,
196}; 196};
197 197
198static const struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { 198static const struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = {
@@ -237,6 +237,16 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = {
237 {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)}, 237 {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)},
238 {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)}, 238 {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)},
239 239
240 /* 11.025k */
241 {11289600, 11025, SSM2602_COEFF_SRATE(0xc, 0x0, 0x0)},
242 {16934400, 11025, SSM2602_COEFF_SRATE(0xc, 0x1, 0x0)},
243 {12000000, 11025, SSM2602_COEFF_SRATE(0xc, 0x1, 0x1)},
244
245 /* 22.05k */
246 {11289600, 22050, SSM2602_COEFF_SRATE(0xd, 0x0, 0x0)},
247 {16934400, 22050, SSM2602_COEFF_SRATE(0xd, 0x1, 0x0)},
248 {12000000, 22050, SSM2602_COEFF_SRATE(0xd, 0x1, 0x1)},
249
240 /* 44.1k */ 250 /* 44.1k */
241 {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)}, 251 {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)},
242 {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)}, 252 {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)},
@@ -467,7 +477,8 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
467 return 0; 477 return 0;
468} 478}
469 479
470#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 480#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
481 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
471 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ 482 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
472 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ 483 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
473 SNDRV_PCM_RATE_96000) 484 SNDRV_PCM_RATE_96000)
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c
new file mode 100644
index 000000000000..4b5c17f8507e
--- /dev/null
+++ b/sound/soc/codecs/ssm4567.c
@@ -0,0 +1,343 @@
1/*
2 * SSM4567 amplifier audio driver
3 *
4 * Copyright 2014 Google Chromium project.
5 * Author: Anatol Pomozov <anatol@chromium.org>
6 *
7 * Based on code copyright/by:
8 * Copyright 2013 Analog Devices Inc.
9 *
10 * Licensed under the GPL-2.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/i2c.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/initval.h>
23#include <sound/tlv.h>
24
25#define SSM4567_REG_POWER_CTRL 0x00
26#define SSM4567_REG_AMP_SNS_CTRL 0x01
27#define SSM4567_REG_DAC_CTRL 0x02
28#define SSM4567_REG_DAC_VOLUME 0x03
29#define SSM4567_REG_SAI_CTRL_1 0x04
30#define SSM4567_REG_SAI_CTRL_2 0x05
31#define SSM4567_REG_SAI_PLACEMENT_1 0x06
32#define SSM4567_REG_SAI_PLACEMENT_2 0x07
33#define SSM4567_REG_SAI_PLACEMENT_3 0x08
34#define SSM4567_REG_SAI_PLACEMENT_4 0x09
35#define SSM4567_REG_SAI_PLACEMENT_5 0x0a
36#define SSM4567_REG_SAI_PLACEMENT_6 0x0b
37#define SSM4567_REG_BATTERY_V_OUT 0x0c
38#define SSM4567_REG_LIMITER_CTRL_1 0x0d
39#define SSM4567_REG_LIMITER_CTRL_2 0x0e
40#define SSM4567_REG_LIMITER_CTRL_3 0x0f
41#define SSM4567_REG_STATUS_1 0x10
42#define SSM4567_REG_STATUS_2 0x11
43#define SSM4567_REG_FAULT_CTRL 0x12
44#define SSM4567_REG_PDM_CTRL 0x13
45#define SSM4567_REG_MCLK_RATIO 0x14
46#define SSM4567_REG_BOOST_CTRL_1 0x15
47#define SSM4567_REG_BOOST_CTRL_2 0x16
48#define SSM4567_REG_SOFT_RESET 0xff
49
50/* POWER_CTRL */
51#define SSM4567_POWER_APWDN_EN BIT(7)
52#define SSM4567_POWER_BSNS_PWDN BIT(6)
53#define SSM4567_POWER_VSNS_PWDN BIT(5)
54#define SSM4567_POWER_ISNS_PWDN BIT(4)
55#define SSM4567_POWER_BOOST_PWDN BIT(3)
56#define SSM4567_POWER_AMP_PWDN BIT(2)
57#define SSM4567_POWER_VBAT_ONLY BIT(1)
58#define SSM4567_POWER_SPWDN BIT(0)
59
60/* DAC_CTRL */
61#define SSM4567_DAC_HV BIT(7)
62#define SSM4567_DAC_MUTE BIT(6)
63#define SSM4567_DAC_HPF BIT(5)
64#define SSM4567_DAC_LPM BIT(4)
65#define SSM4567_DAC_FS_MASK 0x7
66#define SSM4567_DAC_FS_8000_12000 0x0
67#define SSM4567_DAC_FS_16000_24000 0x1
68#define SSM4567_DAC_FS_32000_48000 0x2
69#define SSM4567_DAC_FS_64000_96000 0x3
70#define SSM4567_DAC_FS_128000_192000 0x4
71
72struct ssm4567 {
73 struct regmap *regmap;
74};
75
76static const struct reg_default ssm4567_reg_defaults[] = {
77 { SSM4567_REG_POWER_CTRL, 0x81 },
78 { SSM4567_REG_AMP_SNS_CTRL, 0x09 },
79 { SSM4567_REG_DAC_CTRL, 0x32 },
80 { SSM4567_REG_DAC_VOLUME, 0x40 },
81 { SSM4567_REG_SAI_CTRL_1, 0x00 },
82 { SSM4567_REG_SAI_CTRL_2, 0x08 },
83 { SSM4567_REG_SAI_PLACEMENT_1, 0x01 },
84 { SSM4567_REG_SAI_PLACEMENT_2, 0x20 },
85 { SSM4567_REG_SAI_PLACEMENT_3, 0x32 },
86 { SSM4567_REG_SAI_PLACEMENT_4, 0x07 },
87 { SSM4567_REG_SAI_PLACEMENT_5, 0x07 },
88 { SSM4567_REG_SAI_PLACEMENT_6, 0x07 },
89 { SSM4567_REG_BATTERY_V_OUT, 0x00 },
90 { SSM4567_REG_LIMITER_CTRL_1, 0xa4 },
91 { SSM4567_REG_LIMITER_CTRL_2, 0x73 },
92 { SSM4567_REG_LIMITER_CTRL_3, 0x00 },
93 { SSM4567_REG_STATUS_1, 0x00 },
94 { SSM4567_REG_STATUS_2, 0x00 },
95 { SSM4567_REG_FAULT_CTRL, 0x30 },
96 { SSM4567_REG_PDM_CTRL, 0x40 },
97 { SSM4567_REG_MCLK_RATIO, 0x11 },
98 { SSM4567_REG_BOOST_CTRL_1, 0x03 },
99 { SSM4567_REG_BOOST_CTRL_2, 0x00 },
100 { SSM4567_REG_SOFT_RESET, 0x00 },
101};
102
103
104static bool ssm4567_readable_reg(struct device *dev, unsigned int reg)
105{
106 switch (reg) {
107 case SSM4567_REG_POWER_CTRL ... SSM4567_REG_BOOST_CTRL_2:
108 return true;
109 default:
110 return false;
111 }
112
113}
114
115static bool ssm4567_writeable_reg(struct device *dev, unsigned int reg)
116{
117 switch (reg) {
118 case SSM4567_REG_POWER_CTRL ... SSM4567_REG_SAI_PLACEMENT_6:
119 case SSM4567_REG_LIMITER_CTRL_1 ... SSM4567_REG_LIMITER_CTRL_3:
120 case SSM4567_REG_FAULT_CTRL ... SSM4567_REG_BOOST_CTRL_2:
121 /* The datasheet states that soft reset register is read-only,
122 * but logically it is write-only. */
123 case SSM4567_REG_SOFT_RESET:
124 return true;
125 default:
126 return false;
127 }
128}
129
130static bool ssm4567_volatile_reg(struct device *dev, unsigned int reg)
131{
132 switch (reg) {
133 case SSM4567_REG_BATTERY_V_OUT:
134 case SSM4567_REG_STATUS_1 ... SSM4567_REG_STATUS_2:
135 case SSM4567_REG_SOFT_RESET:
136 return true;
137 default:
138 return false;
139 }
140}
141
142static const DECLARE_TLV_DB_MINMAX_MUTE(ssm4567_vol_tlv, -7125, 2400);
143
144static const struct snd_kcontrol_new ssm4567_snd_controls[] = {
145 SOC_SINGLE_TLV("Master Playback Volume", SSM4567_REG_DAC_VOLUME, 0,
146 0xff, 1, ssm4567_vol_tlv),
147 SOC_SINGLE("DAC Low Power Mode Switch", SSM4567_REG_DAC_CTRL, 4, 1, 0),
148};
149
150static const struct snd_soc_dapm_widget ssm4567_dapm_widgets[] = {
151 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM4567_REG_POWER_CTRL, 2, 1),
152
153 SND_SOC_DAPM_OUTPUT("OUT"),
154};
155
156static const struct snd_soc_dapm_route ssm4567_routes[] = {
157 { "OUT", NULL, "DAC" },
158};
159
160static int ssm4567_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
162{
163 struct snd_soc_codec *codec = dai->codec;
164 struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec);
165 unsigned int rate = params_rate(params);
166 unsigned int dacfs;
167
168 if (rate >= 8000 && rate <= 12000)
169 dacfs = SSM4567_DAC_FS_8000_12000;
170 else if (rate >= 16000 && rate <= 24000)
171 dacfs = SSM4567_DAC_FS_16000_24000;
172 else if (rate >= 32000 && rate <= 48000)
173 dacfs = SSM4567_DAC_FS_32000_48000;
174 else if (rate >= 64000 && rate <= 96000)
175 dacfs = SSM4567_DAC_FS_64000_96000;
176 else if (rate >= 128000 && rate <= 192000)
177 dacfs = SSM4567_DAC_FS_128000_192000;
178 else
179 return -EINVAL;
180
181 return regmap_update_bits(ssm4567->regmap, SSM4567_REG_DAC_CTRL,
182 SSM4567_DAC_FS_MASK, dacfs);
183}
184
185static int ssm4567_mute(struct snd_soc_dai *dai, int mute)
186{
187 struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(dai->codec);
188 unsigned int val;
189
190 val = mute ? SSM4567_DAC_MUTE : 0;
191 return regmap_update_bits(ssm4567->regmap, SSM4567_REG_DAC_CTRL,
192 SSM4567_DAC_MUTE, val);
193}
194
195static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable)
196{
197 int ret = 0;
198
199 if (!enable) {
200 ret = regmap_update_bits(ssm4567->regmap,
201 SSM4567_REG_POWER_CTRL,
202 SSM4567_POWER_SPWDN, SSM4567_POWER_SPWDN);
203 regcache_mark_dirty(ssm4567->regmap);
204 }
205
206 regcache_cache_only(ssm4567->regmap, !enable);
207
208 if (enable) {
209 ret = regmap_update_bits(ssm4567->regmap,
210 SSM4567_REG_POWER_CTRL,
211 SSM4567_POWER_SPWDN, 0x00);
212 regcache_sync(ssm4567->regmap);
213 }
214
215 return ret;
216}
217
218static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
219 enum snd_soc_bias_level level)
220{
221 struct ssm4567 *ssm4567 = snd_soc_codec_get_drvdata(codec);
222 int ret = 0;
223
224 switch (level) {
225 case SND_SOC_BIAS_ON:
226 break;
227 case SND_SOC_BIAS_PREPARE:
228 break;
229 case SND_SOC_BIAS_STANDBY:
230 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
231 ret = ssm4567_set_power(ssm4567, true);
232 break;
233 case SND_SOC_BIAS_OFF:
234 ret = ssm4567_set_power(ssm4567, false);
235 break;
236 }
237
238 if (ret)
239 return ret;
240
241 codec->dapm.bias_level = level;
242
243 return 0;
244}
245
246static const struct snd_soc_dai_ops ssm4567_dai_ops = {
247 .hw_params = ssm4567_hw_params,
248 .digital_mute = ssm4567_mute,
249};
250
251static struct snd_soc_dai_driver ssm4567_dai = {
252 .name = "ssm4567-hifi",
253 .playback = {
254 .stream_name = "Playback",
255 .channels_min = 1,
256 .channels_max = 1,
257 .rates = SNDRV_PCM_RATE_8000_192000,
258 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
259 SNDRV_PCM_FMTBIT_S32,
260 },
261 .ops = &ssm4567_dai_ops,
262};
263
264static struct snd_soc_codec_driver ssm4567_codec_driver = {
265 .set_bias_level = ssm4567_set_bias_level,
266 .idle_bias_off = true,
267
268 .controls = ssm4567_snd_controls,
269 .num_controls = ARRAY_SIZE(ssm4567_snd_controls),
270 .dapm_widgets = ssm4567_dapm_widgets,
271 .num_dapm_widgets = ARRAY_SIZE(ssm4567_dapm_widgets),
272 .dapm_routes = ssm4567_routes,
273 .num_dapm_routes = ARRAY_SIZE(ssm4567_routes),
274};
275
276static const struct regmap_config ssm4567_regmap_config = {
277 .val_bits = 8,
278 .reg_bits = 8,
279
280 .max_register = SSM4567_REG_SOFT_RESET,
281 .readable_reg = ssm4567_readable_reg,
282 .writeable_reg = ssm4567_writeable_reg,
283 .volatile_reg = ssm4567_volatile_reg,
284
285 .cache_type = REGCACHE_RBTREE,
286 .reg_defaults = ssm4567_reg_defaults,
287 .num_reg_defaults = ARRAY_SIZE(ssm4567_reg_defaults),
288};
289
290static int ssm4567_i2c_probe(struct i2c_client *i2c,
291 const struct i2c_device_id *id)
292{
293 struct ssm4567 *ssm4567;
294 int ret;
295
296 ssm4567 = devm_kzalloc(&i2c->dev, sizeof(*ssm4567), GFP_KERNEL);
297 if (ssm4567 == NULL)
298 return -ENOMEM;
299
300 i2c_set_clientdata(i2c, ssm4567);
301
302 ssm4567->regmap = devm_regmap_init_i2c(i2c, &ssm4567_regmap_config);
303 if (IS_ERR(ssm4567->regmap))
304 return PTR_ERR(ssm4567->regmap);
305
306 ret = regmap_write(ssm4567->regmap, SSM4567_REG_SOFT_RESET, 0x00);
307 if (ret)
308 return ret;
309
310 ret = ssm4567_set_power(ssm4567, false);
311 if (ret)
312 return ret;
313
314 return snd_soc_register_codec(&i2c->dev, &ssm4567_codec_driver,
315 &ssm4567_dai, 1);
316}
317
318static int ssm4567_i2c_remove(struct i2c_client *client)
319{
320 snd_soc_unregister_codec(&client->dev);
321 return 0;
322}
323
324static const struct i2c_device_id ssm4567_i2c_ids[] = {
325 { "ssm4567", 0 },
326 { }
327};
328MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids);
329
330static struct i2c_driver ssm4567_driver = {
331 .driver = {
332 .name = "ssm4567",
333 .owner = THIS_MODULE,
334 },
335 .probe = ssm4567_i2c_probe,
336 .remove = ssm4567_i2c_remove,
337 .id_table = ssm4567_i2c_ids,
338};
339module_i2c_driver(ssm4567_driver);
340
341MODULE_DESCRIPTION("ASoC SSM4567 driver");
342MODULE_AUTHOR("Anatol Pomozov <anatol@chromium.org>");
343MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index ae4e408810ec..9b791621294c 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -15,7 +15,6 @@
15 15
16#include <linux/bitrev.h> 16#include <linux/bitrev.h>
17#include <linux/clk.h> 17#include <linux/clk.h>
18#include <linux/clk-private.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/of_address.h> 19#include <linux/of_address.h>
21#include <linux/of_device.h> 20#include <linux/of_device.h>
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index cef7776b712c..fcb431fe20b4 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -10,10 +10,13 @@
10 */ 10 */
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/gpio.h>
13#include <linux/module.h> 14#include <linux/module.h>
14#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_gpio.h>
15#include <linux/platform_device.h> 17#include <linux/platform_device.h>
16#include <linux/string.h> 18#include <linux/string.h>
19#include <sound/jack.h>
17#include <sound/simple_card.h> 20#include <sound/simple_card.h>
18#include <sound/soc-dai.h> 21#include <sound/soc-dai.h>
19#include <sound/soc.h> 22#include <sound/soc.h>
@@ -25,9 +28,15 @@ struct simple_card_data {
25 struct asoc_simple_dai codec_dai; 28 struct asoc_simple_dai codec_dai;
26 } *dai_props; 29 } *dai_props;
27 unsigned int mclk_fs; 30 unsigned int mclk_fs;
31 int gpio_hp_det;
32 int gpio_mic_det;
28 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ 33 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
29}; 34};
30 35
36#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
37#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
38#define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
39
31static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, 40static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params) 41 struct snd_pcm_hw_params *params)
33{ 42{
@@ -50,6 +59,32 @@ static struct snd_soc_ops asoc_simple_card_ops = {
50 .hw_params = asoc_simple_card_hw_params, 59 .hw_params = asoc_simple_card_hw_params,
51}; 60};
52 61
62static struct snd_soc_jack simple_card_hp_jack;
63static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = {
64 {
65 .pin = "Headphones",
66 .mask = SND_JACK_HEADPHONE,
67 },
68};
69static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = {
70 .name = "Headphone detection",
71 .report = SND_JACK_HEADPHONE,
72 .debounce_time = 150,
73};
74
75static struct snd_soc_jack simple_card_mic_jack;
76static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = {
77 {
78 .pin = "Mic Jack",
79 .mask = SND_JACK_MICROPHONE,
80 },
81};
82static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = {
83 .name = "Mic detection",
84 .report = SND_JACK_MICROPHONE,
85 .debounce_time = 150,
86};
87
53static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, 88static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
54 struct asoc_simple_dai *set) 89 struct asoc_simple_dai *set)
55{ 90{
@@ -105,42 +140,70 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
105 if (ret < 0) 140 if (ret < 0)
106 return ret; 141 return ret;
107 142
143 if (gpio_is_valid(priv->gpio_hp_det)) {
144 snd_soc_jack_new(codec->codec, "Headphones", SND_JACK_HEADPHONE,
145 &simple_card_hp_jack);
146 snd_soc_jack_add_pins(&simple_card_hp_jack,
147 ARRAY_SIZE(simple_card_hp_jack_pins),
148 simple_card_hp_jack_pins);
149
150 simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det;
151 snd_soc_jack_add_gpios(&simple_card_hp_jack, 1,
152 &simple_card_hp_jack_gpio);
153 }
154
155 if (gpio_is_valid(priv->gpio_mic_det)) {
156 snd_soc_jack_new(codec->codec, "Mic Jack", SND_JACK_MICROPHONE,
157 &simple_card_mic_jack);
158 snd_soc_jack_add_pins(&simple_card_mic_jack,
159 ARRAY_SIZE(simple_card_mic_jack_pins),
160 simple_card_mic_jack_pins);
161 simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det;
162 snd_soc_jack_add_gpios(&simple_card_mic_jack, 1,
163 &simple_card_mic_jack_gpio);
164 }
108 return 0; 165 return 0;
109} 166}
110 167
111static int 168static int
112asoc_simple_card_sub_parse_of(struct device_node *np, 169asoc_simple_card_sub_parse_of(struct device_node *np,
113 struct asoc_simple_dai *dai, 170 struct asoc_simple_dai *dai,
114 const struct device_node **p_node, 171 struct device_node **p_node,
115 const char **name) 172 const char **name,
173 int *args_count)
116{ 174{
117 struct device_node *node; 175 struct of_phandle_args args;
118 struct clk *clk; 176 struct clk *clk;
119 u32 val; 177 u32 val;
120 int ret; 178 int ret;
121 179
122 /* 180 /*
123 * get node via "sound-dai = <&phandle port>" 181 * Get node via "sound-dai = <&phandle port>"
124 * it will be used as xxx_of_node on soc_bind_dai_link() 182 * it will be used as xxx_of_node on soc_bind_dai_link()
125 */ 183 */
126 node = of_parse_phandle(np, "sound-dai", 0); 184 ret = of_parse_phandle_with_args(np, "sound-dai",
127 if (!node) 185 "#sound-dai-cells", 0, &args);
128 return -ENODEV; 186 if (ret)
129 *p_node = node; 187 return ret;
188
189 *p_node = args.np;
130 190
131 /* get dai->name */ 191 if (args_count)
192 *args_count = args.args_count;
193
194 /* Get dai->name */
132 ret = snd_soc_of_get_dai_name(np, name); 195 ret = snd_soc_of_get_dai_name(np, name);
133 if (ret < 0) 196 if (ret < 0)
134 return ret; 197 return ret;
135 198
136 /* parse TDM slot */ 199 /* Parse TDM slot */
137 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 200 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
138 if (ret) 201 if (ret)
139 return ret; 202 return ret;
140 203
141 /* 204 /*
142 * dai->sysclk come from 205 * Parse dai->sysclk come from "clocks = <&xxx>"
143 * "clocks = <&xxx>" (if system has common clock) 206 * (if system has common clock)
144 * or "system-clock-frequency = <xxx>" 207 * or "system-clock-frequency = <xxx>"
145 * or device's module clock. 208 * or device's module clock.
146 */ 209 */
@@ -155,7 +218,7 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
155 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) { 218 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
156 dai->sysclk = val; 219 dai->sysclk = val;
157 } else { 220 } else {
158 clk = of_clk_get(node, 0); 221 clk = of_clk_get(args.np, 0);
159 if (!IS_ERR(clk)) 222 if (!IS_ERR(clk))
160 dai->sysclk = clk_get_rate(clk); 223 dai->sysclk = clk_get_rate(clk);
161 } 224 }
@@ -163,12 +226,14 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
163 return 0; 226 return 0;
164} 227}
165 228
166static int simple_card_dai_link_of(struct device_node *node, 229static int asoc_simple_card_dai_link_of(struct device_node *node,
167 struct device *dev, 230 struct simple_card_data *priv,
168 struct snd_soc_dai_link *dai_link, 231 int idx,
169 struct simple_dai_props *dai_props, 232 bool is_top_level_node)
170 bool is_top_level_node)
171{ 233{
234 struct device *dev = simple_priv_to_dev(priv);
235 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
236 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
172 struct device_node *np = NULL; 237 struct device_node *np = NULL;
173 struct device_node *bitclkmaster = NULL; 238 struct device_node *bitclkmaster = NULL;
174 struct device_node *framemaster = NULL; 239 struct device_node *framemaster = NULL;
@@ -176,8 +241,9 @@ static int simple_card_dai_link_of(struct device_node *node,
176 char *name; 241 char *name;
177 char prop[128]; 242 char prop[128];
178 char *prefix = ""; 243 char *prefix = "";
179 int ret; 244 int ret, cpu_args;
180 245
246 /* For single DAI link & old style of DT node */
181 if (is_top_level_node) 247 if (is_top_level_node)
182 prefix = "simple-audio-card,"; 248 prefix = "simple-audio-card,";
183 249
@@ -195,7 +261,8 @@ static int simple_card_dai_link_of(struct device_node *node,
195 261
196 ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai, 262 ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai,
197 &dai_link->cpu_of_node, 263 &dai_link->cpu_of_node,
198 &dai_link->cpu_dai_name); 264 &dai_link->cpu_dai_name,
265 &cpu_args);
199 if (ret < 0) 266 if (ret < 0)
200 goto dai_link_of_err; 267 goto dai_link_of_err;
201 268
@@ -226,14 +293,16 @@ static int simple_card_dai_link_of(struct device_node *node,
226 293
227 ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai, 294 ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai,
228 &dai_link->codec_of_node, 295 &dai_link->codec_of_node,
229 &dai_link->codec_dai_name); 296 &dai_link->codec_dai_name, NULL);
230 if (ret < 0) 297 if (ret < 0)
231 goto dai_link_of_err; 298 goto dai_link_of_err;
232 299
233 if (strlen(prefix) && !bitclkmaster && !framemaster) { 300 if (strlen(prefix) && !bitclkmaster && !framemaster) {
234 /* No dai-link level and master setting was not found from 301 /*
235 sound node level, revert back to legacy DT parsing and 302 * No DAI link level and master setting was found
236 take the settings from codec node. */ 303 * from sound node level, revert back to legacy DT
304 * parsing and take the settings from codec node.
305 */
237 dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n", 306 dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n",
238 __func__); 307 __func__);
239 dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt = 308 dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt =
@@ -262,10 +331,10 @@ static int simple_card_dai_link_of(struct device_node *node,
262 goto dai_link_of_err; 331 goto dai_link_of_err;
263 } 332 }
264 333
265 /* simple-card assumes platform == cpu */ 334 /* Simple Card assumes platform == cpu */
266 dai_link->platform_of_node = dai_link->cpu_of_node; 335 dai_link->platform_of_node = dai_link->cpu_of_node;
267 336
268 /* Link name is created from CPU/CODEC dai name */ 337 /* DAI link name is created from CPU/CODEC dai name */
269 name = devm_kzalloc(dev, 338 name = devm_kzalloc(dev,
270 strlen(dai_link->cpu_dai_name) + 339 strlen(dai_link->cpu_dai_name) +
271 strlen(dai_link->codec_dai_name) + 2, 340 strlen(dai_link->codec_dai_name) + 2,
@@ -274,6 +343,7 @@ static int simple_card_dai_link_of(struct device_node *node,
274 dai_link->codec_dai_name); 343 dai_link->codec_dai_name);
275 dai_link->name = dai_link->stream_name = name; 344 dai_link->name = dai_link->stream_name = name;
276 dai_link->ops = &asoc_simple_card_ops; 345 dai_link->ops = &asoc_simple_card_ops;
346 dai_link->init = asoc_simple_card_dai_init;
277 347
278 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); 348 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
279 dev_dbg(dev, "\tcpu : %s / %04x / %d\n", 349 dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
@@ -285,6 +355,18 @@ static int simple_card_dai_link_of(struct device_node *node,
285 dai_props->codec_dai.fmt, 355 dai_props->codec_dai.fmt,
286 dai_props->codec_dai.sysclk); 356 dai_props->codec_dai.sysclk);
287 357
358 /*
359 * In soc_bind_dai_link() will check cpu name after
360 * of_node matching if dai_link has cpu_dai_name.
361 * but, it will never match if name was created by
362 * fmt_single_name() remove cpu_dai_name if cpu_args
363 * was 0. See:
364 * fmt_single_name()
365 * fmt_multiple_name()
366 */
367 if (!cpu_args)
368 dai_link->cpu_dai_name = NULL;
369
288dai_link_of_err: 370dai_link_of_err:
289 if (np) 371 if (np)
290 of_node_put(np); 372 of_node_put(np);
@@ -296,19 +378,19 @@ dai_link_of_err:
296} 378}
297 379
298static int asoc_simple_card_parse_of(struct device_node *node, 380static int asoc_simple_card_parse_of(struct device_node *node,
299 struct simple_card_data *priv, 381 struct simple_card_data *priv)
300 struct device *dev,
301 int multi)
302{ 382{
303 struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; 383 struct device *dev = simple_priv_to_dev(priv);
304 struct simple_dai_props *dai_props = priv->dai_props;
305 u32 val; 384 u32 val;
306 int ret; 385 int ret;
307 386
308 /* parsing the card name from DT */ 387 if (!node)
388 return -EINVAL;
389
390 /* Parse the card name from DT */
309 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); 391 snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
310 392
311 /* off-codec widgets */ 393 /* The off-codec widgets */
312 if (of_property_read_bool(node, "simple-audio-card,widgets")) { 394 if (of_property_read_bool(node, "simple-audio-card,widgets")) {
313 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, 395 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
314 "simple-audio-card,widgets"); 396 "simple-audio-card,widgets");
@@ -332,32 +414,45 @@ static int asoc_simple_card_parse_of(struct device_node *node,
332 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ? 414 dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
333 priv->snd_card.name : ""); 415 priv->snd_card.name : "");
334 416
335 if (multi) { 417 /* Single/Muti DAI link(s) & New style of DT node */
418 if (of_get_child_by_name(node, "simple-audio-card,dai-link")) {
336 struct device_node *np = NULL; 419 struct device_node *np = NULL;
337 int i; 420 int i = 0;
338 for (i = 0; (np = of_get_next_child(node, np)); i++) { 421
422 for_each_child_of_node(node, np) {
339 dev_dbg(dev, "\tlink %d:\n", i); 423 dev_dbg(dev, "\tlink %d:\n", i);
340 ret = simple_card_dai_link_of(np, dev, dai_link + i, 424 ret = asoc_simple_card_dai_link_of(np, priv,
341 dai_props + i, false); 425 i, false);
342 if (ret < 0) { 426 if (ret < 0) {
343 of_node_put(np); 427 of_node_put(np);
344 return ret; 428 return ret;
345 } 429 }
430 i++;
346 } 431 }
347 } else { 432 } else {
348 ret = simple_card_dai_link_of(node, dev, dai_link, dai_props, 433 /* For single DAI link & old style of DT node */
349 true); 434 ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
350 if (ret < 0) 435 if (ret < 0)
351 return ret; 436 return ret;
352 } 437 }
353 438
439 priv->gpio_hp_det = of_get_named_gpio(node,
440 "simple-audio-card,hp-det-gpio", 0);
441 if (priv->gpio_hp_det == -EPROBE_DEFER)
442 return -EPROBE_DEFER;
443
444 priv->gpio_mic_det = of_get_named_gpio(node,
445 "simple-audio-card,mic-det-gpio", 0);
446 if (priv->gpio_mic_det == -EPROBE_DEFER)
447 return -EPROBE_DEFER;
448
354 if (!priv->snd_card.name) 449 if (!priv->snd_card.name)
355 priv->snd_card.name = priv->snd_card.dai_link->name; 450 priv->snd_card.name = priv->snd_card.dai_link->name;
356 451
357 return 0; 452 return 0;
358} 453}
359 454
360/* update the reference count of the devices nodes at end of probe */ 455/* Decrease the reference count of the device nodes */
361static int asoc_simple_card_unref(struct platform_device *pdev) 456static int asoc_simple_card_unref(struct platform_device *pdev)
362{ 457{
363 struct snd_soc_card *card = platform_get_drvdata(pdev); 458 struct snd_soc_card *card = platform_get_drvdata(pdev);
@@ -384,34 +479,29 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
384 struct snd_soc_dai_link *dai_link; 479 struct snd_soc_dai_link *dai_link;
385 struct device_node *np = pdev->dev.of_node; 480 struct device_node *np = pdev->dev.of_node;
386 struct device *dev = &pdev->dev; 481 struct device *dev = &pdev->dev;
387 int num_links, multi, ret; 482 int num_links, ret;
388 483
389 /* get the number of DAI links */ 484 /* Get the number of DAI links */
390 if (np && of_get_child_by_name(np, "simple-audio-card,dai-link")) { 485 if (np && of_get_child_by_name(np, "simple-audio-card,dai-link"))
391 num_links = of_get_child_count(np); 486 num_links = of_get_child_count(np);
392 multi = 1; 487 else
393 } else {
394 num_links = 1; 488 num_links = 1;
395 multi = 0;
396 }
397 489
398 /* allocate the private data and the DAI link array */ 490 /* Allocate the private data and the DAI link array */
399 priv = devm_kzalloc(dev, 491 priv = devm_kzalloc(dev,
400 sizeof(*priv) + sizeof(*dai_link) * num_links, 492 sizeof(*priv) + sizeof(*dai_link) * num_links,
401 GFP_KERNEL); 493 GFP_KERNEL);
402 if (!priv) 494 if (!priv)
403 return -ENOMEM; 495 return -ENOMEM;
404 496
405 /* 497 /* Init snd_soc_card */
406 * init snd_soc_card
407 */
408 priv->snd_card.owner = THIS_MODULE; 498 priv->snd_card.owner = THIS_MODULE;
409 priv->snd_card.dev = dev; 499 priv->snd_card.dev = dev;
410 dai_link = priv->dai_link; 500 dai_link = priv->dai_link;
411 priv->snd_card.dai_link = dai_link; 501 priv->snd_card.dai_link = dai_link;
412 priv->snd_card.num_links = num_links; 502 priv->snd_card.num_links = num_links;
413 503
414 /* get room for the other properties */ 504 /* Get room for the other properties */
415 priv->dai_props = devm_kzalloc(dev, 505 priv->dai_props = devm_kzalloc(dev,
416 sizeof(*priv->dai_props) * num_links, 506 sizeof(*priv->dai_props) * num_links,
417 GFP_KERNEL); 507 GFP_KERNEL);
@@ -420,25 +510,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
420 510
421 if (np && of_device_is_available(np)) { 511 if (np && of_device_is_available(np)) {
422 512
423 ret = asoc_simple_card_parse_of(np, priv, dev, multi); 513 ret = asoc_simple_card_parse_of(np, priv);
424 if (ret < 0) { 514 if (ret < 0) {
425 if (ret != -EPROBE_DEFER) 515 if (ret != -EPROBE_DEFER)
426 dev_err(dev, "parse error %d\n", ret); 516 dev_err(dev, "parse error %d\n", ret);
427 goto err; 517 goto err;
428 } 518 }
429 519
430 /*
431 * soc_bind_dai_link() will check cpu name
432 * after of_node matching if dai_link has cpu_dai_name.
433 * but, it will never match if name was created by fmt_single_name()
434 * remove cpu_dai_name to escape name matching.
435 * see
436 * fmt_single_name()
437 * fmt_multiple_name()
438 */
439 if (num_links == 1)
440 dai_link->cpu_dai_name = NULL;
441
442 } else { 520 } else {
443 struct asoc_simple_card_info *cinfo; 521 struct asoc_simple_card_info *cinfo;
444 522
@@ -464,6 +542,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
464 dai_link->codec_name = cinfo->codec; 542 dai_link->codec_name = cinfo->codec;
465 dai_link->cpu_dai_name = cinfo->cpu_dai.name; 543 dai_link->cpu_dai_name = cinfo->cpu_dai.name;
466 dai_link->codec_dai_name = cinfo->codec_dai.name; 544 dai_link->codec_dai_name = cinfo->codec_dai.name;
545 dai_link->init = asoc_simple_card_dai_init;
467 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai, 546 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
468 sizeof(priv->dai_props->cpu_dai)); 547 sizeof(priv->dai_props->cpu_dai));
469 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, 548 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
@@ -473,11 +552,6 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
473 priv->dai_props->codec_dai.fmt |= cinfo->daifmt; 552 priv->dai_props->codec_dai.fmt |= cinfo->daifmt;
474 } 553 }
475 554
476 /*
477 * init snd_soc_dai_link
478 */
479 dai_link->init = asoc_simple_card_dai_init;
480
481 snd_soc_card_set_drvdata(&priv->snd_card, priv); 555 snd_soc_card_set_drvdata(&priv->snd_card, priv);
482 556
483 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 557 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
@@ -491,6 +565,16 @@ err:
491 565
492static int asoc_simple_card_remove(struct platform_device *pdev) 566static int asoc_simple_card_remove(struct platform_device *pdev)
493{ 567{
568 struct snd_soc_card *card = platform_get_drvdata(pdev);
569 struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
570
571 if (gpio_is_valid(priv->gpio_hp_det))
572 snd_soc_jack_free_gpios(&simple_card_hp_jack, 1,
573 &simple_card_hp_jack_gpio);
574 if (gpio_is_valid(priv->gpio_mic_det))
575 snd_soc_jack_free_gpios(&simple_card_mic_jack, 1,
576 &simple_card_mic_jack_gpio);
577
494 return asoc_simple_card_unref(pdev); 578 return asoc_simple_card_unref(pdev);
495} 579}
496 580
diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c
index 3a730374e259..186dc7f33a55 100644
--- a/sound/soc/sirf/sirf-usp.c
+++ b/sound/soc/sirf/sirf-usp.c
@@ -100,6 +100,16 @@ static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai,
100 return -EINVAL; 100 return -EINVAL;
101 } 101 }
102 102
103 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
104 case SND_SOC_DAIFMT_NB_NF:
105 break;
106 case SND_SOC_DAIFMT_IB_NF:
107 usp->daifmt_format |= (fmt & SND_SOC_DAIFMT_INV_MASK);
108 break;
109 default:
110 return -EINVAL;
111 }
112
103 return 0; 113 return 0;
104} 114}
105 115
@@ -177,7 +187,7 @@ static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream,
177 187
178 shifter_len = data_len; 188 shifter_len = data_len;
179 189
180 switch (usp->daifmt_format) { 190 switch (usp->daifmt_format & SND_SOC_DAIFMT_FORMAT_MASK) {
181 case SND_SOC_DAIFMT_I2S: 191 case SND_SOC_DAIFMT_I2S:
182 regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, 192 regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL,
183 USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG); 193 USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG);
@@ -193,6 +203,18 @@ static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream,
193 return -EINVAL; 203 return -EINVAL;
194 } 204 }
195 205
206 switch (usp->daifmt_format & SND_SOC_DAIFMT_INV_MASK) {
207 case SND_SOC_DAIFMT_NB_NF:
208 break;
209 case SND_SOC_DAIFMT_IB_NF:
210 regmap_update_bits(usp->regmap, USP_MODE1,
211 USP_RXD_ACT_EDGE_FALLING | USP_TXD_ACT_EDGE_FALLING,
212 USP_RXD_ACT_EDGE_FALLING);
213 break;
214 default:
215 return -EINVAL;
216 }
217
196 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 218 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
197 regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL, 219 regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL,
198 USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK 220 USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK