0001
0002
0003
0004
0005
0006
0007
0008 #include <sound/soc.h>
0009 #include <sound/jack.h>
0010
0011 #define soc_card_ret(dai, ret) _soc_card_ret(dai, __func__, ret)
0012 static inline int _soc_card_ret(struct snd_soc_card *card,
0013 const char *func, int ret)
0014 {
0015 switch (ret) {
0016 case -EPROBE_DEFER:
0017 case -ENOTSUPP:
0018 case 0:
0019 break;
0020 default:
0021 dev_err(card->dev,
0022 "ASoC: error at %s on %s: %d\n",
0023 func, card->name, ret);
0024 }
0025
0026 return ret;
0027 }
0028
0029 struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
0030 const char *name)
0031 {
0032 struct snd_card *card = soc_card->snd_card;
0033 struct snd_kcontrol *kctl;
0034
0035 if (unlikely(!name))
0036 return NULL;
0037
0038 list_for_each_entry(kctl, &card->controls, list)
0039 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name)))
0040 return kctl;
0041 return NULL;
0042 }
0043 EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol);
0044
0045 static int jack_new(struct snd_soc_card *card, const char *id, int type,
0046 struct snd_soc_jack *jack, bool initial_kctl)
0047 {
0048 mutex_init(&jack->mutex);
0049 jack->card = card;
0050 INIT_LIST_HEAD(&jack->pins);
0051 INIT_LIST_HEAD(&jack->jack_zones);
0052 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
0053
0054 return snd_jack_new(card->snd_card, id, type, &jack->jack, initial_kctl, false);
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
0073 struct snd_soc_jack *jack)
0074 {
0075 return soc_card_ret(card, jack_new(card, id, type, jack, true));
0076 }
0077 EXPORT_SYMBOL_GPL(snd_soc_card_jack_new);
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 int snd_soc_card_jack_new_pins(struct snd_soc_card *card, const char *id,
0096 int type, struct snd_soc_jack *jack,
0097 struct snd_soc_jack_pin *pins,
0098 unsigned int num_pins)
0099 {
0100 int ret;
0101
0102 ret = jack_new(card, id, type, jack, false);
0103 if (ret)
0104 goto end;
0105
0106 if (num_pins)
0107 ret = snd_soc_jack_add_pins(jack, num_pins, pins);
0108 end:
0109 return soc_card_ret(card, ret);
0110 }
0111 EXPORT_SYMBOL_GPL(snd_soc_card_jack_new_pins);
0112
0113 int snd_soc_card_suspend_pre(struct snd_soc_card *card)
0114 {
0115 int ret = 0;
0116
0117 if (card->suspend_pre)
0118 ret = card->suspend_pre(card);
0119
0120 return soc_card_ret(card, ret);
0121 }
0122
0123 int snd_soc_card_suspend_post(struct snd_soc_card *card)
0124 {
0125 int ret = 0;
0126
0127 if (card->suspend_post)
0128 ret = card->suspend_post(card);
0129
0130 return soc_card_ret(card, ret);
0131 }
0132
0133 int snd_soc_card_resume_pre(struct snd_soc_card *card)
0134 {
0135 int ret = 0;
0136
0137 if (card->resume_pre)
0138 ret = card->resume_pre(card);
0139
0140 return soc_card_ret(card, ret);
0141 }
0142
0143 int snd_soc_card_resume_post(struct snd_soc_card *card)
0144 {
0145 int ret = 0;
0146
0147 if (card->resume_post)
0148 ret = card->resume_post(card);
0149
0150 return soc_card_ret(card, ret);
0151 }
0152
0153 int snd_soc_card_probe(struct snd_soc_card *card)
0154 {
0155 if (card->probe) {
0156 int ret = card->probe(card);
0157
0158 if (ret < 0)
0159 return soc_card_ret(card, ret);
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170 card->probed = 1;
0171 }
0172
0173 return 0;
0174 }
0175
0176 int snd_soc_card_late_probe(struct snd_soc_card *card)
0177 {
0178 if (card->late_probe) {
0179 int ret = card->late_probe(card);
0180
0181 if (ret < 0)
0182 return soc_card_ret(card, ret);
0183 }
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 card->probed = 1;
0196
0197 return 0;
0198 }
0199
0200 void snd_soc_card_fixup_controls(struct snd_soc_card *card)
0201 {
0202 if (card->fixup_controls)
0203 card->fixup_controls(card);
0204 }
0205
0206 int snd_soc_card_remove(struct snd_soc_card *card)
0207 {
0208 int ret = 0;
0209
0210 if (card->probed &&
0211 card->remove)
0212 ret = card->remove(card);
0213
0214 card->probed = 0;
0215
0216 return soc_card_ret(card, ret);
0217 }
0218
0219 int snd_soc_card_set_bias_level(struct snd_soc_card *card,
0220 struct snd_soc_dapm_context *dapm,
0221 enum snd_soc_bias_level level)
0222 {
0223 int ret = 0;
0224
0225 if (card && card->set_bias_level)
0226 ret = card->set_bias_level(card, dapm, level);
0227
0228 return soc_card_ret(card, ret);
0229 }
0230
0231 int snd_soc_card_set_bias_level_post(struct snd_soc_card *card,
0232 struct snd_soc_dapm_context *dapm,
0233 enum snd_soc_bias_level level)
0234 {
0235 int ret = 0;
0236
0237 if (card && card->set_bias_level_post)
0238 ret = card->set_bias_level_post(card, dapm, level);
0239
0240 return soc_card_ret(card, ret);
0241 }
0242
0243 int snd_soc_card_add_dai_link(struct snd_soc_card *card,
0244 struct snd_soc_dai_link *dai_link)
0245 {
0246 int ret = 0;
0247
0248 if (card->add_dai_link)
0249 ret = card->add_dai_link(card, dai_link);
0250
0251 return soc_card_ret(card, ret);
0252 }
0253 EXPORT_SYMBOL_GPL(snd_soc_card_add_dai_link);
0254
0255 void snd_soc_card_remove_dai_link(struct snd_soc_card *card,
0256 struct snd_soc_dai_link *dai_link)
0257 {
0258 if (card->remove_dai_link)
0259 card->remove_dai_link(card, dai_link);
0260 }
0261 EXPORT_SYMBOL_GPL(snd_soc_card_remove_dai_link);