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

Merge remote-tracking branches 'asoc/topic/gpiod-flags', 'asoc/topic/gtm601', 'asoc/topic/intel', 'asoc/topic/lm3857' and 'asoc/topic/max98090' into asoc-next

+785 -187
+13
Documentation/devicetree/bindings/sound/gtm601.txt
··· 1 + GTM601 UMTS modem audio interface CODEC 2 + 3 + This device has no configuration interface. Sample rate is fixed - 8kHz. 4 + 5 + Required properties: 6 + 7 + - compatible : "option,gtm601" 8 + 9 + Example: 10 + 11 + codec: gtm601_codec { 12 + compatible = "option,gtm601"; 13 + };
+6
Documentation/devicetree/bindings/sound/max98090.txt
··· 18 18 19 19 - maxim,dmic-freq: Frequency at which to clock DMIC 20 20 21 + - maxim,micbias: Micbias voltage applies to the analog mic, valid voltages value are: 22 + 0 - 2.2v 23 + 1 - 2.55v 24 + 2 - 2.4v 25 + 3 - 2.8v 26 + 21 27 Pins on the device (for linking into audio routes): 22 28 23 29 * MIC1
+29 -83
sound/soc/codecs/lm4857.c
··· 23 23 #include <sound/soc.h> 24 24 #include <sound/tlv.h> 25 25 26 - struct lm4857 { 27 - struct regmap *regmap; 28 - uint8_t mode; 29 - }; 30 - 31 26 static const struct reg_default lm4857_default_regs[] = { 32 27 { 0x0, 0x00 }, 33 28 { 0x1, 0x00 }, ··· 41 46 #define LM4857_WAKEUP 5 42 47 #define LM4857_EPGAIN 4 43 48 44 - static int lm4857_get_mode(struct snd_kcontrol *kcontrol, 45 - struct snd_ctl_elem_value *ucontrol) 46 - { 47 - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 48 - struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); 49 + static const unsigned int lm4857_mode_values[] = { 50 + 0, 51 + 6, 52 + 7, 53 + 8, 54 + 9, 55 + }; 49 56 50 - ucontrol->value.integer.value[0] = lm4857->mode; 51 - 52 - return 0; 53 - } 54 - 55 - static int lm4857_set_mode(struct snd_kcontrol *kcontrol, 56 - struct snd_ctl_elem_value *ucontrol) 57 - { 58 - struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 59 - struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); 60 - uint8_t value = ucontrol->value.integer.value[0]; 61 - 62 - lm4857->mode = value; 63 - 64 - if (codec->dapm.bias_level == SND_SOC_BIAS_ON) 65 - regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, value + 6); 66 - 67 - return 1; 68 - } 69 - 70 - static int lm4857_set_bias_level(struct snd_soc_codec *codec, 71 - enum snd_soc_bias_level level) 72 - { 73 - struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); 74 - 75 - switch (level) { 76 - case SND_SOC_BIAS_ON: 77 - regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, 78 - lm4857->mode + 6); 79 - break; 80 - case SND_SOC_BIAS_STANDBY: 81 - regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, 0); 82 - break; 83 - default: 84 - break; 85 - } 86 - 87 - return 0; 88 - } 89 - 90 - static const char *lm4857_mode[] = { 57 + static const char * const lm4857_mode_texts[] = { 58 + "Off", 91 59 "Earpiece", 92 60 "Loudspeaker", 93 61 "Loudspeaker + Headphone", 94 62 "Headphone", 95 63 }; 96 64 97 - static SOC_ENUM_SINGLE_EXT_DECL(lm4857_mode_enum, lm4857_mode); 65 + static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(lm4857_mode_enum, 66 + LM4857_CTRL, 0, 0xf, lm4857_mode_texts, lm4857_mode_values); 67 + 68 + static const struct snd_kcontrol_new lm4857_mode_ctrl = 69 + SOC_DAPM_ENUM("Mode", lm4857_mode_enum); 98 70 99 71 static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = { 100 72 SND_SOC_DAPM_INPUT("IN"), 73 + 74 + SND_SOC_DAPM_DEMUX("Mode", SND_SOC_NOPM, 0, 0, &lm4857_mode_ctrl), 101 75 102 76 SND_SOC_DAPM_OUTPUT("LS"), 103 77 SND_SOC_DAPM_OUTPUT("HP"), ··· 89 125 LM4857_WAKEUP, 1, 0), 90 126 SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL, 91 127 LM4857_EPGAIN, 1, 0), 92 - 93 - SOC_ENUM_EXT("Mode", lm4857_mode_enum, 94 - lm4857_get_mode, lm4857_set_mode), 95 128 }; 96 129 97 - /* There is a demux between the input signal and the output signals. 98 - * Currently there is no easy way to model it in ASoC and since it does not make 99 - * much of a difference in practice simply connect the input direclty to the 100 - * outputs. */ 101 130 static const struct snd_soc_dapm_route lm4857_routes[] = { 102 - {"LS", NULL, "IN"}, 103 - {"HP", NULL, "IN"}, 104 - {"EP", NULL, "IN"}, 131 + { "Mode", NULL, "IN" }, 132 + { "LS", "Loudspeaker", "Mode" }, 133 + { "LS", "Loudspeaker + Headphone", "Mode" }, 134 + { "HP", "Headphone", "Mode" }, 135 + { "HP", "Loudspeaker + Headphone", "Mode" }, 136 + { "EP", "Earpiece", "Mode" }, 105 137 }; 106 138 107 - static struct snd_soc_codec_driver soc_codec_dev_lm4857 = { 108 - .set_bias_level = lm4857_set_bias_level, 109 - 139 + static struct snd_soc_component_driver lm4857_component_driver = { 110 140 .controls = lm4857_controls, 111 141 .num_controls = ARRAY_SIZE(lm4857_controls), 112 142 .dapm_widgets = lm4857_dapm_widgets, ··· 123 165 static int lm4857_i2c_probe(struct i2c_client *i2c, 124 166 const struct i2c_device_id *id) 125 167 { 126 - struct lm4857 *lm4857; 168 + struct regmap *regmap; 127 169 128 - lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL); 129 - if (!lm4857) 130 - return -ENOMEM; 170 + regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config); 171 + if (IS_ERR(regmap)) 172 + return PTR_ERR(regmap); 131 173 132 - i2c_set_clientdata(i2c, lm4857); 133 - 134 - lm4857->regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config); 135 - if (IS_ERR(lm4857->regmap)) 136 - return PTR_ERR(lm4857->regmap); 137 - 138 - return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0); 139 - } 140 - 141 - static int lm4857_i2c_remove(struct i2c_client *i2c) 142 - { 143 - snd_soc_unregister_codec(&i2c->dev); 144 - return 0; 174 + return devm_snd_soc_register_component(&i2c->dev, 175 + &lm4857_component_driver, NULL, 0); 145 176 } 146 177 147 178 static const struct i2c_device_id lm4857_i2c_id[] = { ··· 145 198 .owner = THIS_MODULE, 146 199 }, 147 200 .probe = lm4857_i2c_probe, 148 - .remove = lm4857_i2c_remove, 149 201 .id_table = lm4857_i2c_id, 150 202 }; 151 203
+12 -1
sound/soc/codecs/max98090.c
··· 2419 2419 struct max98090_cdata *cdata; 2420 2420 enum max98090_type devtype; 2421 2421 int ret = 0; 2422 + int err; 2423 + unsigned int micbias; 2422 2424 2423 2425 dev_dbg(codec->dev, "max98090_probe\n"); 2424 2426 ··· 2505 2503 snd_soc_write(codec, M98090_REG_BIAS_CONTROL, 2506 2504 M98090_VCM_MODE_MASK); 2507 2505 2506 + err = device_property_read_u32(codec->dev, "maxim,micbias", &micbias); 2507 + if (err) { 2508 + micbias = M98090_MBVSEL_2V8; 2509 + dev_info(codec->dev, "use default 2.8v micbias\n"); 2510 + } else if (micbias < M98090_MBVSEL_2V2 || micbias > M98090_MBVSEL_2V8) { 2511 + dev_err(codec->dev, "micbias out of range 0x%x\n", micbias); 2512 + micbias = M98090_MBVSEL_2V8; 2513 + } 2514 + 2508 2515 snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE, 2509 - M98090_MBVSEL_MASK, M98090_MBVSEL_2V8); 2516 + M98090_MBVSEL_MASK, micbias); 2510 2517 2511 2518 max98090_add_widgets(codec); 2512 2519
+1 -2
sound/soc/codecs/max98357a.c
··· 60 60 { 61 61 struct gpio_desc *sdmode; 62 62 63 - sdmode = devm_gpiod_get(codec->dev, "sdmode"); 63 + sdmode = devm_gpiod_get(codec->dev, "sdmode", GPIOD_OUT_LOW); 64 64 if (IS_ERR(sdmode)) { 65 65 dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n", 66 66 __func__, PTR_ERR(sdmode)); 67 67 return PTR_ERR(sdmode); 68 68 } 69 - gpiod_direction_output(sdmode, 0); 70 69 snd_soc_codec_set_drvdata(codec, sdmode); 71 70 72 71 return 0;
+4 -10
sound/soc/codecs/sta32x.c
··· 1095 1095 #endif 1096 1096 1097 1097 /* GPIOs */ 1098 - sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset"); 1099 - if (IS_ERR(sta32x->gpiod_nreset)) { 1100 - ret = PTR_ERR(sta32x->gpiod_nreset); 1101 - if (ret != -ENOENT && ret != -ENOSYS) 1102 - return ret; 1103 - 1104 - sta32x->gpiod_nreset = NULL; 1105 - } else { 1106 - gpiod_direction_output(sta32x->gpiod_nreset, 0); 1107 - } 1098 + sta32x->gpiod_nreset = devm_gpiod_get_optional(dev, "reset", 1099 + GPIOD_OUT_LOW); 1100 + if (IS_ERR(sta32x->gpiod_nreset)) 1101 + return PTR_ERR(sta32x->gpiod_nreset); 1108 1102 1109 1103 /* regulators */ 1110 1104 for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
+14 -3
sound/soc/intel/Kconfig
··· 79 79 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \ 80 80 I2C_DESIGNWARE_PLATFORM 81 81 select SND_SOC_INTEL_HASWELL 82 - select SND_COMPRESS_OFFLOAD 83 82 select SND_SOC_RT286 84 83 help 85 84 This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell ··· 111 112 If unsure select "N". 112 113 113 114 config SND_SOC_INTEL_CHT_BSW_RT5645_MACH 114 - tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645 codec" 115 + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" 115 116 depends on X86_INTEL_LPSS 116 117 select SND_SOC_RT5645 117 118 select SND_SST_MFLD_PLATFORM 118 119 select SND_SST_IPC_ACPI 119 120 help 120 121 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell 121 - platforms with RT5645 audio codec. 122 + platforms with RT5645/5650 audio codec. 122 123 If unsure select "N". 124 + 125 + config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH 126 + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" 127 + depends on X86_INTEL_LPSS 128 + select SND_SOC_MAX98090 129 + select SND_SOC_TS3A227E 130 + select SND_SST_MFLD_PLATFORM 131 + select SND_SST_IPC_ACPI 132 + help 133 + This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell 134 + platforms with MAX98090 audio codec it also can support TI jack chip as aux device. 135 + If unsure select "N".
+144 -23
sound/soc/intel/atom/sst-atom-controls.c
··· 774 774 return ret; 775 775 } 776 776 777 + int sst_fill_ssp_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 778 + unsigned int rx_mask, int slots, int slot_width) 779 + { 780 + struct sst_data *ctx = snd_soc_dai_get_drvdata(dai); 781 + 782 + ctx->ssp_cmd.nb_slots = slots; 783 + ctx->ssp_cmd.active_tx_slot_map = tx_mask; 784 + ctx->ssp_cmd.active_rx_slot_map = rx_mask; 785 + ctx->ssp_cmd.nb_bits_per_slots = slot_width; 786 + 787 + return 0; 788 + } 789 + 790 + static int sst_get_frame_sync_polarity(struct snd_soc_dai *dai, 791 + unsigned int fmt) 792 + { 793 + int format; 794 + 795 + format = fmt & SND_SOC_DAIFMT_INV_MASK; 796 + dev_dbg(dai->dev, "Enter:%s, format=%x\n", __func__, format); 797 + 798 + switch (format) { 799 + case SND_SOC_DAIFMT_NB_NF: 800 + return SSP_FS_ACTIVE_LOW; 801 + case SND_SOC_DAIFMT_NB_IF: 802 + return SSP_FS_ACTIVE_HIGH; 803 + case SND_SOC_DAIFMT_IB_IF: 804 + return SSP_FS_ACTIVE_LOW; 805 + case SND_SOC_DAIFMT_IB_NF: 806 + return SSP_FS_ACTIVE_HIGH; 807 + default: 808 + dev_err(dai->dev, "Invalid frame sync polarity %d\n", format); 809 + } 810 + 811 + return -EINVAL; 812 + } 813 + 814 + static int sst_get_ssp_mode(struct snd_soc_dai *dai, unsigned int fmt) 815 + { 816 + int format; 817 + 818 + format = (fmt & SND_SOC_DAIFMT_MASTER_MASK); 819 + dev_dbg(dai->dev, "Enter:%s, format=%x\n", __func__, format); 820 + 821 + switch (format) { 822 + case SND_SOC_DAIFMT_CBS_CFS: 823 + return SSP_MODE_MASTER; 824 + case SND_SOC_DAIFMT_CBM_CFM: 825 + return SSP_MODE_SLAVE; 826 + default: 827 + dev_err(dai->dev, "Invalid ssp protocol: %d\n", format); 828 + } 829 + 830 + return -EINVAL; 831 + } 832 + 833 + 834 + int sst_fill_ssp_config(struct snd_soc_dai *dai, unsigned int fmt) 835 + { 836 + unsigned int mode; 837 + int fs_polarity; 838 + struct sst_data *ctx = snd_soc_dai_get_drvdata(dai); 839 + 840 + mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 841 + 842 + switch (mode) { 843 + case SND_SOC_DAIFMT_DSP_B: 844 + ctx->ssp_cmd.ssp_protocol = SSP_MODE_PCM; 845 + ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NETWORK << 1); 846 + ctx->ssp_cmd.start_delay = 0; 847 + ctx->ssp_cmd.data_polarity = 1; 848 + ctx->ssp_cmd.frame_sync_width = 1; 849 + break; 850 + 851 + case SND_SOC_DAIFMT_DSP_A: 852 + ctx->ssp_cmd.ssp_protocol = SSP_MODE_PCM; 853 + ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NETWORK << 1); 854 + ctx->ssp_cmd.start_delay = 1; 855 + ctx->ssp_cmd.data_polarity = 1; 856 + ctx->ssp_cmd.frame_sync_width = 1; 857 + break; 858 + 859 + case SND_SOC_DAIFMT_I2S: 860 + ctx->ssp_cmd.ssp_protocol = SSP_MODE_I2S; 861 + ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NORMAL << 1); 862 + ctx->ssp_cmd.start_delay = 1; 863 + ctx->ssp_cmd.data_polarity = 0; 864 + ctx->ssp_cmd.frame_sync_width = ctx->ssp_cmd.nb_bits_per_slots; 865 + break; 866 + 867 + case SND_SOC_DAIFMT_LEFT_J: 868 + ctx->ssp_cmd.ssp_protocol = SSP_MODE_I2S; 869 + ctx->ssp_cmd.mode = sst_get_ssp_mode(dai, fmt) | (SSP_PCM_MODE_NORMAL << 1); 870 + ctx->ssp_cmd.start_delay = 0; 871 + ctx->ssp_cmd.data_polarity = 0; 872 + ctx->ssp_cmd.frame_sync_width = ctx->ssp_cmd.nb_bits_per_slots; 873 + break; 874 + 875 + default: 876 + dev_dbg(dai->dev, "using default ssp configs\n"); 877 + } 878 + 879 + fs_polarity = sst_get_frame_sync_polarity(dai, fmt); 880 + if (fs_polarity < 0) 881 + return fs_polarity; 882 + 883 + ctx->ssp_cmd.frame_sync_polarity = fs_polarity; 884 + 885 + return 0; 886 + } 887 + 777 888 /** 778 889 * sst_ssp_config - contains SSP configuration for media UC 890 + * this can be overwritten by set_dai_xxx APIs 779 891 */ 780 892 static const struct sst_ssp_config sst_ssp_configs = { 781 893 .ssp_id = SSP_CODEC, ··· 901 789 .fs_frequency = SSP_FS_48_KHZ, 902 790 .active_slot_map = 0xF, 903 791 .start_delay = 0, 792 + .frame_sync_polarity = SSP_FS_ACTIVE_HIGH, 793 + .data_polarity = 1, 904 794 }; 795 + 796 + void sst_fill_ssp_defaults(struct snd_soc_dai *dai) 797 + { 798 + const struct sst_ssp_config *config; 799 + struct sst_data *ctx = snd_soc_dai_get_drvdata(dai); 800 + 801 + config = &sst_ssp_configs; 802 + 803 + ctx->ssp_cmd.selection = config->ssp_id; 804 + ctx->ssp_cmd.nb_bits_per_slots = config->bits_per_slot; 805 + ctx->ssp_cmd.nb_slots = config->slots; 806 + ctx->ssp_cmd.mode = config->ssp_mode | (config->pcm_mode << 1); 807 + ctx->ssp_cmd.duplex = config->duplex; 808 + ctx->ssp_cmd.active_tx_slot_map = config->active_slot_map; 809 + ctx->ssp_cmd.active_rx_slot_map = config->active_slot_map; 810 + ctx->ssp_cmd.frame_sync_frequency = config->fs_frequency; 811 + ctx->ssp_cmd.frame_sync_polarity = config->frame_sync_polarity; 812 + ctx->ssp_cmd.data_polarity = config->data_polarity; 813 + ctx->ssp_cmd.frame_sync_width = config->fs_width; 814 + ctx->ssp_cmd.ssp_protocol = config->ssp_protocol; 815 + ctx->ssp_cmd.start_delay = config->start_delay; 816 + ctx->ssp_cmd.reserved1 = ctx->ssp_cmd.reserved2 = 0xFF; 817 + } 905 818 906 819 int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable) 907 820 { 908 - struct sst_cmd_sba_hw_set_ssp cmd; 909 821 struct sst_data *drv = snd_soc_dai_get_drvdata(dai); 910 822 const struct sst_ssp_config *config; 911 823 912 824 dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id); 913 825 914 - SST_FILL_DEFAULT_DESTINATION(cmd.header.dst); 915 - cmd.header.command_id = SBA_HW_SET_SSP; 916 - cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) 826 + SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst); 827 + drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP; 828 + drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp) 917 829 - sizeof(struct sst_dsp_header); 918 830 919 831 config = &sst_ssp_configs; 920 832 dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id); 921 833 922 834 if (enable) 923 - cmd.switch_state = SST_SWITCH_ON; 835 + drv->ssp_cmd.switch_state = SST_SWITCH_ON; 924 836 else 925 - cmd.switch_state = SST_SWITCH_OFF; 926 - 927 - cmd.selection = config->ssp_id; 928 - cmd.nb_bits_per_slots = config->bits_per_slot; 929 - cmd.nb_slots = config->slots; 930 - cmd.mode = config->ssp_mode | (config->pcm_mode << 1); 931 - cmd.duplex = config->duplex; 932 - cmd.active_tx_slot_map = config->active_slot_map; 933 - cmd.active_rx_slot_map = config->active_slot_map; 934 - cmd.frame_sync_frequency = config->fs_frequency; 935 - cmd.frame_sync_polarity = SSP_FS_ACTIVE_HIGH; 936 - cmd.data_polarity = 1; 937 - cmd.frame_sync_width = config->fs_width; 938 - cmd.ssp_protocol = config->ssp_protocol; 939 - cmd.start_delay = config->start_delay; 940 - cmd.reserved1 = cmd.reserved2 = 0xFF; 837 + drv->ssp_cmd.switch_state = SST_SWITCH_OFF; 941 838 942 839 return sst_fill_and_send_cmd(drv, SST_IPC_IA_CMD, SST_FLAG_BLOCKED, 943 - SST_TASK_SBA, 0, &cmd, 944 - sizeof(cmd.header) + cmd.header.length); 840 + SST_TASK_SBA, 0, &drv->ssp_cmd, 841 + sizeof(drv->ssp_cmd.header) + drv->ssp_cmd.header.length); 945 842 } 946 843 947 844 static int sst_set_be_modules(struct snd_soc_dapm_widget *w,
+8 -1
sound/soc/intel/atom/sst-atom-controls.h
··· 562 562 u8 active_slot_map; 563 563 u8 start_delay; 564 564 u16 fs_width; 565 + u8 frame_sync_polarity; 566 + u8 data_polarity; 565 567 }; 566 568 567 569 struct sst_ssp_cfg { ··· 697 695 u16 module_id; 698 696 u16 pipe_id; 699 697 u16 task_id; 700 - char pname[44]; 698 + char pname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 701 699 struct snd_soc_dapm_widget *w; 702 700 }; 703 701 ··· 868 866 #define SST_SSP_MUX_CTL(xpname, xinstance, xreg, xshift, xtexts) \ 869 867 SOC_DAPM_ENUM(SST_MUX_CTL_NAME(xpname, xinstance), \ 870 868 SST_SSP_MUX_ENUM(xreg, xshift, xtexts)) 869 + 870 + int sst_fill_ssp_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 871 + unsigned int rx_mask, int slots, int slot_width); 872 + int sst_fill_ssp_config(struct snd_soc_dai *dai, unsigned int fmt); 873 + void sst_fill_ssp_defaults(struct snd_soc_dai *dai); 871 874 872 875 #endif
+44 -3
sound/soc/intel/atom/sst-mfld-platform-pcm.c
··· 434 434 435 435 if (!dai->active) { 436 436 ret = sst_handle_vb_timer(dai, true); 437 - if (ret) 438 - return ret; 439 - ret = send_ssp_cmd(dai, dai->name, 1); 437 + sst_fill_ssp_defaults(dai); 440 438 } 439 + return ret; 440 + } 441 + 442 + static int sst_be_hw_params(struct snd_pcm_substream *substream, 443 + struct snd_pcm_hw_params *params, 444 + struct snd_soc_dai *dai) 445 + { 446 + int ret = 0; 447 + 448 + if (dai->active == 1) 449 + ret = send_ssp_cmd(dai, dai->name, 1); 450 + return ret; 451 + } 452 + 453 + static int sst_set_format(struct snd_soc_dai *dai, unsigned int fmt) 454 + { 455 + int ret = 0; 456 + 457 + if (!dai->active) 458 + return 0; 459 + 460 + ret = sst_fill_ssp_config(dai, fmt); 461 + if (ret < 0) 462 + dev_err(dai->dev, "sst_set_format failed..\n"); 463 + 464 + return ret; 465 + } 466 + 467 + static int sst_platform_set_ssp_slot(struct snd_soc_dai *dai, 468 + unsigned int tx_mask, unsigned int rx_mask, 469 + int slots, int slot_width) { 470 + int ret = 0; 471 + 472 + if (!dai->active) 473 + return ret; 474 + 475 + ret = sst_fill_ssp_slot(dai, tx_mask, rx_mask, slots, slot_width); 476 + if (ret < 0) 477 + dev_err(dai->dev, "sst_fill_ssp_slot failed..%d\n", ret); 478 + 441 479 return ret; 442 480 } 443 481 ··· 503 465 504 466 static struct snd_soc_dai_ops sst_be_dai_ops = { 505 467 .startup = sst_enable_ssp, 468 + .hw_params = sst_be_hw_params, 469 + .set_fmt = sst_set_format, 470 + .set_tdm_slot = sst_platform_set_ssp_slot, 506 471 .shutdown = sst_disable_ssp, 507 472 }; 508 473
+2
sound/soc/intel/atom/sst-mfld-platform.h
··· 22 22 #define __SST_PLATFORMDRV_H__ 23 23 24 24 #include "sst-mfld-dsp.h" 25 + #include "sst-atom-controls.h" 25 26 26 27 extern struct sst_device *sst; 27 28 ··· 176 175 struct snd_sst_bytes_v2 *byte_stream; 177 176 struct mutex lock; 178 177 struct snd_soc_card *soc_card; 178 + struct sst_cmd_sba_hw_set_ssp ssp_cmd; 179 179 }; 180 180 int sst_register_dsp(struct sst_device *sst); 181 181 int sst_unregister_dsp(struct sst_device *sst);
+4
sound/soc/intel/atom/sst/sst_acpi.c
··· 354 354 &chv_platform_data }, 355 355 {"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", 356 356 &chv_platform_data }, 357 + {"10EC5650", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", 358 + &chv_platform_data }, 359 + {"193C9890", "cht-bsw", "cht-bsw-max98090", NULL, 360 + "intel/fw_sst_22a8.bin", &chv_platform_data }, 357 361 {}, 358 362 }; 359 363
+11
sound/soc/intel/baytrail/sst-baytrail-ipc.c
··· 679 679 return header; 680 680 } 681 681 682 + static bool byt_is_dsp_busy(struct sst_dsp *dsp) 683 + { 684 + u64 ipcx; 685 + 686 + ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX); 687 + return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)); 688 + } 689 + 682 690 int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) 683 691 { 684 692 struct sst_byt *byt; ··· 707 699 ipc->ops.shim_dbg = byt_shim_dbg; 708 700 ipc->ops.tx_data_copy = byt_tx_data_copy; 709 701 ipc->ops.reply_msg_match = byt_reply_msg_match; 702 + ipc->ops.is_dsp_busy = byt_is_dsp_busy; 703 + ipc->tx_data_max_size = IPC_MAX_MAILBOX_BYTES; 704 + ipc->rx_data_max_size = IPC_MAX_MAILBOX_BYTES; 710 705 711 706 err = sst_ipc_init(ipc); 712 707 if (err != 0)
+2
sound/soc/intel/boards/Makefile
··· 5 5 snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o 6 6 snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 7 7 snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 8 + snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 8 9 9 10 obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 10 11 obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o ··· 14 13 obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o 15 14 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 16 15 obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 16 + obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
+318
sound/soc/intel/boards/cht_bsw_max98090_ti.c
··· 1 + /* 2 + * cht-bsw-max98090.c - ASoc Machine driver for Intel Cherryview-based 3 + * platforms Cherrytrail and Braswell, with max98090 & TI codec. 4 + * 5 + * Copyright (C) 2015 Intel Corp 6 + * Author: Fang, Yang A <yang.a.fang@intel.com> 7 + * This file is modified from cht_bsw_rt5645.c 8 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation; version 2 of the License. 13 + * 14 + * This program is distributed in the hope that it will be useful, but 15 + * WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 + * General Public License for more details. 18 + * 19 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/platform_device.h> 24 + #include <linux/slab.h> 25 + #include <linux/acpi.h> 26 + #include <sound/pcm.h> 27 + #include <sound/pcm_params.h> 28 + #include <sound/soc.h> 29 + #include <sound/jack.h> 30 + #include "../../codecs/max98090.h" 31 + #include "../atom/sst-atom-controls.h" 32 + #include "../../codecs/ts3a227e.h" 33 + 34 + #define CHT_PLAT_CLK_3_HZ 19200000 35 + #define CHT_CODEC_DAI "HiFi" 36 + 37 + struct cht_mc_private { 38 + struct snd_soc_jack jack; 39 + bool ts3a227e_present; 40 + }; 41 + 42 + static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 43 + { 44 + int i; 45 + 46 + for (i = 0; i < card->num_rtd; i++) { 47 + struct snd_soc_pcm_runtime *rtd; 48 + 49 + rtd = card->rtd + i; 50 + if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 51 + strlen(CHT_CODEC_DAI))) 52 + return rtd->codec_dai; 53 + } 54 + return NULL; 55 + } 56 + 57 + static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { 58 + SND_SOC_DAPM_HP("Headphone", NULL), 59 + SND_SOC_DAPM_MIC("Headset Mic", NULL), 60 + SND_SOC_DAPM_MIC("Int Mic", NULL), 61 + SND_SOC_DAPM_SPK("Ext Spk", NULL), 62 + }; 63 + 64 + static const struct snd_soc_dapm_route cht_audio_map[] = { 65 + {"IN34", NULL, "Headset Mic"}, 66 + {"Headset Mic", NULL, "MICBIAS"}, 67 + {"DMICL", NULL, "Int Mic"}, 68 + {"Headphone", NULL, "HPL"}, 69 + {"Headphone", NULL, "HPR"}, 70 + {"Ext Spk", NULL, "SPKL"}, 71 + {"Ext Spk", NULL, "SPKR"}, 72 + {"AIF1 Playback", NULL, "ssp2 Tx"}, 73 + {"ssp2 Tx", NULL, "codec_out0"}, 74 + {"ssp2 Tx", NULL, "codec_out1"}, 75 + {"codec_in0", NULL, "ssp2 Rx" }, 76 + {"codec_in1", NULL, "ssp2 Rx" }, 77 + {"ssp2 Rx", NULL, "AIF1 Capture"}, 78 + }; 79 + 80 + static const struct snd_kcontrol_new cht_mc_controls[] = { 81 + SOC_DAPM_PIN_SWITCH("Headphone"), 82 + SOC_DAPM_PIN_SWITCH("Headset Mic"), 83 + SOC_DAPM_PIN_SWITCH("Int Mic"), 84 + SOC_DAPM_PIN_SWITCH("Ext Spk"), 85 + }; 86 + 87 + static int cht_aif1_hw_params(struct snd_pcm_substream *substream, 88 + struct snd_pcm_hw_params *params) 89 + { 90 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 91 + struct snd_soc_dai *codec_dai = rtd->codec_dai; 92 + int ret; 93 + 94 + ret = snd_soc_dai_set_sysclk(codec_dai, M98090_REG_SYSTEM_CLOCK, 95 + CHT_PLAT_CLK_3_HZ, SND_SOC_CLOCK_IN); 96 + if (ret < 0) { 97 + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); 98 + return ret; 99 + } 100 + 101 + return 0; 102 + } 103 + 104 + static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) 105 + { 106 + int ret; 107 + int jack_type; 108 + struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); 109 + struct snd_soc_jack *jack = &ctx->jack; 110 + 111 + /** 112 + * TI supports 4 butons headset detection 113 + * KEY_MEDIA 114 + * KEY_VOICECOMMAND 115 + * KEY_VOLUMEUP 116 + * KEY_VOLUMEDOWN 117 + */ 118 + if (ctx->ts3a227e_present) 119 + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | 120 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 121 + SND_JACK_BTN_2 | SND_JACK_BTN_3; 122 + else 123 + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE; 124 + 125 + ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", 126 + jack_type, jack, NULL, 0); 127 + 128 + if (ret) { 129 + dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret); 130 + return ret; 131 + } 132 + 133 + return ret; 134 + } 135 + 136 + static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, 137 + struct snd_pcm_hw_params *params) 138 + { 139 + struct snd_interval *rate = hw_param_interval(params, 140 + SNDRV_PCM_HW_PARAM_RATE); 141 + struct snd_interval *channels = hw_param_interval(params, 142 + SNDRV_PCM_HW_PARAM_CHANNELS); 143 + int ret = 0; 144 + unsigned int fmt = 0; 145 + 146 + ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16); 147 + if (ret < 0) { 148 + dev_err(rtd->dev, "can't set cpu_dai slot fmt: %d\n", ret); 149 + return ret; 150 + } 151 + 152 + fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF 153 + | SND_SOC_DAIFMT_CBS_CFS; 154 + 155 + ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt); 156 + if (ret < 0) { 157 + dev_err(rtd->dev, "can't set cpu_dai set fmt: %d\n", ret); 158 + return ret; 159 + } 160 + 161 + /* The DSP will covert the FE rate to 48k, stereo, 24bits */ 162 + rate->min = rate->max = 48000; 163 + channels->min = channels->max = 2; 164 + 165 + /* set SSP2 to 24-bit */ 166 + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 167 + return 0; 168 + } 169 + 170 + static unsigned int rates_48000[] = { 171 + 48000, 172 + }; 173 + 174 + static struct snd_pcm_hw_constraint_list constraints_48000 = { 175 + .count = ARRAY_SIZE(rates_48000), 176 + .list = rates_48000, 177 + }; 178 + 179 + static int cht_aif1_startup(struct snd_pcm_substream *substream) 180 + { 181 + return snd_pcm_hw_constraint_list(substream->runtime, 0, 182 + SNDRV_PCM_HW_PARAM_RATE, 183 + &constraints_48000); 184 + } 185 + 186 + static int cht_max98090_headset_init(struct snd_soc_component *component) 187 + { 188 + struct snd_soc_card *card = component->card; 189 + struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); 190 + 191 + return ts3a227e_enable_jack_detect(component, &ctx->jack); 192 + } 193 + 194 + static struct snd_soc_ops cht_aif1_ops = { 195 + .startup = cht_aif1_startup, 196 + }; 197 + 198 + static struct snd_soc_ops cht_be_ssp2_ops = { 199 + .hw_params = cht_aif1_hw_params, 200 + }; 201 + 202 + static struct snd_soc_aux_dev cht_max98090_headset_dev = { 203 + .name = "Headset Chip", 204 + .init = cht_max98090_headset_init, 205 + .codec_name = "i2c-104C227E:00", 206 + }; 207 + 208 + static struct snd_soc_dai_link cht_dailink[] = { 209 + [MERR_DPCM_AUDIO] = { 210 + .name = "Audio Port", 211 + .stream_name = "Audio", 212 + .cpu_dai_name = "media-cpu-dai", 213 + .codec_dai_name = "snd-soc-dummy-dai", 214 + .codec_name = "snd-soc-dummy", 215 + .platform_name = "sst-mfld-platform", 216 + .nonatomic = true, 217 + .dynamic = 1, 218 + .dpcm_playback = 1, 219 + .dpcm_capture = 1, 220 + .ops = &cht_aif1_ops, 221 + }, 222 + [MERR_DPCM_COMPR] = { 223 + .name = "Compressed Port", 224 + .stream_name = "Compress", 225 + .cpu_dai_name = "compress-cpu-dai", 226 + .codec_dai_name = "snd-soc-dummy-dai", 227 + .codec_name = "snd-soc-dummy", 228 + .platform_name = "sst-mfld-platform", 229 + }, 230 + /* back ends */ 231 + { 232 + .name = "SSP2-Codec", 233 + .be_id = 1, 234 + .cpu_dai_name = "ssp2-port", 235 + .platform_name = "sst-mfld-platform", 236 + .no_pcm = 1, 237 + .codec_dai_name = "HiFi", 238 + .codec_name = "i2c-193C9890:00", 239 + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 240 + | SND_SOC_DAIFMT_CBS_CFS, 241 + .init = cht_codec_init, 242 + .be_hw_params_fixup = cht_codec_fixup, 243 + .dpcm_playback = 1, 244 + .dpcm_capture = 1, 245 + .ops = &cht_be_ssp2_ops, 246 + }, 247 + }; 248 + 249 + /* SoC card */ 250 + static struct snd_soc_card snd_soc_card_cht = { 251 + .name = "chtmax98090", 252 + .dai_link = cht_dailink, 253 + .num_links = ARRAY_SIZE(cht_dailink), 254 + .aux_dev = &cht_max98090_headset_dev, 255 + .num_aux_devs = 1, 256 + .dapm_widgets = cht_dapm_widgets, 257 + .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), 258 + .dapm_routes = cht_audio_map, 259 + .num_dapm_routes = ARRAY_SIZE(cht_audio_map), 260 + .controls = cht_mc_controls, 261 + .num_controls = ARRAY_SIZE(cht_mc_controls), 262 + }; 263 + 264 + static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level, 265 + void *context, void **ret) 266 + { 267 + *(bool *)context = true; 268 + return AE_OK; 269 + } 270 + 271 + static int snd_cht_mc_probe(struct platform_device *pdev) 272 + { 273 + int ret_val = 0; 274 + bool found = false; 275 + struct cht_mc_private *drv; 276 + 277 + drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 278 + if (!drv) 279 + return -ENOMEM; 280 + 281 + if (ACPI_SUCCESS(acpi_get_devices( 282 + "104C227E", 283 + snd_acpi_codec_match, 284 + &found, NULL)) && found) { 285 + drv->ts3a227e_present = true; 286 + } else { 287 + /* no need probe TI jack detection chip */ 288 + snd_soc_card_cht.aux_dev = NULL; 289 + snd_soc_card_cht.num_aux_devs = 0; 290 + drv->ts3a227e_present = false; 291 + } 292 + 293 + /* register the soc card */ 294 + snd_soc_card_cht.dev = &pdev->dev; 295 + snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); 296 + ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); 297 + if (ret_val) { 298 + dev_err(&pdev->dev, 299 + "snd_soc_register_card failed %d\n", ret_val); 300 + return ret_val; 301 + } 302 + platform_set_drvdata(pdev, &snd_soc_card_cht); 303 + return ret_val; 304 + } 305 + 306 + static struct platform_driver snd_cht_mc_driver = { 307 + .driver = { 308 + .name = "cht-bsw-max98090", 309 + }, 310 + .probe = snd_cht_mc_probe, 311 + }; 312 + 313 + module_platform_driver(snd_cht_mc_driver) 314 + 315 + MODULE_DESCRIPTION("ASoC Intel(R) Braswell Machine driver"); 316 + MODULE_AUTHOR("Fang, Yang A <yang.a.fang@intel.com>"); 317 + MODULE_LICENSE("GPL v2"); 318 + MODULE_ALIAS("platform:cht-bsw-max98090");
+95 -25
sound/soc/intel/boards/cht_bsw_rt5645.c
··· 21 21 */ 22 22 23 23 #include <linux/module.h> 24 + #include <linux/acpi.h> 24 25 #include <linux/platform_device.h> 25 26 #include <linux/slab.h> 26 27 #include <sound/pcm.h> ··· 34 33 #define CHT_PLAT_CLK_3_HZ 19200000 35 34 #define CHT_CODEC_DAI "rt5645-aif1" 36 35 36 + struct cht_acpi_card { 37 + char *codec_id; 38 + int codec_type; 39 + struct snd_soc_card *soc_card; 40 + }; 41 + 37 42 struct cht_mc_private { 38 - struct snd_soc_jack hp_jack; 39 - struct snd_soc_jack mic_jack; 43 + struct snd_soc_jack jack; 44 + struct cht_acpi_card *acpi_card; 40 45 }; 41 46 42 47 static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) ··· 101 94 platform_clock_control, SND_SOC_DAPM_POST_PMD), 102 95 }; 103 96 104 - static const struct snd_soc_dapm_route cht_audio_map[] = { 97 + static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { 105 98 {"IN1P", NULL, "Headset Mic"}, 106 99 {"IN1N", NULL, "Headset Mic"}, 107 100 {"DMIC L1", NULL, "Int Mic"}, 108 101 {"DMIC R1", NULL, "Int Mic"}, 102 + {"Headphone", NULL, "HPOL"}, 103 + {"Headphone", NULL, "HPOR"}, 104 + {"Ext Spk", NULL, "SPOL"}, 105 + {"Ext Spk", NULL, "SPOR"}, 106 + {"AIF1 Playback", NULL, "ssp2 Tx"}, 107 + {"ssp2 Tx", NULL, "codec_out0"}, 108 + {"ssp2 Tx", NULL, "codec_out1"}, 109 + {"codec_in0", NULL, "ssp2 Rx" }, 110 + {"codec_in1", NULL, "ssp2 Rx" }, 111 + {"ssp2 Rx", NULL, "AIF1 Capture"}, 112 + {"Headphone", NULL, "Platform Clock"}, 113 + {"Headset Mic", NULL, "Platform Clock"}, 114 + {"Int Mic", NULL, "Platform Clock"}, 115 + {"Ext Spk", NULL, "Platform Clock"}, 116 + }; 117 + 118 + static const struct snd_soc_dapm_route cht_rt5650_audio_map[] = { 119 + {"IN1P", NULL, "Headset Mic"}, 120 + {"IN1N", NULL, "Headset Mic"}, 121 + {"DMIC L2", NULL, "Int Mic"}, 122 + {"DMIC R2", NULL, "Int Mic"}, 109 123 {"Headphone", NULL, "HPOL"}, 110 124 {"Headphone", NULL, "HPOR"}, 111 125 {"Ext Spk", NULL, "SPOL"}, ··· 178 150 static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) 179 151 { 180 152 int ret; 153 + int jack_type; 181 154 struct snd_soc_codec *codec = runtime->codec; 182 155 struct snd_soc_dai *codec_dai = runtime->codec_dai; 183 156 struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); ··· 198 169 return ret; 199 170 } 200 171 201 - ret = snd_soc_card_jack_new(runtime->card, "Headphone Jack", 202 - SND_JACK_HEADPHONE, &ctx->hp_jack, 172 + if (ctx->acpi_card->codec_type == CODEC_TYPE_RT5650) 173 + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | 174 + SND_JACK_BTN_0 | SND_JACK_BTN_1 | 175 + SND_JACK_BTN_2 | SND_JACK_BTN_3; 176 + else 177 + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE; 178 + 179 + ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", 180 + jack_type, &ctx->jack, 203 181 NULL, 0); 204 182 if (ret) { 205 - dev_err(runtime->dev, "HP jack creation failed %d\n", ret); 183 + dev_err(runtime->dev, "Headset jack creation failed %d\n", ret); 206 184 return ret; 207 185 } 208 186 209 - ret = snd_soc_card_jack_new(runtime->card, "Mic Jack", 210 - SND_JACK_MICROPHONE, &ctx->mic_jack, 211 - NULL, 0); 212 - if (ret) { 213 - dev_err(runtime->dev, "Mic jack creation failed %d\n", ret); 214 - return ret; 215 - } 216 - 217 - rt5645_set_jack_detect(codec, &ctx->hp_jack, &ctx->mic_jack, NULL); 187 + rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); 218 188 219 189 return ret; 220 190 } ··· 267 239 .codec_dai_name = "snd-soc-dummy-dai", 268 240 .codec_name = "snd-soc-dummy", 269 241 .platform_name = "sst-mfld-platform", 270 - .ignore_suspend = 1, 242 + .nonatomic = true, 271 243 .dynamic = 1, 272 244 .dpcm_playback = 1, 273 245 .dpcm_capture = 1, ··· 295 267 | SND_SOC_DAIFMT_CBS_CFS, 296 268 .init = cht_codec_init, 297 269 .be_hw_params_fixup = cht_codec_fixup, 298 - .ignore_suspend = 1, 270 + .nonatomic = true, 299 271 .dpcm_playback = 1, 300 272 .dpcm_capture = 1, 301 273 .ops = &cht_be_ssp2_ops, ··· 303 275 }; 304 276 305 277 /* SoC card */ 306 - static struct snd_soc_card snd_soc_card_cht = { 278 + static struct snd_soc_card snd_soc_card_chtrt5645 = { 307 279 .name = "chtrt5645", 308 280 .dai_link = cht_dailink, 309 281 .num_links = ARRAY_SIZE(cht_dailink), 310 282 .dapm_widgets = cht_dapm_widgets, 311 283 .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), 312 - .dapm_routes = cht_audio_map, 313 - .num_dapm_routes = ARRAY_SIZE(cht_audio_map), 284 + .dapm_routes = cht_rt5645_audio_map, 285 + .num_dapm_routes = ARRAY_SIZE(cht_rt5645_audio_map), 314 286 .controls = cht_mc_controls, 315 287 .num_controls = ARRAY_SIZE(cht_mc_controls), 316 288 }; 317 289 290 + static struct snd_soc_card snd_soc_card_chtrt5650 = { 291 + .name = "chtrt5650", 292 + .dai_link = cht_dailink, 293 + .num_links = ARRAY_SIZE(cht_dailink), 294 + .dapm_widgets = cht_dapm_widgets, 295 + .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), 296 + .dapm_routes = cht_rt5650_audio_map, 297 + .num_dapm_routes = ARRAY_SIZE(cht_rt5650_audio_map), 298 + .controls = cht_mc_controls, 299 + .num_controls = ARRAY_SIZE(cht_mc_controls), 300 + }; 301 + 302 + static struct cht_acpi_card snd_soc_cards[] = { 303 + {"10EC5645", CODEC_TYPE_RT5645, &snd_soc_card_chtrt5645}, 304 + {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650}, 305 + }; 306 + 307 + static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level, 308 + void *context, void **ret) 309 + { 310 + *(bool *)context = true; 311 + return AE_OK; 312 + } 313 + 318 314 static int snd_cht_mc_probe(struct platform_device *pdev) 319 315 { 320 316 int ret_val = 0; 317 + int i; 321 318 struct cht_mc_private *drv; 319 + struct snd_soc_card *card = snd_soc_cards[0].soc_card; 320 + bool found = false; 321 + char codec_name[16]; 322 322 323 323 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 324 324 if (!drv) 325 325 return -ENOMEM; 326 326 327 - snd_soc_card_cht.dev = &pdev->dev; 328 - snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); 329 - ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); 327 + for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { 328 + if (ACPI_SUCCESS(acpi_get_devices( 329 + snd_soc_cards[i].codec_id, 330 + snd_acpi_codec_match, 331 + &found, NULL)) && found) { 332 + dev_dbg(&pdev->dev, 333 + "found codec %s\n", snd_soc_cards[i].codec_id); 334 + card = snd_soc_cards[i].soc_card; 335 + drv->acpi_card = &snd_soc_cards[i]; 336 + break; 337 + } 338 + } 339 + card->dev = &pdev->dev; 340 + sprintf(codec_name, "i2c-%s:00", drv->acpi_card->codec_id); 341 + /* set correct codec name */ 342 + strcpy((char *)card->dai_link[2].codec_name, codec_name); 343 + snd_soc_card_set_drvdata(card, drv); 344 + ret_val = devm_snd_soc_register_card(&pdev->dev, card); 330 345 if (ret_val) { 331 346 dev_err(&pdev->dev, 332 347 "snd_soc_register_card failed %d\n", ret_val); 333 348 return ret_val; 334 349 } 335 - platform_set_drvdata(pdev, &snd_soc_card_cht); 350 + platform_set_drvdata(pdev, card); 336 351 return ret_val; 337 352 } 338 353 339 354 static struct platform_driver snd_cht_mc_driver = { 340 355 .driver = { 341 356 .name = "cht-bsw-rt5645", 342 - .pm = &snd_soc_pm_ops, 343 357 }, 344 358 .probe = snd_cht_mc_probe, 345 359 };
+30 -4
sound/soc/intel/common/sst-ipc.c
··· 129 129 return -ENOMEM; 130 130 131 131 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 132 + ipc->msg[i].tx_data = kzalloc(ipc->tx_data_max_size, GFP_KERNEL); 133 + if (ipc->msg[i].tx_data == NULL) 134 + goto free_mem; 135 + 136 + ipc->msg[i].rx_data = kzalloc(ipc->rx_data_max_size, GFP_KERNEL); 137 + if (ipc->msg[i].rx_data == NULL) { 138 + kfree(ipc->msg[i].tx_data); 139 + goto free_mem; 140 + } 141 + 132 142 init_waitqueue_head(&ipc->msg[i].waitq); 133 143 list_add(&ipc->msg[i].list, &ipc->empty_list); 134 144 } 135 145 136 146 return 0; 147 + 148 + free_mem: 149 + while (i > 0) { 150 + kfree(ipc->msg[i-1].tx_data); 151 + kfree(ipc->msg[i-1].rx_data); 152 + --i; 153 + } 154 + kfree(ipc->msg); 155 + 156 + return -ENOMEM; 137 157 } 138 158 139 159 static void ipc_tx_msgs(struct kthread_work *work) ··· 162 142 container_of(work, struct sst_generic_ipc, kwork); 163 143 struct ipc_message *msg; 164 144 unsigned long flags; 165 - u64 ipcx; 166 145 167 146 spin_lock_irqsave(&ipc->dsp->spinlock, flags); 168 147 ··· 172 153 173 154 /* if the DSP is busy, we will TX messages after IRQ. 174 155 * also postpone if we are in the middle of procesing completion irq*/ 175 - ipcx = sst_dsp_shim_read_unlocked(ipc->dsp, SST_IPCX); 176 - if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) { 156 + if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) { 157 + dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n"); 177 158 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); 178 159 return; 179 160 } ··· 299 280 300 281 void sst_ipc_fini(struct sst_generic_ipc *ipc) 301 282 { 283 + int i; 284 + 302 285 if (ipc->tx_thread) 303 286 kthread_stop(ipc->tx_thread); 304 287 305 - if (ipc->msg) 288 + if (ipc->msg) { 289 + for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 290 + kfree(ipc->msg[i].tx_data); 291 + kfree(ipc->msg[i].rx_data); 292 + } 306 293 kfree(ipc->msg); 294 + } 307 295 } 308 296 EXPORT_SYMBOL_GPL(sst_ipc_fini); 309 297
+5 -2
sound/soc/intel/common/sst-ipc.h
··· 32 32 u64 header; 33 33 34 34 /* direction wrt host CPU */ 35 - char tx_data[IPC_MAX_MAILBOX_BYTES]; 35 + char *tx_data; 36 36 size_t tx_size; 37 - char rx_data[IPC_MAX_MAILBOX_BYTES]; 37 + char *rx_data; 38 38 size_t rx_size; 39 39 40 40 wait_queue_head_t waitq; ··· 51 51 void (*shim_dbg)(struct sst_generic_ipc *, const char *); 52 52 void (*tx_data_copy)(struct ipc_message *, char *, size_t); 53 53 u64 (*reply_msg_match)(u64 header, u64 *mask); 54 + bool (*is_dsp_busy)(struct sst_dsp *dsp); 54 55 }; 55 56 56 57 /* SST generic IPC data */ ··· 69 68 struct kthread_work kwork; 70 69 bool pending; 71 70 struct ipc_message *msg; 71 + int tx_data_max_size; 72 + int rx_data_max_size; 72 73 73 74 struct sst_plat_ipc_ops ops; 74 75 };
+12
sound/soc/intel/haswell/sst-haswell-ipc.c
··· 2098 2098 return header; 2099 2099 } 2100 2100 2101 + static bool hsw_is_dsp_busy(struct sst_dsp *dsp) 2102 + { 2103 + u64 ipcx; 2104 + 2105 + ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX); 2106 + return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)); 2107 + } 2108 + 2101 2109 int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) 2102 2110 { 2103 2111 struct sst_hsw_ipc_fw_version version; ··· 2125 2117 ipc->ops.shim_dbg = hsw_shim_dbg; 2126 2118 ipc->ops.tx_data_copy = hsw_tx_data_copy; 2127 2119 ipc->ops.reply_msg_match = hsw_reply_msg_match; 2120 + ipc->ops.is_dsp_busy = hsw_is_dsp_busy; 2121 + 2122 + ipc->tx_data_max_size = IPC_MAX_MAILBOX_BYTES; 2123 + ipc->rx_data_max_size = IPC_MAX_MAILBOX_BYTES; 2128 2124 2129 2125 ret = sst_ipc_init(ipc); 2130 2126 if (ret != 0)
+23 -8
sound/soc/intel/haswell/sst-haswell-pcm.c
··· 928 928 929 929 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 930 930 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; 931 - sst_hsw_runtime_module_free(pcm_data->runtime); 931 + if (pcm_data->runtime){ 932 + sst_hsw_runtime_module_free(pcm_data->runtime); 933 + pcm_data->runtime = NULL; 934 + } 932 935 } 933 - if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) { 936 + if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES) && 937 + pdata->runtime_waves) { 934 938 sst_hsw_runtime_module_free(pdata->runtime_waves); 939 + pdata->runtime_waves = NULL; 935 940 } 936 941 } 937 942 ··· 1209 1204 return 0; 1210 1205 } 1211 1206 1207 + static int hsw_pcm_suspend(struct device *dev) 1208 + { 1209 + struct hsw_priv_data *pdata = dev_get_drvdata(dev); 1210 + struct sst_hsw *hsw = pdata->hsw; 1211 + 1212 + /* enter D3 state and stall */ 1213 + sst_hsw_dsp_runtime_suspend(hsw); 1214 + /* free all runtime modules */ 1215 + hsw_pcm_free_modules(pdata); 1216 + /* put the DSP to sleep, fw unloaded after runtime modules freed */ 1217 + sst_hsw_dsp_runtime_sleep(hsw); 1218 + return 0; 1219 + } 1220 + 1212 1221 static int hsw_pcm_runtime_suspend(struct device *dev) 1213 1222 { 1214 1223 struct hsw_priv_data *pdata = dev_get_drvdata(dev); ··· 1239 1220 return ret; 1240 1221 sst_hsw_set_module_enabled_rtd3(hsw, SST_HSW_MODULE_WAVES); 1241 1222 } 1242 - sst_hsw_dsp_runtime_suspend(hsw); 1243 - sst_hsw_dsp_runtime_sleep(hsw); 1223 + hsw_pcm_suspend(dev); 1244 1224 pdata->pm_state = HSW_PM_STATE_RTD3; 1245 1225 1246 1226 return 0; ··· 1379 1361 if (err < 0) 1380 1362 dev_err(dev, "failed to save context for PCM %d\n", i); 1381 1363 } 1382 - /* enter D3 state and stall */ 1383 - sst_hsw_dsp_runtime_suspend(hsw); 1384 - /* put the DSP to sleep */ 1385 - sst_hsw_dsp_runtime_sleep(hsw); 1364 + hsw_pcm_suspend(dev); 1386 1365 } 1387 1366 1388 1367 snd_soc_suspend(pdata->soc_card->dev);
+8 -22
sound/soc/omap/rx51.c
··· 455 455 snd_soc_card_set_drvdata(card, pdata); 456 456 457 457 pdata->tvout_selection_gpio = devm_gpiod_get(card->dev, 458 - "tvout-selection"); 458 + "tvout-selection", 459 + GPIOD_OUT_LOW); 459 460 if (IS_ERR(pdata->tvout_selection_gpio)) { 460 461 dev_err(card->dev, "could not get tvout selection gpio\n"); 461 462 return PTR_ERR(pdata->tvout_selection_gpio); 462 463 } 463 464 464 - err = gpiod_direction_output(pdata->tvout_selection_gpio, 0); 465 - if (err) { 466 - dev_err(card->dev, "could not setup tvout selection gpio\n"); 467 - return err; 468 - } 469 - 470 465 pdata->jack_detection_gpio = devm_gpiod_get(card->dev, 471 - "jack-detection"); 466 + "jack-detection", 467 + GPIOD_ASIS); 472 468 if (IS_ERR(pdata->jack_detection_gpio)) { 473 469 dev_err(card->dev, "could not get jack detection gpio\n"); 474 470 return PTR_ERR(pdata->jack_detection_gpio); 475 471 } 476 472 477 - pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch"); 473 + pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch", 474 + GPIOD_OUT_HIGH); 478 475 if (IS_ERR(pdata->eci_sw_gpio)) { 479 476 dev_err(card->dev, "could not get eci switch gpio\n"); 480 477 return PTR_ERR(pdata->eci_sw_gpio); 481 478 } 482 479 483 - err = gpiod_direction_output(pdata->eci_sw_gpio, 1); 484 - if (err) { 485 - dev_err(card->dev, "could not setup eci switch gpio\n"); 486 - return err; 487 - } 488 - 489 480 pdata->speaker_amp_gpio = devm_gpiod_get(card->dev, 490 - "speaker-amplifier"); 481 + "speaker-amplifier", 482 + GPIOD_OUT_LOW); 491 483 if (IS_ERR(pdata->speaker_amp_gpio)) { 492 484 dev_err(card->dev, "could not get speaker enable gpio\n"); 493 485 return PTR_ERR(pdata->speaker_amp_gpio); 494 - } 495 - 496 - err = gpiod_direction_output(pdata->speaker_amp_gpio, 0); 497 - if (err) { 498 - dev_err(card->dev, "could not setup speaker enable gpio\n"); 499 - return err; 500 486 } 501 487 502 488 err = devm_snd_soc_register_card(card->dev, card);