diff options
| -rw-r--r-- | Documentation/devicetree/bindings/sound/samsung,odroid.txt | 6 | ||||
| -rw-r--r-- | include/sound/rt5677.h | 45 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5665.c | 53 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5665.h | 21 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5670.c | 60 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5677.c | 80 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5677.h | 30 | ||||
| -rw-r--r-- | sound/soc/samsung/i2s.c | 45 | ||||
| -rw-r--r-- | sound/soc/samsung/idma.c | 4 | ||||
| -rw-r--r-- | sound/soc/samsung/jive_wm8750.c | 2 | ||||
| -rw-r--r-- | sound/soc/samsung/odroid.c | 44 | ||||
| -rw-r--r-- | sound/soc/samsung/pcm.c | 8 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c-i2s-v2.c | 14 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c-i2s-v2.h | 7 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c2412-i2s.c | 15 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c24xx-i2s.c | 11 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c24xx_simtec.c | 2 | ||||
| -rw-r--r-- | sound/soc/samsung/s3c24xx_uda134x.c | 3 | ||||
| -rw-r--r-- | sound/soc/samsung/smdk_spdif.c | 2 | ||||
| -rw-r--r-- | sound/soc/samsung/spdif.c | 8 | ||||
| -rw-r--r-- | sound/soc/samsung/tm2_wm5110.c | 4 |
21 files changed, 287 insertions, 177 deletions
diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.txt b/Documentation/devicetree/bindings/sound/samsung,odroid.txt index c30934dd975b..625b1b18fd02 100644 --- a/Documentation/devicetree/bindings/sound/samsung,odroid.txt +++ b/Documentation/devicetree/bindings/sound/samsung,odroid.txt | |||
| @@ -7,9 +7,6 @@ Required properties: | |||
| 7 | - model - the user-visible name of this sound complex | 7 | - model - the user-visible name of this sound complex |
| 8 | - clocks - should contain entries matching clock names in the clock-names | 8 | - clocks - should contain entries matching clock names in the clock-names |
| 9 | property | 9 | property |
| 10 | - clock-names - should contain following entries: | ||
| 11 | - "epll" - indicating the EPLL output clock | ||
| 12 | - "i2s_rclk" - indicating the RCLK (root) clock of the I2S0 controller | ||
| 13 | - samsung,audio-widgets - this property specifies off-codec audio elements | 10 | - samsung,audio-widgets - this property specifies off-codec audio elements |
| 14 | like headphones or speakers, for details see widgets.txt | 11 | like headphones or speakers, for details see widgets.txt |
| 15 | - samsung,audio-routing - a list of the connections between audio | 12 | - samsung,audio-routing - a list of the connections between audio |
| @@ -46,9 +43,6 @@ sound { | |||
| 46 | "IN1", "Mic Jack", | 43 | "IN1", "Mic Jack", |
| 47 | "Mic Jack", "MICBIAS"; | 44 | "Mic Jack", "MICBIAS"; |
| 48 | 45 | ||
| 49 | clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>; | ||
| 50 | clock-names = "epll", "sclk_i2s"; | ||
| 51 | |||
| 52 | cpu { | 46 | cpu { |
| 53 | sound-dai = <&i2s0 0>; | 47 | sound-dai = <&i2s0 0>; |
| 54 | }; | 48 | }; |
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h deleted file mode 100644 index a6207043ac3c..000000000000 --- a/include/sound/rt5677.h +++ /dev/null | |||
| @@ -1,45 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/sound/rt5677.h -- Platform data for RT5677 | ||
| 3 | * | ||
| 4 | * Copyright 2013 Realtek Semiconductor Corp. | ||
| 5 | * Author: Oder Chiou <oder_chiou@realtek.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __LINUX_SND_RT5677_H | ||
| 13 | #define __LINUX_SND_RT5677_H | ||
| 14 | |||
| 15 | enum rt5677_dmic2_clk { | ||
| 16 | RT5677_DMIC_CLK1 = 0, | ||
| 17 | RT5677_DMIC_CLK2 = 1, | ||
| 18 | }; | ||
| 19 | |||
| 20 | |||
| 21 | struct rt5677_platform_data { | ||
| 22 | /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ | ||
| 23 | bool in1_diff; | ||
| 24 | bool in2_diff; | ||
| 25 | bool lout1_diff; | ||
| 26 | bool lout2_diff; | ||
| 27 | bool lout3_diff; | ||
| 28 | /* DMIC2 clock source selection */ | ||
| 29 | enum rt5677_dmic2_clk dmic2_clk_pin; | ||
| 30 | |||
| 31 | /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ | ||
| 32 | u8 gpio_config[6]; | ||
| 33 | |||
| 34 | /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */ | ||
| 35 | unsigned int jd1_gpio; | ||
| 36 | /* jd2 and jd3 can select 0 ~ 3 as | ||
| 37 | OFF, GPIO4, GPIO5 and GPIO6 respectively */ | ||
| 38 | unsigned int jd2_gpio; | ||
| 39 | unsigned int jd3_gpio; | ||
| 40 | |||
| 41 | /* Set MICBIAS1 VDD 1v8 or 3v3 */ | ||
| 42 | bool micbias1_vdd_3v3; | ||
| 43 | }; | ||
| 44 | |||
| 45 | #endif | ||
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 02493bbb07e1..f05d362c4e23 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c | |||
| @@ -1381,6 +1381,16 @@ static void rt5665_jack_detect_handler(struct work_struct *work) | |||
| 1381 | mutex_unlock(&rt5665->calibrate_mutex); | 1381 | mutex_unlock(&rt5665->calibrate_mutex); |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| 1384 | static const char * const rt5665_clk_sync[] = { | ||
| 1385 | "I2S1_1", "I2S1_2", "I2S2", "I2S3", "IF2 Slave", "IF3 Slave" | ||
| 1386 | }; | ||
| 1387 | |||
| 1388 | static const struct soc_enum rt5665_enum[] = { | ||
| 1389 | SOC_ENUM_SINGLE(RT5665_I2S1_SDP, 11, 5, rt5665_clk_sync), | ||
| 1390 | SOC_ENUM_SINGLE(RT5665_I2S2_SDP, 11, 5, rt5665_clk_sync), | ||
| 1391 | SOC_ENUM_SINGLE(RT5665_I2S3_SDP, 11, 5, rt5665_clk_sync), | ||
| 1392 | }; | ||
| 1393 | |||
| 1384 | static const struct snd_kcontrol_new rt5665_snd_controls[] = { | 1394 | static const struct snd_kcontrol_new rt5665_snd_controls[] = { |
| 1385 | /* Headphone Output Volume */ | 1395 | /* Headphone Output Volume */ |
| 1386 | SOC_DOUBLE_R_EXT_TLV("Headphone Playback Volume", RT5665_HPL_GAIN, | 1396 | SOC_DOUBLE_R_EXT_TLV("Headphone Playback Volume", RT5665_HPL_GAIN, |
| @@ -1392,6 +1402,9 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = { | |||
| 1392 | RT5665_L_VOL_SFT, 15, 1, snd_soc_get_volsw, | 1402 | RT5665_L_VOL_SFT, 15, 1, snd_soc_get_volsw, |
| 1393 | rt5665_mono_vol_put, mono_vol_tlv), | 1403 | rt5665_mono_vol_put, mono_vol_tlv), |
| 1394 | 1404 | ||
| 1405 | SOC_SINGLE_TLV("MONOVOL Playback Volume", RT5665_MONO_OUT, | ||
| 1406 | RT5665_L_VOL_SFT, 39, 1, out_vol_tlv), | ||
| 1407 | |||
| 1395 | /* Output Volume */ | 1408 | /* Output Volume */ |
| 1396 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5665_LOUT, RT5665_L_VOL_SFT, | 1409 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5665_LOUT, RT5665_L_VOL_SFT, |
| 1397 | RT5665_R_VOL_SFT, 39, 1, out_vol_tlv), | 1410 | RT5665_R_VOL_SFT, 39, 1, out_vol_tlv), |
| @@ -1446,6 +1459,11 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = { | |||
| 1446 | SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5665_STO2_ADC_BOOST, | 1459 | SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5665_STO2_ADC_BOOST, |
| 1447 | RT5665_STO2_ADC_L_BST_SFT, RT5665_STO2_ADC_R_BST_SFT, | 1460 | RT5665_STO2_ADC_L_BST_SFT, RT5665_STO2_ADC_R_BST_SFT, |
| 1448 | 3, 0, adc_bst_tlv), | 1461 | 3, 0, adc_bst_tlv), |
| 1462 | |||
| 1463 | /* I2S3 CLK Source */ | ||
| 1464 | SOC_ENUM("I2S1 Master Clk Sel", rt5665_enum[0]), | ||
| 1465 | SOC_ENUM("I2S2 Master Clk Sel", rt5665_enum[1]), | ||
| 1466 | SOC_ENUM("I2S3 Master Clk Sel", rt5665_enum[2]), | ||
| 1449 | }; | 1467 | }; |
| 1450 | 1468 | ||
| 1451 | /** | 1469 | /** |
| @@ -4098,9 +4116,12 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, | |||
| 4098 | rt5665->lrck[dai->id] = params_rate(params); | 4116 | rt5665->lrck[dai->id] = params_rate(params); |
| 4099 | pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]); | 4117 | pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]); |
| 4100 | if (pre_div < 0) { | 4118 | if (pre_div < 0) { |
| 4101 | dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", | 4119 | dev_warn(codec->dev, "Force using PLL"); |
| 4102 | rt5665->lrck[dai->id], dai->id); | 4120 | snd_soc_codec_set_pll(codec, 0, RT5665_PLL1_S_MCLK, |
| 4103 | return -EINVAL; | 4121 | rt5665->sysclk, rt5665->lrck[dai->id] * 512); |
| 4122 | snd_soc_codec_set_sysclk(codec, RT5665_SCLK_S_PLL1, 0, | ||
| 4123 | rt5665->lrck[dai->id] * 512, 0); | ||
| 4124 | pre_div = 1; | ||
| 4104 | } | 4125 | } |
| 4105 | frame_size = snd_soc_params_to_frame_size(params); | 4126 | frame_size = snd_soc_params_to_frame_size(params); |
| 4106 | if (frame_size < 0) { | 4127 | if (frame_size < 0) { |
| @@ -4183,6 +4204,15 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, | |||
| 4183 | break; | 4204 | break; |
| 4184 | } | 4205 | } |
| 4185 | 4206 | ||
| 4207 | if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) { | ||
| 4208 | snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, | ||
| 4209 | RT5665_I2S2_M_PD_MASK, pre_div << RT5665_I2S2_M_PD_SFT); | ||
| 4210 | } | ||
| 4211 | if (rt5665->master[RT5665_AIF3]) { | ||
| 4212 | snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, | ||
| 4213 | RT5665_I2S3_M_PD_MASK, pre_div << RT5665_I2S3_M_PD_SFT); | ||
| 4214 | } | ||
| 4215 | |||
| 4186 | return 0; | 4216 | return 0; |
| 4187 | } | 4217 | } |
| 4188 | 4218 | ||
| @@ -4259,7 +4289,7 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
| 4259 | int source, unsigned int freq, int dir) | 4289 | int source, unsigned int freq, int dir) |
| 4260 | { | 4290 | { |
| 4261 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); | 4291 | struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); |
| 4262 | unsigned int reg_val = 0; | 4292 | unsigned int reg_val = 0, src = 0; |
| 4263 | 4293 | ||
| 4264 | if (freq == rt5665->sysclk && clk_id == rt5665->sysclk_src) | 4294 | if (freq == rt5665->sysclk && clk_id == rt5665->sysclk_src) |
| 4265 | return 0; | 4295 | return 0; |
| @@ -4267,12 +4297,15 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
| 4267 | switch (clk_id) { | 4297 | switch (clk_id) { |
| 4268 | case RT5665_SCLK_S_MCLK: | 4298 | case RT5665_SCLK_S_MCLK: |
| 4269 | reg_val |= RT5665_SCLK_SRC_MCLK; | 4299 | reg_val |= RT5665_SCLK_SRC_MCLK; |
| 4300 | src = RT5665_CLK_SRC_MCLK; | ||
| 4270 | break; | 4301 | break; |
| 4271 | case RT5665_SCLK_S_PLL1: | 4302 | case RT5665_SCLK_S_PLL1: |
| 4272 | reg_val |= RT5665_SCLK_SRC_PLL1; | 4303 | reg_val |= RT5665_SCLK_SRC_PLL1; |
| 4304 | src = RT5665_CLK_SRC_PLL1; | ||
| 4273 | break; | 4305 | break; |
| 4274 | case RT5665_SCLK_S_RCCLK: | 4306 | case RT5665_SCLK_S_RCCLK: |
| 4275 | reg_val |= RT5665_SCLK_SRC_RCCLK; | 4307 | reg_val |= RT5665_SCLK_SRC_RCCLK; |
| 4308 | src = RT5665_CLK_SRC_RCCLK; | ||
| 4276 | break; | 4309 | break; |
| 4277 | default: | 4310 | default: |
| 4278 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | 4311 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); |
| @@ -4280,6 +4313,16 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
| 4280 | } | 4313 | } |
| 4281 | snd_soc_update_bits(codec, RT5665_GLB_CLK, | 4314 | snd_soc_update_bits(codec, RT5665_GLB_CLK, |
| 4282 | RT5665_SCLK_SRC_MASK, reg_val); | 4315 | RT5665_SCLK_SRC_MASK, reg_val); |
| 4316 | |||
| 4317 | if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) { | ||
| 4318 | snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, | ||
| 4319 | RT5665_I2S2_SRC_MASK, src << RT5665_I2S2_SRC_SFT); | ||
| 4320 | } | ||
| 4321 | if (rt5665->master[RT5665_AIF3]) { | ||
| 4322 | snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, | ||
| 4323 | RT5665_I2S3_SRC_MASK, src << RT5665_I2S3_SRC_SFT); | ||
| 4324 | } | ||
| 4325 | |||
| 4283 | rt5665->sysclk = freq; | 4326 | rt5665->sysclk = freq; |
| 4284 | rt5665->sysclk_src = clk_id; | 4327 | rt5665->sysclk_src = clk_id; |
| 4285 | 4328 | ||
| @@ -4927,7 +4970,7 @@ MODULE_DEVICE_TABLE(of, rt5665_of_match); | |||
| 4927 | #endif | 4970 | #endif |
| 4928 | 4971 | ||
| 4929 | #ifdef CONFIG_ACPI | 4972 | #ifdef CONFIG_ACPI |
| 4930 | static struct acpi_device_id rt5665_acpi_match[] = { | 4973 | static const struct acpi_device_id rt5665_acpi_match[] = { |
| 4931 | {"10EC5665", 0,}, | 4974 | {"10EC5665", 0,}, |
| 4932 | {"10EC5666", 0,}, | 4975 | {"10EC5666", 0,}, |
| 4933 | {"10EC5668", 0,}, | 4976 | {"10EC5668", 0,}, |
diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h index d95249c4c47b..5ddebd6a4a1b 100644 --- a/sound/soc/codecs/rt5665.h +++ b/sound/soc/codecs/rt5665.h | |||
| @@ -1628,6 +1628,27 @@ | |||
| 1628 | #define RT5665_PWR_CLK1M_PD (0x0 << 8) | 1628 | #define RT5665_PWR_CLK1M_PD (0x0 << 8) |
| 1629 | #define RT5665_PWR_CLK1M_PU (0x1 << 8) | 1629 | #define RT5665_PWR_CLK1M_PU (0x1 << 8) |
| 1630 | 1630 | ||
| 1631 | /* I2S Master Mode Clock Control 1 (0x00a0) */ | ||
| 1632 | #define RT5665_CLK_SRC_MCLK (0x0) | ||
| 1633 | #define RT5665_CLK_SRC_PLL1 (0x1) | ||
| 1634 | #define RT5665_CLK_SRC_RCCLK (0x2) | ||
| 1635 | #define RT5665_I2S_PD_1 (0x0) | ||
| 1636 | #define RT5665_I2S_PD_2 (0x1) | ||
| 1637 | #define RT5665_I2S_PD_3 (0x2) | ||
| 1638 | #define RT5665_I2S_PD_4 (0x3) | ||
| 1639 | #define RT5665_I2S_PD_6 (0x4) | ||
| 1640 | #define RT5665_I2S_PD_8 (0x5) | ||
| 1641 | #define RT5665_I2S_PD_12 (0x6) | ||
| 1642 | #define RT5665_I2S_PD_16 (0x7) | ||
| 1643 | #define RT5665_I2S2_SRC_MASK (0x3 << 12) | ||
| 1644 | #define RT5665_I2S2_SRC_SFT 12 | ||
| 1645 | #define RT5665_I2S2_M_PD_MASK (0x7 << 8) | ||
| 1646 | #define RT5665_I2S2_M_PD_SFT 8 | ||
| 1647 | #define RT5665_I2S3_SRC_MASK (0x3 << 4) | ||
| 1648 | #define RT5665_I2S3_SRC_SFT 4 | ||
| 1649 | #define RT5665_I2S3_M_PD_MASK (0x7 << 0) | ||
| 1650 | #define RT5665_I2S3_M_PD_SFT 0 | ||
| 1651 | |||
| 1631 | 1652 | ||
| 1632 | /* EQ Control 1 (0x00b0) */ | 1653 | /* EQ Control 1 (0x00b0) */ |
| 1633 | #define RT5665_EQ_SRC_DAC (0x0 << 15) | 1654 | #define RT5665_EQ_SRC_DAC (0x0 << 15) |
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index f2d6a999df6f..9545764ef3eb 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
| @@ -1151,20 +1151,15 @@ static const char * const rt5670_stereo_adc1_src[] = { | |||
| 1151 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER, | 1151 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER, |
| 1152 | RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); | 1152 | RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); |
| 1153 | 1153 | ||
| 1154 | static const struct snd_kcontrol_new rt5670_sto_adc_l1_mux = | 1154 | static const struct snd_kcontrol_new rt5670_sto_adc_1_mux = |
| 1155 | SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5670_stereo1_adc1_enum); | 1155 | SOC_DAPM_ENUM("Stereo1 ADC 1 Mux", rt5670_stereo1_adc1_enum); |
| 1156 | |||
| 1157 | static const struct snd_kcontrol_new rt5670_sto_adc_r1_mux = | ||
| 1158 | SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5670_stereo1_adc1_enum); | ||
| 1159 | 1156 | ||
| 1160 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER, | 1157 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER, |
| 1161 | RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); | 1158 | RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); |
| 1162 | 1159 | ||
| 1163 | static const struct snd_kcontrol_new rt5670_sto2_adc_l1_mux = | 1160 | static const struct snd_kcontrol_new rt5670_sto2_adc_1_mux = |
| 1164 | SOC_DAPM_ENUM("Stereo2 ADC L1 source", rt5670_stereo2_adc1_enum); | 1161 | SOC_DAPM_ENUM("Stereo2 ADC 1 Mux", rt5670_stereo2_adc1_enum); |
| 1165 | 1162 | ||
| 1166 | static const struct snd_kcontrol_new rt5670_sto2_adc_r1_mux = | ||
| 1167 | SOC_DAPM_ENUM("Stereo2 ADC R1 source", rt5670_stereo2_adc1_enum); | ||
| 1168 | 1163 | ||
| 1169 | /* MX-27 MX-26 [11] */ | 1164 | /* MX-27 MX-26 [11] */ |
| 1170 | static const char * const rt5670_stereo_adc2_src[] = { | 1165 | static const char * const rt5670_stereo_adc2_src[] = { |
| @@ -1174,20 +1169,15 @@ static const char * const rt5670_stereo_adc2_src[] = { | |||
| 1174 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER, | 1169 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER, |
| 1175 | RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); | 1170 | RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); |
| 1176 | 1171 | ||
| 1177 | static const struct snd_kcontrol_new rt5670_sto_adc_l2_mux = | 1172 | static const struct snd_kcontrol_new rt5670_sto_adc_2_mux = |
| 1178 | SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5670_stereo1_adc2_enum); | 1173 | SOC_DAPM_ENUM("Stereo1 ADC 2 Mux", rt5670_stereo1_adc2_enum); |
| 1179 | |||
| 1180 | static const struct snd_kcontrol_new rt5670_sto_adc_r2_mux = | ||
| 1181 | SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5670_stereo1_adc2_enum); | ||
| 1182 | 1174 | ||
| 1183 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER, | 1175 | static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER, |
| 1184 | RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); | 1176 | RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); |
| 1185 | 1177 | ||
| 1186 | static const struct snd_kcontrol_new rt5670_sto2_adc_l2_mux = | 1178 | static const struct snd_kcontrol_new rt5670_sto2_adc_2_mux = |
| 1187 | SOC_DAPM_ENUM("Stereo2 ADC L2 source", rt5670_stereo2_adc2_enum); | 1179 | SOC_DAPM_ENUM("Stereo2 ADC 2 Mux", rt5670_stereo2_adc2_enum); |
| 1188 | 1180 | ||
| 1189 | static const struct snd_kcontrol_new rt5670_sto2_adc_r2_mux = | ||
| 1190 | SOC_DAPM_ENUM("Stereo2 ADC R2 source", rt5670_stereo2_adc2_enum); | ||
| 1191 | 1181 | ||
| 1192 | /* MX-27 MX26 [10] */ | 1182 | /* MX-27 MX26 [10] */ |
| 1193 | static const char * const rt5670_stereo_adc_src[] = { | 1183 | static const char * const rt5670_stereo_adc_src[] = { |
| @@ -1642,23 +1632,23 @@ static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = { | |||
| 1642 | SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, | 1632 | SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, |
| 1643 | &rt5670_sto1_dmic_mux), | 1633 | &rt5670_sto1_dmic_mux), |
| 1644 | SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, | 1634 | SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, |
| 1645 | &rt5670_sto_adc_l2_mux), | 1635 | &rt5670_sto_adc_2_mux), |
| 1646 | SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, | 1636 | SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, |
| 1647 | &rt5670_sto_adc_r2_mux), | 1637 | &rt5670_sto_adc_2_mux), |
| 1648 | SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, | 1638 | SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, |
| 1649 | &rt5670_sto_adc_l1_mux), | 1639 | &rt5670_sto_adc_1_mux), |
| 1650 | SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, | 1640 | SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, |
| 1651 | &rt5670_sto_adc_r1_mux), | 1641 | &rt5670_sto_adc_1_mux), |
| 1652 | SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0, | 1642 | SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0, |
| 1653 | &rt5670_sto2_dmic_mux), | 1643 | &rt5670_sto2_dmic_mux), |
| 1654 | SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0, | 1644 | SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0, |
| 1655 | &rt5670_sto2_adc_l2_mux), | 1645 | &rt5670_sto2_adc_2_mux), |
| 1656 | SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0, | 1646 | SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0, |
| 1657 | &rt5670_sto2_adc_r2_mux), | 1647 | &rt5670_sto2_adc_2_mux), |
| 1658 | SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0, | 1648 | SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0, |
| 1659 | &rt5670_sto2_adc_l1_mux), | 1649 | &rt5670_sto2_adc_1_mux), |
| 1660 | SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0, | 1650 | SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0, |
| 1661 | &rt5670_sto2_adc_r1_mux), | 1651 | &rt5670_sto2_adc_1_mux), |
| 1662 | SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0, | 1652 | SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0, |
| 1663 | &rt5670_sto2_adc_lr_mux), | 1653 | &rt5670_sto2_adc_lr_mux), |
| 1664 | SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0, | 1654 | SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0, |
| @@ -2743,6 +2733,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { | |||
| 2743 | .formats = RT5670_FORMATS, | 2733 | .formats = RT5670_FORMATS, |
| 2744 | }, | 2734 | }, |
| 2745 | .ops = &rt5670_aif_dai_ops, | 2735 | .ops = &rt5670_aif_dai_ops, |
| 2736 | .symmetric_rates = 1, | ||
| 2746 | }, | 2737 | }, |
| 2747 | { | 2738 | { |
| 2748 | .name = "rt5670-aif2", | 2739 | .name = "rt5670-aif2", |
| @@ -2762,6 +2753,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { | |||
| 2762 | .formats = RT5670_FORMATS, | 2753 | .formats = RT5670_FORMATS, |
| 2763 | }, | 2754 | }, |
| 2764 | .ops = &rt5670_aif_dai_ops, | 2755 | .ops = &rt5670_aif_dai_ops, |
| 2756 | .symmetric_rates = 1, | ||
| 2765 | }, | 2757 | }, |
| 2766 | }; | 2758 | }; |
| 2767 | 2759 | ||
| @@ -2859,6 +2851,17 @@ static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode2[] = { | |||
| 2859 | {} | 2851 | {} |
| 2860 | }; | 2852 | }; |
| 2861 | 2853 | ||
| 2854 | static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode3[] = { | ||
| 2855 | { | ||
| 2856 | .ident = "Dell Venue 8 Pro 5855", | ||
| 2857 | .matches = { | ||
| 2858 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 2859 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5855"), | ||
| 2860 | }, | ||
| 2861 | }, | ||
| 2862 | {} | ||
| 2863 | }; | ||
| 2864 | |||
| 2862 | static int rt5670_i2c_probe(struct i2c_client *i2c, | 2865 | static int rt5670_i2c_probe(struct i2c_client *i2c, |
| 2863 | const struct i2c_device_id *id) | 2866 | const struct i2c_device_id *id) |
| 2864 | { | 2867 | { |
| @@ -2888,6 +2891,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, | |||
| 2888 | rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; | 2891 | rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; |
| 2889 | rt5670->pdata.dev_gpio = true; | 2892 | rt5670->pdata.dev_gpio = true; |
| 2890 | rt5670->pdata.jd_mode = 2; | 2893 | rt5670->pdata.jd_mode = 2; |
| 2894 | } else if (dmi_check_system(dmi_platform_intel_bytcht_jdmode3)) { | ||
| 2895 | rt5670->pdata.dmic_en = true; | ||
| 2896 | rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; | ||
| 2897 | rt5670->pdata.dev_gpio = true; | ||
| 2898 | rt5670->pdata.jd_mode = 3; | ||
| 2891 | } | 2899 | } |
| 2892 | 2900 | ||
| 2893 | rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); | 2901 | rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 8dacfdd05d6b..0791fec398fb 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
| 23 | #include <linux/firmware.h> | 23 | #include <linux/firmware.h> |
| 24 | #include <linux/of_device.h> | ||
| 24 | #include <linux/property.h> | 25 | #include <linux/property.h> |
| 25 | #include <sound/core.h> | 26 | #include <sound/core.h> |
| 26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
| @@ -779,9 +780,7 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) | |||
| 779 | return 0; | 780 | return 0; |
| 780 | } | 781 | } |
| 781 | 782 | ||
| 782 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); | ||
| 783 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); | 783 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); |
| 784 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | ||
| 785 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); | 784 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); |
| 786 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | 785 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); |
| 787 | static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0); | 786 | static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0); |
| @@ -4624,35 +4623,27 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 4624 | struct regmap_irq_chip_data *data = rt5677->irq_data; | 4623 | struct regmap_irq_chip_data *data = rt5677->irq_data; |
| 4625 | int irq; | 4624 | int irq; |
| 4626 | 4625 | ||
| 4627 | if (offset >= RT5677_GPIO1 && offset <= RT5677_GPIO3) { | 4626 | if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || |
| 4628 | if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || | 4627 | (rt5677->pdata.jd1_gpio == 2 && |
| 4629 | (rt5677->pdata.jd1_gpio == 2 && | 4628 | offset == RT5677_GPIO2) || |
| 4630 | offset == RT5677_GPIO2) || | 4629 | (rt5677->pdata.jd1_gpio == 3 && |
| 4631 | (rt5677->pdata.jd1_gpio == 3 && | 4630 | offset == RT5677_GPIO3)) { |
| 4632 | offset == RT5677_GPIO3)) { | 4631 | irq = RT5677_IRQ_JD1; |
| 4633 | irq = RT5677_IRQ_JD1; | 4632 | } else if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || |
| 4634 | } else { | 4633 | (rt5677->pdata.jd2_gpio == 2 && |
| 4635 | return -ENXIO; | 4634 | offset == RT5677_GPIO5) || |
| 4636 | } | 4635 | (rt5677->pdata.jd2_gpio == 3 && |
| 4637 | } | 4636 | offset == RT5677_GPIO6)) { |
| 4638 | 4637 | irq = RT5677_IRQ_JD2; | |
| 4639 | if (offset >= RT5677_GPIO4 && offset <= RT5677_GPIO6) { | 4638 | } else if ((rt5677->pdata.jd3_gpio == 1 && |
| 4640 | if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || | 4639 | offset == RT5677_GPIO4) || |
| 4641 | (rt5677->pdata.jd2_gpio == 2 && | 4640 | (rt5677->pdata.jd3_gpio == 2 && |
| 4642 | offset == RT5677_GPIO5) || | 4641 | offset == RT5677_GPIO5) || |
| 4643 | (rt5677->pdata.jd2_gpio == 3 && | 4642 | (rt5677->pdata.jd3_gpio == 3 && |
| 4644 | offset == RT5677_GPIO6)) { | 4643 | offset == RT5677_GPIO6)) { |
| 4645 | irq = RT5677_IRQ_JD2; | 4644 | irq = RT5677_IRQ_JD3; |
| 4646 | } else if ((rt5677->pdata.jd3_gpio == 1 && | 4645 | } else { |
| 4647 | offset == RT5677_GPIO4) || | 4646 | return -ENXIO; |
| 4648 | (rt5677->pdata.jd3_gpio == 2 && | ||
| 4649 | offset == RT5677_GPIO5) || | ||
| 4650 | (rt5677->pdata.jd3_gpio == 3 && | ||
| 4651 | offset == RT5677_GPIO6)) { | ||
| 4652 | irq = RT5677_IRQ_JD3; | ||
| 4653 | } else { | ||
| 4654 | return -ENXIO; | ||
| 4655 | } | ||
| 4656 | } | 4647 | } |
| 4657 | 4648 | ||
| 4658 | return regmap_irq_get_virq(data, irq); | 4649 | return regmap_irq_get_virq(data, irq); |
| @@ -5021,24 +5012,21 @@ static const struct regmap_config rt5677_regmap = { | |||
| 5021 | static const struct i2c_device_id rt5677_i2c_id[] = { | 5012 | static const struct i2c_device_id rt5677_i2c_id[] = { |
| 5022 | { "rt5677", RT5677 }, | 5013 | { "rt5677", RT5677 }, |
| 5023 | { "rt5676", RT5676 }, | 5014 | { "rt5676", RT5676 }, |
| 5024 | { "RT5677CE:00", RT5677 }, | ||
| 5025 | { } | 5015 | { } |
| 5026 | }; | 5016 | }; |
| 5027 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); | 5017 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); |
| 5028 | 5018 | ||
| 5029 | static const struct of_device_id rt5677_of_match[] = { | 5019 | static const struct of_device_id rt5677_of_match[] = { |
| 5030 | { .compatible = "realtek,rt5677", }, | 5020 | { .compatible = "realtek,rt5677", RT5677 }, |
| 5031 | { } | 5021 | { } |
| 5032 | }; | 5022 | }; |
| 5033 | MODULE_DEVICE_TABLE(of, rt5677_of_match); | 5023 | MODULE_DEVICE_TABLE(of, rt5677_of_match); |
| 5034 | 5024 | ||
| 5035 | #ifdef CONFIG_ACPI | ||
| 5036 | static const struct acpi_device_id rt5677_acpi_match[] = { | 5025 | static const struct acpi_device_id rt5677_acpi_match[] = { |
| 5037 | { "RT5677CE", RT5677 }, | 5026 | { "RT5677CE", RT5677 }, |
| 5038 | { } | 5027 | { } |
| 5039 | }; | 5028 | }; |
| 5040 | MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match); | 5029 | MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match); |
| 5041 | #endif | ||
| 5042 | 5030 | ||
| 5043 | static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, | 5031 | static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, |
| 5044 | struct device *dev) | 5032 | struct device *dev) |
| @@ -5148,7 +5136,6 @@ static void rt5677_free_irq(struct i2c_client *i2c) | |||
| 5148 | static int rt5677_i2c_probe(struct i2c_client *i2c, | 5136 | static int rt5677_i2c_probe(struct i2c_client *i2c, |
| 5149 | const struct i2c_device_id *id) | 5137 | const struct i2c_device_id *id) |
| 5150 | { | 5138 | { |
| 5151 | struct rt5677_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
| 5152 | struct rt5677_priv *rt5677; | 5139 | struct rt5677_priv *rt5677; |
| 5153 | int ret; | 5140 | int ret; |
| 5154 | unsigned int val; | 5141 | unsigned int val; |
| @@ -5160,16 +5147,25 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
| 5160 | 5147 | ||
| 5161 | i2c_set_clientdata(i2c, rt5677); | 5148 | i2c_set_clientdata(i2c, rt5677); |
| 5162 | 5149 | ||
| 5163 | rt5677->type = id->driver_data; | 5150 | if (i2c->dev.of_node) { |
| 5151 | const struct of_device_id *match_id; | ||
| 5152 | |||
| 5153 | match_id = of_match_device(rt5677_of_match, &i2c->dev); | ||
| 5154 | if (match_id) | ||
| 5155 | rt5677->type = (enum rt5677_type)match_id->data; | ||
| 5164 | 5156 | ||
| 5165 | if (pdata) | ||
| 5166 | rt5677->pdata = *pdata; | ||
| 5167 | else if (i2c->dev.of_node) | ||
| 5168 | rt5677_read_device_properties(rt5677, &i2c->dev); | 5157 | rt5677_read_device_properties(rt5677, &i2c->dev); |
| 5169 | else if (ACPI_HANDLE(&i2c->dev)) | 5158 | } else if (ACPI_HANDLE(&i2c->dev)) { |
| 5159 | const struct acpi_device_id *acpi_id; | ||
| 5160 | |||
| 5161 | acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev); | ||
| 5162 | if (acpi_id) | ||
| 5163 | rt5677->type = (enum rt5677_type)acpi_id->driver_data; | ||
| 5164 | |||
| 5170 | rt5677_read_acpi_properties(rt5677, &i2c->dev); | 5165 | rt5677_read_acpi_properties(rt5677, &i2c->dev); |
| 5171 | else | 5166 | } else { |
| 5172 | return -EINVAL; | 5167 | return -EINVAL; |
| 5168 | } | ||
| 5173 | 5169 | ||
| 5174 | /* pow-ldo2 and reset are optional. The codec pins may be statically | 5170 | /* pow-ldo2 and reset are optional. The codec pins may be statically |
| 5175 | * connected on the board without gpios. If the gpio device property | 5171 | * connected on the board without gpios. If the gpio device property |
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index d46855a42c40..97239973edc4 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #ifndef __RT5677_H__ | 12 | #ifndef __RT5677_H__ |
| 13 | #define __RT5677_H__ | 13 | #define __RT5677_H__ |
| 14 | 14 | ||
| 15 | #include <sound/rt5677.h> | ||
| 16 | #include <linux/gpio/driver.h> | 15 | #include <linux/gpio/driver.h> |
| 17 | #include <linux/gpio/consumer.h> | 16 | #include <linux/gpio/consumer.h> |
| 18 | 17 | ||
| @@ -1761,6 +1760,35 @@ enum { | |||
| 1761 | RT5677_I2S4_SOURCE = (0x1 << 18), | 1760 | RT5677_I2S4_SOURCE = (0x1 << 18), |
| 1762 | }; | 1761 | }; |
| 1763 | 1762 | ||
| 1763 | enum rt5677_dmic2_clk { | ||
| 1764 | RT5677_DMIC_CLK1 = 0, | ||
| 1765 | RT5677_DMIC_CLK2 = 1, | ||
| 1766 | }; | ||
| 1767 | |||
| 1768 | struct rt5677_platform_data { | ||
| 1769 | /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ | ||
| 1770 | bool in1_diff; | ||
| 1771 | bool in2_diff; | ||
| 1772 | bool lout1_diff; | ||
| 1773 | bool lout2_diff; | ||
| 1774 | bool lout3_diff; | ||
| 1775 | /* DMIC2 clock source selection */ | ||
| 1776 | enum rt5677_dmic2_clk dmic2_clk_pin; | ||
| 1777 | |||
| 1778 | /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ | ||
| 1779 | u8 gpio_config[6]; | ||
| 1780 | |||
| 1781 | /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */ | ||
| 1782 | unsigned int jd1_gpio; | ||
| 1783 | /* jd2 and jd3 can select 0 ~ 3 as | ||
| 1784 | OFF, GPIO4, GPIO5 and GPIO6 respectively */ | ||
| 1785 | unsigned int jd2_gpio; | ||
| 1786 | unsigned int jd3_gpio; | ||
| 1787 | |||
| 1788 | /* Set MICBIAS1 VDD 1v8 or 3v3 */ | ||
| 1789 | bool micbias1_vdd_3v3; | ||
| 1790 | }; | ||
| 1791 | |||
| 1764 | struct rt5677_priv { | 1792 | struct rt5677_priv { |
| 1765 | struct snd_soc_codec *codec; | 1793 | struct snd_soc_codec *codec; |
| 1766 | struct rt5677_platform_data pdata; | 1794 | struct rt5677_platform_data pdata; |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index af3ba4d4ccc5..10a4da06c0a1 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
| @@ -50,6 +50,7 @@ struct samsung_i2s_variant_regs { | |||
| 50 | 50 | ||
| 51 | struct samsung_i2s_dai_data { | 51 | struct samsung_i2s_dai_data { |
| 52 | u32 quirks; | 52 | u32 quirks; |
| 53 | unsigned int pcm_rates; | ||
| 53 | const struct samsung_i2s_variant_regs *i2s_variant_regs; | 54 | const struct samsung_i2s_variant_regs *i2s_variant_regs; |
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| @@ -550,7 +551,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
| 550 | goto err; | 551 | goto err; |
| 551 | } | 552 | } |
| 552 | 553 | ||
| 553 | clk_prepare_enable(i2s->op_clk); | 554 | ret = clk_prepare_enable(i2s->op_clk); |
| 555 | if (ret) | ||
| 556 | goto err; | ||
| 554 | i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); | 557 | i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); |
| 555 | 558 | ||
| 556 | /* Over-ride the other's */ | 559 | /* Over-ride the other's */ |
| @@ -1076,13 +1079,13 @@ static const struct snd_soc_component_driver samsung_i2s_component = { | |||
| 1076 | .name = "samsung-i2s", | 1079 | .name = "samsung-i2s", |
| 1077 | }; | 1080 | }; |
| 1078 | 1081 | ||
| 1079 | #define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 | ||
| 1080 | |||
| 1081 | #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | 1082 | #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |
| 1082 | SNDRV_PCM_FMTBIT_S16_LE | \ | 1083 | SNDRV_PCM_FMTBIT_S16_LE | \ |
| 1083 | SNDRV_PCM_FMTBIT_S24_LE) | 1084 | SNDRV_PCM_FMTBIT_S24_LE) |
| 1084 | 1085 | ||
| 1085 | static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) | 1086 | static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, |
| 1087 | const struct samsung_i2s_dai_data *i2s_dai_data, | ||
| 1088 | bool sec) | ||
| 1086 | { | 1089 | { |
| 1087 | struct i2s_dai *i2s; | 1090 | struct i2s_dai *i2s; |
| 1088 | 1091 | ||
| @@ -1101,13 +1104,13 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) | |||
| 1101 | i2s->i2s_dai_drv.resume = i2s_resume; | 1104 | i2s->i2s_dai_drv.resume = i2s_resume; |
| 1102 | i2s->i2s_dai_drv.playback.channels_min = 1; | 1105 | i2s->i2s_dai_drv.playback.channels_min = 1; |
| 1103 | i2s->i2s_dai_drv.playback.channels_max = 2; | 1106 | i2s->i2s_dai_drv.playback.channels_max = 2; |
| 1104 | i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; | 1107 | i2s->i2s_dai_drv.playback.rates = i2s_dai_data->pcm_rates; |
| 1105 | i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; | 1108 | i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; |
| 1106 | 1109 | ||
| 1107 | if (!sec) { | 1110 | if (!sec) { |
| 1108 | i2s->i2s_dai_drv.capture.channels_min = 1; | 1111 | i2s->i2s_dai_drv.capture.channels_min = 1; |
| 1109 | i2s->i2s_dai_drv.capture.channels_max = 2; | 1112 | i2s->i2s_dai_drv.capture.channels_max = 2; |
| 1110 | i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; | 1113 | i2s->i2s_dai_drv.capture.rates = i2s_dai_data->pcm_rates; |
| 1111 | i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; | 1114 | i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; |
| 1112 | } | 1115 | } |
| 1113 | return i2s; | 1116 | return i2s; |
| @@ -1132,10 +1135,19 @@ static int i2s_runtime_suspend(struct device *dev) | |||
| 1132 | static int i2s_runtime_resume(struct device *dev) | 1135 | static int i2s_runtime_resume(struct device *dev) |
| 1133 | { | 1136 | { |
| 1134 | struct i2s_dai *i2s = dev_get_drvdata(dev); | 1137 | struct i2s_dai *i2s = dev_get_drvdata(dev); |
| 1138 | int ret; | ||
| 1135 | 1139 | ||
| 1136 | clk_prepare_enable(i2s->clk); | 1140 | ret = clk_prepare_enable(i2s->clk); |
| 1137 | if (i2s->op_clk) | 1141 | if (ret) |
| 1138 | clk_prepare_enable(i2s->op_clk); | 1142 | return ret; |
| 1143 | |||
| 1144 | if (i2s->op_clk) { | ||
| 1145 | ret = clk_prepare_enable(i2s->op_clk); | ||
| 1146 | if (ret) { | ||
| 1147 | clk_disable_unprepare(i2s->clk); | ||
| 1148 | return ret; | ||
| 1149 | } | ||
| 1150 | } | ||
| 1139 | 1151 | ||
| 1140 | writel(i2s->suspend_i2scon, i2s->addr + I2SCON); | 1152 | writel(i2s->suspend_i2scon, i2s->addr + I2SCON); |
| 1141 | writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); | 1153 | writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); |
| @@ -1242,7 +1254,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
| 1242 | i2s_dai_data = (struct samsung_i2s_dai_data *) | 1254 | i2s_dai_data = (struct samsung_i2s_dai_data *) |
| 1243 | platform_get_device_id(pdev)->driver_data; | 1255 | platform_get_device_id(pdev)->driver_data; |
| 1244 | 1256 | ||
| 1245 | pri_dai = i2s_alloc_dai(pdev, false); | 1257 | pri_dai = i2s_alloc_dai(pdev, i2s_dai_data, false); |
| 1246 | if (!pri_dai) { | 1258 | if (!pri_dai) { |
| 1247 | dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); | 1259 | dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); |
| 1248 | return -ENOMEM; | 1260 | return -ENOMEM; |
| @@ -1316,7 +1328,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
| 1316 | goto err_disable_clk; | 1328 | goto err_disable_clk; |
| 1317 | 1329 | ||
| 1318 | if (quirks & QUIRK_SEC_DAI) { | 1330 | if (quirks & QUIRK_SEC_DAI) { |
| 1319 | sec_dai = i2s_alloc_dai(pdev, true); | 1331 | sec_dai = i2s_alloc_dai(pdev, i2s_dai_data, true); |
| 1320 | if (!sec_dai) { | 1332 | if (!sec_dai) { |
| 1321 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); | 1333 | dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); |
| 1322 | ret = -ENOMEM; | 1334 | ret = -ENOMEM; |
| @@ -1376,13 +1388,9 @@ err_disable_clk: | |||
| 1376 | 1388 | ||
| 1377 | static int samsung_i2s_remove(struct platform_device *pdev) | 1389 | static int samsung_i2s_remove(struct platform_device *pdev) |
| 1378 | { | 1390 | { |
| 1379 | struct i2s_dai *pri_dai, *sec_dai; | 1391 | struct i2s_dai *pri_dai; |
| 1380 | 1392 | ||
| 1381 | pri_dai = dev_get_drvdata(&pdev->dev); | 1393 | pri_dai = dev_get_drvdata(&pdev->dev); |
| 1382 | sec_dai = pri_dai->sec_dai; | ||
| 1383 | |||
| 1384 | pri_dai->sec_dai = NULL; | ||
| 1385 | sec_dai->pri_dai = NULL; | ||
| 1386 | 1394 | ||
| 1387 | pm_runtime_get_sync(&pdev->dev); | 1395 | pm_runtime_get_sync(&pdev->dev); |
| 1388 | pm_runtime_disable(&pdev->dev); | 1396 | pm_runtime_disable(&pdev->dev); |
| @@ -1452,29 +1460,34 @@ static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = { | |||
| 1452 | 1460 | ||
| 1453 | static const struct samsung_i2s_dai_data i2sv3_dai_type = { | 1461 | static const struct samsung_i2s_dai_data i2sv3_dai_type = { |
| 1454 | .quirks = QUIRK_NO_MUXPSR, | 1462 | .quirks = QUIRK_NO_MUXPSR, |
| 1463 | .pcm_rates = SNDRV_PCM_RATE_8000_96000, | ||
| 1455 | .i2s_variant_regs = &i2sv3_regs, | 1464 | .i2s_variant_regs = &i2sv3_regs, |
| 1456 | }; | 1465 | }; |
| 1457 | 1466 | ||
| 1458 | static const struct samsung_i2s_dai_data i2sv5_dai_type = { | 1467 | static const struct samsung_i2s_dai_data i2sv5_dai_type = { |
| 1459 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | | 1468 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | |
| 1460 | QUIRK_SUPPORTS_IDMA, | 1469 | QUIRK_SUPPORTS_IDMA, |
| 1470 | .pcm_rates = SNDRV_PCM_RATE_8000_96000, | ||
| 1461 | .i2s_variant_regs = &i2sv3_regs, | 1471 | .i2s_variant_regs = &i2sv3_regs, |
| 1462 | }; | 1472 | }; |
| 1463 | 1473 | ||
| 1464 | static const struct samsung_i2s_dai_data i2sv6_dai_type = { | 1474 | static const struct samsung_i2s_dai_data i2sv6_dai_type = { |
| 1465 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | | 1475 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | |
| 1466 | QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, | 1476 | QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, |
| 1477 | .pcm_rates = SNDRV_PCM_RATE_8000_96000, | ||
| 1467 | .i2s_variant_regs = &i2sv6_regs, | 1478 | .i2s_variant_regs = &i2sv6_regs, |
| 1468 | }; | 1479 | }; |
| 1469 | 1480 | ||
| 1470 | static const struct samsung_i2s_dai_data i2sv7_dai_type = { | 1481 | static const struct samsung_i2s_dai_data i2sv7_dai_type = { |
| 1471 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | | 1482 | .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | |
| 1472 | QUIRK_SUPPORTS_TDM, | 1483 | QUIRK_SUPPORTS_TDM, |
| 1484 | .pcm_rates = SNDRV_PCM_RATE_8000_192000, | ||
| 1473 | .i2s_variant_regs = &i2sv7_regs, | 1485 | .i2s_variant_regs = &i2sv7_regs, |
| 1474 | }; | 1486 | }; |
| 1475 | 1487 | ||
| 1476 | static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { | 1488 | static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { |
| 1477 | .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, | 1489 | .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, |
| 1490 | .pcm_rates = SNDRV_PCM_RATE_8000_96000, | ||
| 1478 | .i2s_variant_regs = &i2sv5_i2s1_regs, | 1491 | .i2s_variant_regs = &i2sv5_i2s1_regs, |
| 1479 | }; | 1492 | }; |
| 1480 | 1493 | ||
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 3e408158625d..a635df61f928 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c | |||
| @@ -325,7 +325,7 @@ static int idma_close(struct snd_pcm_substream *substream) | |||
| 325 | return 0; | 325 | return 0; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static struct snd_pcm_ops idma_ops = { | 328 | static const struct snd_pcm_ops idma_ops = { |
| 329 | .open = idma_open, | 329 | .open = idma_open, |
| 330 | .close = idma_close, | 330 | .close = idma_close, |
| 331 | .ioctl = snd_pcm_lib_ioctl, | 331 | .ioctl = snd_pcm_lib_ioctl, |
| @@ -399,7 +399,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr) | |||
| 399 | } | 399 | } |
| 400 | EXPORT_SYMBOL_GPL(idma_reg_addr_init); | 400 | EXPORT_SYMBOL_GPL(idma_reg_addr_init); |
| 401 | 401 | ||
| 402 | static struct snd_soc_platform_driver asoc_idma_platform = { | 402 | static const struct snd_soc_platform_driver asoc_idma_platform = { |
| 403 | .ops = &idma_ops, | 403 | .ops = &idma_ops, |
| 404 | .pcm_new = idma_new, | 404 | .pcm_new = idma_new, |
| 405 | .pcm_free = idma_free, | 405 | .pcm_free = idma_free, |
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 7fcb51faa2a0..529b10dc532b 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c | |||
| @@ -79,7 +79,7 @@ static int jive_hw_params(struct snd_pcm_substream *substream, | |||
| 79 | return 0; | 79 | return 0; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static struct snd_soc_ops jive_ops = { | 82 | static const struct snd_soc_ops jive_ops = { |
| 83 | .hw_params = jive_hw_params, | 83 | .hw_params = jive_hw_params, |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 0834319ead42..44b6de5a331a 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c | |||
| @@ -19,8 +19,8 @@ struct odroid_priv { | |||
| 19 | struct snd_soc_card card; | 19 | struct snd_soc_card card; |
| 20 | struct snd_soc_dai_link dai_link; | 20 | struct snd_soc_dai_link dai_link; |
| 21 | 21 | ||
| 22 | struct clk *pll; | 22 | struct clk *clk_i2s_bus; |
| 23 | struct clk *rclk; | 23 | struct clk *sclk_i2s; |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | static int odroid_card_startup(struct snd_pcm_substream *substream) | 26 | static int odroid_card_startup(struct snd_pcm_substream *substream) |
| @@ -58,13 +58,18 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream, | |||
| 58 | return -EINVAL; | 58 | return -EINVAL; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | ret = clk_set_rate(priv->pll, pll_freq + 1); | 61 | ret = clk_set_rate(priv->clk_i2s_bus, pll_freq / 2 + 1); |
| 62 | if (ret < 0) | 62 | if (ret < 0) |
| 63 | return ret; | 63 | return ret; |
| 64 | 64 | ||
| 65 | rclk_freq = params_rate(params) * 256 * 4; | 65 | /* |
| 66 | * We add 1 to the rclk_freq value in order to avoid too low clock | ||
| 67 | * frequency values due to the EPLL output frequency not being exact | ||
| 68 | * multiple of the audio sampling rate. | ||
| 69 | */ | ||
| 70 | rclk_freq = params_rate(params) * 256 + 1; | ||
| 66 | 71 | ||
| 67 | ret = clk_set_rate(priv->rclk, rclk_freq); | 72 | ret = clk_set_rate(priv->sclk_i2s, rclk_freq); |
| 68 | if (ret < 0) | 73 | if (ret < 0) |
| 69 | return ret; | 74 | return ret; |
| 70 | 75 | ||
| @@ -118,14 +123,6 @@ static int odroid_audio_probe(struct platform_device *pdev) | |||
| 118 | 123 | ||
| 119 | snd_soc_card_set_drvdata(card, priv); | 124 | snd_soc_card_set_drvdata(card, priv); |
| 120 | 125 | ||
| 121 | priv->pll = devm_clk_get(dev, "epll"); | ||
| 122 | if (IS_ERR(priv->pll)) | ||
| 123 | return PTR_ERR(priv->pll); | ||
| 124 | |||
| 125 | priv->rclk = devm_clk_get(dev, "i2s_rclk"); | ||
| 126 | if (IS_ERR(priv->rclk)) | ||
| 127 | return PTR_ERR(priv->rclk); | ||
| 128 | |||
| 129 | ret = snd_soc_of_parse_card_name(card, "model"); | 126 | ret = snd_soc_of_parse_card_name(card, "model"); |
| 130 | if (ret < 0) | 127 | if (ret < 0) |
| 131 | return ret; | 128 | return ret; |
| @@ -171,14 +168,31 @@ static int odroid_audio_probe(struct platform_device *pdev) | |||
| 171 | link->name = "Primary"; | 168 | link->name = "Primary"; |
| 172 | link->stream_name = link->name; | 169 | link->stream_name = link->name; |
| 173 | 170 | ||
| 171 | |||
| 172 | priv->sclk_i2s = of_clk_get_by_name(link->cpu_of_node, "i2s_opclk1"); | ||
| 173 | if (IS_ERR(priv->sclk_i2s)) { | ||
| 174 | ret = PTR_ERR(priv->sclk_i2s); | ||
| 175 | goto err_put_i2s_n; | ||
| 176 | } | ||
| 177 | |||
| 178 | priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node, "iis"); | ||
| 179 | if (IS_ERR(priv->clk_i2s_bus)) { | ||
| 180 | ret = PTR_ERR(priv->clk_i2s_bus); | ||
| 181 | goto err_put_sclk; | ||
| 182 | } | ||
| 183 | |||
| 174 | ret = devm_snd_soc_register_card(dev, card); | 184 | ret = devm_snd_soc_register_card(dev, card); |
| 175 | if (ret < 0) { | 185 | if (ret < 0) { |
| 176 | dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); | 186 | dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); |
| 177 | goto err_put_i2s_n; | 187 | goto err_put_clk_i2s; |
| 178 | } | 188 | } |
| 179 | 189 | ||
| 180 | return 0; | 190 | return 0; |
| 181 | 191 | ||
| 192 | err_put_clk_i2s: | ||
| 193 | clk_put(priv->clk_i2s_bus); | ||
| 194 | err_put_sclk: | ||
| 195 | clk_put(priv->sclk_i2s); | ||
| 182 | err_put_i2s_n: | 196 | err_put_i2s_n: |
| 183 | of_node_put(link->cpu_of_node); | 197 | of_node_put(link->cpu_of_node); |
| 184 | err_put_codec_n: | 198 | err_put_codec_n: |
| @@ -192,6 +206,8 @@ static int odroid_audio_remove(struct platform_device *pdev) | |||
| 192 | 206 | ||
| 193 | of_node_put(priv->dai_link.cpu_of_node); | 207 | of_node_put(priv->dai_link.cpu_of_node); |
| 194 | odroid_put_codec_of_nodes(&priv->dai_link); | 208 | odroid_put_codec_of_nodes(&priv->dai_link); |
| 209 | clk_put(priv->sclk_i2s); | ||
| 210 | clk_put(priv->clk_i2s_bus); | ||
| 195 | 211 | ||
| 196 | return 0; | 212 | return 0; |
| 197 | } | 213 | } |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index d50a6377c23d..37f95eee1558 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
| @@ -522,7 +522,9 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
| 522 | dev_err(&pdev->dev, "failed to get audio-bus clock\n"); | 522 | dev_err(&pdev->dev, "failed to get audio-bus clock\n"); |
| 523 | return PTR_ERR(pcm->cclk); | 523 | return PTR_ERR(pcm->cclk); |
| 524 | } | 524 | } |
| 525 | clk_prepare_enable(pcm->cclk); | 525 | ret = clk_prepare_enable(pcm->cclk); |
| 526 | if (ret) | ||
| 527 | return ret; | ||
| 526 | 528 | ||
| 527 | /* record our pcm structure for later use in the callbacks */ | 529 | /* record our pcm structure for later use in the callbacks */ |
| 528 | dev_set_drvdata(&pdev->dev, pcm); | 530 | dev_set_drvdata(&pdev->dev, pcm); |
| @@ -533,7 +535,9 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
| 533 | ret = PTR_ERR(pcm->pclk); | 535 | ret = PTR_ERR(pcm->pclk); |
| 534 | goto err_dis_cclk; | 536 | goto err_dis_cclk; |
| 535 | } | 537 | } |
| 536 | clk_prepare_enable(pcm->pclk); | 538 | ret = clk_prepare_enable(pcm->pclk); |
| 539 | if (ret) | ||
| 540 | goto err_dis_cclk; | ||
| 537 | 541 | ||
| 538 | s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO; | 542 | s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO; |
| 539 | s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO; | 543 | s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO; |
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 8f42deaa184b..58c3e9bfc6b7 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #undef S3C_IIS_V2_SUPPORTED | 28 | #undef S3C_IIS_V2_SUPPORTED |
| 29 | 29 | ||
| 30 | #if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \ | 30 | #if defined(CONFIG_CPU_S3C2412) \ |
| 31 | || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210) | 31 | || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210) |
| 32 | #define S3C_IIS_V2_SUPPORTED | 32 | #define S3C_IIS_V2_SUPPORTED |
| 33 | #endif | 33 | #endif |
| @@ -634,11 +634,10 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, | |||
| 634 | i2s->iis_pclk = clk_get(dev, "iis"); | 634 | i2s->iis_pclk = clk_get(dev, "iis"); |
| 635 | if (IS_ERR(i2s->iis_pclk)) { | 635 | if (IS_ERR(i2s->iis_pclk)) { |
| 636 | dev_err(dev, "failed to get iis_clock\n"); | 636 | dev_err(dev, "failed to get iis_clock\n"); |
| 637 | iounmap(i2s->regs); | ||
| 638 | return -ENOENT; | 637 | return -ENOENT; |
| 639 | } | 638 | } |
| 640 | 639 | ||
| 641 | clk_enable(i2s->iis_pclk); | 640 | clk_prepare_enable(i2s->iis_pclk); |
| 642 | 641 | ||
| 643 | /* Mark ourselves as in TXRX mode so we can run through our cleanup | 642 | /* Mark ourselves as in TXRX mode so we can run through our cleanup |
| 644 | * process without warnings. */ | 643 | * process without warnings. */ |
| @@ -652,6 +651,15 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, | |||
| 652 | } | 651 | } |
| 653 | EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); | 652 | EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); |
| 654 | 653 | ||
| 654 | void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, | ||
| 655 | struct s3c_i2sv2_info *i2s) | ||
| 656 | { | ||
| 657 | clk_disable_unprepare(i2s->iis_pclk); | ||
| 658 | clk_put(i2s->iis_pclk); | ||
| 659 | i2s->iis_pclk = NULL; | ||
| 660 | } | ||
| 661 | EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup); | ||
| 662 | |||
| 655 | #ifdef CONFIG_PM | 663 | #ifdef CONFIG_PM |
| 656 | static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) | 664 | static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) |
| 657 | { | 665 | { |
diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index 182d80564e37..3fca20f7a853 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h | |||
| @@ -92,6 +92,13 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, | |||
| 92 | unsigned long base); | 92 | unsigned long base); |
| 93 | 93 | ||
| 94 | /** | 94 | /** |
| 95 | * s3c_i2sv2_cleanup - cleanup resources allocated in s3c_i2sv2_probe | ||
| 96 | * @dai: The ASoC DAI structure supplied to the original probe. | ||
| 97 | * @i2s: Our local i2s structure to fill in. | ||
| 98 | */ | ||
| 99 | extern void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, | ||
| 100 | struct s3c_i2sv2_info *i2s); | ||
| 101 | /** | ||
| 95 | * s3c_i2sv2_register_component - register component and dai with soc core | 102 | * s3c_i2sv2_register_component - register component and dai with soc core |
| 96 | * @dev: DAI device | 103 | * @dev: DAI device |
| 97 | * @id: DAI ID | 104 | * @id: DAI ID |
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 0a4718207e6e..cc0840fff5aa 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
| @@ -65,26 +65,33 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) | |||
| 65 | s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk"); | 65 | s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk"); |
| 66 | if (IS_ERR(s3c2412_i2s.iis_cclk)) { | 66 | if (IS_ERR(s3c2412_i2s.iis_cclk)) { |
| 67 | pr_err("failed to get i2sclk clock\n"); | 67 | pr_err("failed to get i2sclk clock\n"); |
| 68 | return PTR_ERR(s3c2412_i2s.iis_cclk); | 68 | ret = PTR_ERR(s3c2412_i2s.iis_cclk); |
| 69 | goto err; | ||
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | /* Set MPLL as the source for IIS CLK */ | 72 | /* Set MPLL as the source for IIS CLK */ |
| 72 | 73 | ||
| 73 | clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); | 74 | clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); |
| 74 | clk_prepare_enable(s3c2412_i2s.iis_cclk); | 75 | ret = clk_prepare_enable(s3c2412_i2s.iis_cclk); |
| 75 | 76 | if (ret) | |
| 76 | s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; | 77 | goto err; |
| 77 | 78 | ||
| 78 | /* Configure the I2S pins (GPE0...GPE4) in correct mode */ | 79 | /* Configure the I2S pins (GPE0...GPE4) in correct mode */ |
| 79 | s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), | 80 | s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), |
| 80 | S3C_GPIO_PULL_NONE); | 81 | S3C_GPIO_PULL_NONE); |
| 81 | 82 | ||
| 82 | return 0; | 83 | return 0; |
| 84 | |||
| 85 | err: | ||
| 86 | s3c_i2sv2_cleanup(dai, &s3c2412_i2s); | ||
| 87 | |||
| 88 | return ret; | ||
| 83 | } | 89 | } |
| 84 | 90 | ||
| 85 | static int s3c2412_i2s_remove(struct snd_soc_dai *dai) | 91 | static int s3c2412_i2s_remove(struct snd_soc_dai *dai) |
| 86 | { | 92 | { |
| 87 | clk_disable_unprepare(s3c2412_i2s.iis_cclk); | 93 | clk_disable_unprepare(s3c2412_i2s.iis_cclk); |
| 94 | s3c_i2sv2_cleanup(dai, &s3c2412_i2s); | ||
| 88 | 95 | ||
| 89 | return 0; | 96 | return 0; |
| 90 | } | 97 | } |
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 91e6871e5413..8d58d02183bf 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
| @@ -340,6 +340,7 @@ EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); | |||
| 340 | 340 | ||
| 341 | static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) | 341 | static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) |
| 342 | { | 342 | { |
| 343 | int ret; | ||
| 343 | snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, | 344 | snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, |
| 344 | &s3c24xx_i2s_pcm_stereo_in); | 345 | &s3c24xx_i2s_pcm_stereo_in); |
| 345 | 346 | ||
| @@ -348,7 +349,9 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) | |||
| 348 | pr_err("failed to get iis_clock\n"); | 349 | pr_err("failed to get iis_clock\n"); |
| 349 | return PTR_ERR(s3c24xx_i2s.iis_clk); | 350 | return PTR_ERR(s3c24xx_i2s.iis_clk); |
| 350 | } | 351 | } |
| 351 | clk_prepare_enable(s3c24xx_i2s.iis_clk); | 352 | ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); |
| 353 | if (ret) | ||
| 354 | return ret; | ||
| 352 | 355 | ||
| 353 | /* Configure the I2S pins (GPE0...GPE4) in correct mode */ | 356 | /* Configure the I2S pins (GPE0...GPE4) in correct mode */ |
| 354 | s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), | 357 | s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), |
| @@ -377,7 +380,11 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) | |||
| 377 | 380 | ||
| 378 | static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) | 381 | static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) |
| 379 | { | 382 | { |
| 380 | clk_prepare_enable(s3c24xx_i2s.iis_clk); | 383 | int ret; |
| 384 | |||
| 385 | ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); | ||
| 386 | if (ret) | ||
| 387 | return ret; | ||
| 381 | 388 | ||
| 382 | writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); | 389 | writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); |
| 383 | writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); | 390 | writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); |
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index dcc008d1e1ab..6de63f3e37d5 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c | |||
| @@ -211,7 +211,7 @@ static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) | |||
| 211 | return 0; | 211 | return 0; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static struct snd_soc_ops simtec_snd_ops = { | 214 | static const struct snd_soc_ops simtec_snd_ops = { |
| 215 | .hw_params = simtec_hw_params, | 215 | .hw_params = simtec_hw_params, |
| 216 | }; | 216 | }; |
| 217 | 217 | ||
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 55538e333cc8..5fb3bab6bbfe 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
| @@ -199,7 +199,7 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, | |||
| 199 | return 0; | 199 | return 0; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static struct snd_soc_ops s3c24xx_uda134x_ops = { | 202 | static const struct snd_soc_ops s3c24xx_uda134x_ops = { |
| 203 | .startup = s3c24xx_uda134x_startup, | 203 | .startup = s3c24xx_uda134x_startup, |
| 204 | .shutdown = s3c24xx_uda134x_shutdown, | 204 | .shutdown = s3c24xx_uda134x_shutdown, |
| 205 | .hw_params = s3c24xx_uda134x_hw_params, | 205 | .hw_params = s3c24xx_uda134x_hw_params, |
| @@ -237,7 +237,6 @@ static int s3c24xx_uda134x_probe(struct platform_device *pdev) | |||
| 237 | mutex_init(&priv->clk_lock); | 237 | mutex_init(&priv->clk_lock); |
| 238 | 238 | ||
| 239 | card->dev = &pdev->dev; | 239 | card->dev = &pdev->dev; |
| 240 | platform_set_drvdata(pdev, card); | ||
| 241 | snd_soc_card_set_drvdata(card, priv); | 240 | snd_soc_card_set_drvdata(card, priv); |
| 242 | 241 | ||
| 243 | ret = devm_snd_soc_register_card(&pdev->dev, card); | 242 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index a2f2363fe1c2..7fc7cc6d1530 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c | |||
| @@ -144,7 +144,7 @@ static int smdk_hw_params(struct snd_pcm_substream *substream, | |||
| 144 | return ret; | 144 | return ret; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static struct snd_soc_ops smdk_spdif_ops = { | 147 | static const struct snd_soc_ops smdk_spdif_ops = { |
| 148 | .hw_params = smdk_hw_params, | 148 | .hw_params = smdk_hw_params, |
| 149 | }; | 149 | }; |
| 150 | 150 | ||
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 779504f54bc0..cb59911e65c0 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
| @@ -391,7 +391,9 @@ static int spdif_probe(struct platform_device *pdev) | |||
| 391 | ret = -ENOENT; | 391 | ret = -ENOENT; |
| 392 | goto err0; | 392 | goto err0; |
| 393 | } | 393 | } |
| 394 | clk_prepare_enable(spdif->pclk); | 394 | ret = clk_prepare_enable(spdif->pclk); |
| 395 | if (ret) | ||
| 396 | goto err0; | ||
| 395 | 397 | ||
| 396 | spdif->sclk = devm_clk_get(&pdev->dev, "sclk_spdif"); | 398 | spdif->sclk = devm_clk_get(&pdev->dev, "sclk_spdif"); |
| 397 | if (IS_ERR(spdif->sclk)) { | 399 | if (IS_ERR(spdif->sclk)) { |
| @@ -399,7 +401,9 @@ static int spdif_probe(struct platform_device *pdev) | |||
| 399 | ret = -ENOENT; | 401 | ret = -ENOENT; |
| 400 | goto err1; | 402 | goto err1; |
| 401 | } | 403 | } |
| 402 | clk_prepare_enable(spdif->sclk); | 404 | ret = clk_prepare_enable(spdif->sclk); |
| 405 | if (ret) | ||
| 406 | goto err1; | ||
| 403 | 407 | ||
| 404 | /* Request S/PDIF Register's memory region */ | 408 | /* Request S/PDIF Register's memory region */ |
| 405 | if (!request_mem_region(mem_res->start, | 409 | if (!request_mem_region(mem_res->start, |
diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c index 24cc9d63ce87..68698f3d72f9 100644 --- a/sound/soc/samsung/tm2_wm5110.c +++ b/sound/soc/samsung/tm2_wm5110.c | |||
| @@ -318,7 +318,7 @@ static const struct snd_kcontrol_new tm2_controls[] = { | |||
| 318 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 318 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
| 319 | }; | 319 | }; |
| 320 | 320 | ||
| 321 | const struct snd_soc_dapm_widget tm2_dapm_widgets[] = { | 321 | static const struct snd_soc_dapm_widget tm2_dapm_widgets[] = { |
| 322 | SND_SOC_DAPM_HP("HP", NULL), | 322 | SND_SOC_DAPM_HP("HP", NULL), |
| 323 | SND_SOC_DAPM_SPK("SPK", NULL), | 323 | SND_SOC_DAPM_SPK("SPK", NULL), |
| 324 | SND_SOC_DAPM_SPK("RCV", NULL), | 324 | SND_SOC_DAPM_SPK("RCV", NULL), |
| @@ -521,7 +521,7 @@ static void tm2_pm_complete(struct device *dev) | |||
| 521 | tm2_start_sysclk(card); | 521 | tm2_start_sysclk(card); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | const struct dev_pm_ops tm2_pm_ops = { | 524 | static const struct dev_pm_ops tm2_pm_ops = { |
| 525 | .prepare = tm2_pm_prepare, | 525 | .prepare = tm2_pm_prepare, |
| 526 | .suspend = snd_soc_suspend, | 526 | .suspend = snd_soc_suspend, |
| 527 | .resume = snd_soc_resume, | 527 | .resume = snd_soc_resume, |
