0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/init.h>
0011 #include <linux/delay.h>
0012 #include <linux/module.h>
0013 #include <linux/pm_runtime.h>
0014 #include <sound/pcm_params.h>
0015 #include <sound/soc.h>
0016 #include <sound/hdaudio_ext.h>
0017 #include <sound/hda_i915.h>
0018 #include <sound/hda_codec.h>
0019 #include <sound/hda_register.h>
0020
0021 #include "hdac_hda.h"
0022
0023 #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
0024 SNDRV_PCM_FMTBIT_U8 | \
0025 SNDRV_PCM_FMTBIT_S16_LE | \
0026 SNDRV_PCM_FMTBIT_U16_LE | \
0027 SNDRV_PCM_FMTBIT_S24_LE | \
0028 SNDRV_PCM_FMTBIT_U24_LE | \
0029 SNDRV_PCM_FMTBIT_S32_LE | \
0030 SNDRV_PCM_FMTBIT_U32_LE | \
0031 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
0032
0033 #define STUB_HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
0034 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
0035 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
0036 SNDRV_PCM_RATE_192000)
0037
0038 static int hdac_hda_dai_open(struct snd_pcm_substream *substream,
0039 struct snd_soc_dai *dai);
0040 static void hdac_hda_dai_close(struct snd_pcm_substream *substream,
0041 struct snd_soc_dai *dai);
0042 static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream,
0043 struct snd_soc_dai *dai);
0044 static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,
0045 struct snd_pcm_hw_params *params,
0046 struct snd_soc_dai *dai);
0047 static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream,
0048 struct snd_soc_dai *dai);
0049 static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai, void *stream,
0050 int direction);
0051 static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,
0052 struct snd_soc_dai *dai);
0053
0054 static const struct snd_soc_dai_ops hdac_hda_dai_ops = {
0055 .startup = hdac_hda_dai_open,
0056 .shutdown = hdac_hda_dai_close,
0057 .prepare = hdac_hda_dai_prepare,
0058 .hw_params = hdac_hda_dai_hw_params,
0059 .hw_free = hdac_hda_dai_hw_free,
0060 .set_stream = hdac_hda_dai_set_stream,
0061 };
0062
0063 static struct snd_soc_dai_driver hdac_hda_dais[] = {
0064 {
0065 .id = HDAC_ANALOG_DAI_ID,
0066 .name = "Analog Codec DAI",
0067 .ops = &hdac_hda_dai_ops,
0068 .playback = {
0069 .stream_name = "Analog Codec Playback",
0070 .channels_min = 1,
0071 .channels_max = 16,
0072 .rates = SNDRV_PCM_RATE_8000_192000,
0073 .formats = STUB_FORMATS,
0074 .sig_bits = 24,
0075 },
0076 .capture = {
0077 .stream_name = "Analog Codec Capture",
0078 .channels_min = 1,
0079 .channels_max = 16,
0080 .rates = SNDRV_PCM_RATE_8000_192000,
0081 .formats = STUB_FORMATS,
0082 .sig_bits = 24,
0083 },
0084 },
0085 {
0086 .id = HDAC_DIGITAL_DAI_ID,
0087 .name = "Digital Codec DAI",
0088 .ops = &hdac_hda_dai_ops,
0089 .playback = {
0090 .stream_name = "Digital Codec Playback",
0091 .channels_min = 1,
0092 .channels_max = 16,
0093 .rates = SNDRV_PCM_RATE_8000_192000,
0094 .formats = STUB_FORMATS,
0095 .sig_bits = 24,
0096 },
0097 .capture = {
0098 .stream_name = "Digital Codec Capture",
0099 .channels_min = 1,
0100 .channels_max = 16,
0101 .rates = SNDRV_PCM_RATE_8000_192000,
0102 .formats = STUB_FORMATS,
0103 .sig_bits = 24,
0104 },
0105 },
0106 {
0107 .id = HDAC_ALT_ANALOG_DAI_ID,
0108 .name = "Alt Analog Codec DAI",
0109 .ops = &hdac_hda_dai_ops,
0110 .playback = {
0111 .stream_name = "Alt Analog Codec Playback",
0112 .channels_min = 1,
0113 .channels_max = 16,
0114 .rates = SNDRV_PCM_RATE_8000_192000,
0115 .formats = STUB_FORMATS,
0116 .sig_bits = 24,
0117 },
0118 .capture = {
0119 .stream_name = "Alt Analog Codec Capture",
0120 .channels_min = 1,
0121 .channels_max = 16,
0122 .rates = SNDRV_PCM_RATE_8000_192000,
0123 .formats = STUB_FORMATS,
0124 .sig_bits = 24,
0125 },
0126 },
0127 {
0128 .id = HDAC_HDMI_0_DAI_ID,
0129 .name = "intel-hdmi-hifi1",
0130 .ops = &hdac_hda_dai_ops,
0131 .playback = {
0132 .stream_name = "hifi1",
0133 .channels_min = 1,
0134 .channels_max = 32,
0135 .rates = STUB_HDMI_RATES,
0136 .formats = STUB_FORMATS,
0137 .sig_bits = 24,
0138 },
0139 },
0140 {
0141 .id = HDAC_HDMI_1_DAI_ID,
0142 .name = "intel-hdmi-hifi2",
0143 .ops = &hdac_hda_dai_ops,
0144 .playback = {
0145 .stream_name = "hifi2",
0146 .channels_min = 1,
0147 .channels_max = 32,
0148 .rates = STUB_HDMI_RATES,
0149 .formats = STUB_FORMATS,
0150 .sig_bits = 24,
0151 },
0152 },
0153 {
0154 .id = HDAC_HDMI_2_DAI_ID,
0155 .name = "intel-hdmi-hifi3",
0156 .ops = &hdac_hda_dai_ops,
0157 .playback = {
0158 .stream_name = "hifi3",
0159 .channels_min = 1,
0160 .channels_max = 32,
0161 .rates = STUB_HDMI_RATES,
0162 .formats = STUB_FORMATS,
0163 .sig_bits = 24,
0164 },
0165 },
0166 {
0167 .id = HDAC_HDMI_3_DAI_ID,
0168 .name = "intel-hdmi-hifi4",
0169 .ops = &hdac_hda_dai_ops,
0170 .playback = {
0171 .stream_name = "hifi4",
0172 .channels_min = 1,
0173 .channels_max = 32,
0174 .rates = STUB_HDMI_RATES,
0175 .formats = STUB_FORMATS,
0176 .sig_bits = 24,
0177 },
0178 },
0179
0180 };
0181
0182 static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai,
0183 void *stream, int direction)
0184 {
0185 struct snd_soc_component *component = dai->component;
0186 struct hdac_hda_priv *hda_pvt;
0187 struct hdac_hda_pcm *pcm;
0188 struct hdac_stream *hstream;
0189
0190 if (!stream)
0191 return -EINVAL;
0192
0193 hda_pvt = snd_soc_component_get_drvdata(component);
0194 pcm = &hda_pvt->pcm[dai->id];
0195 hstream = (struct hdac_stream *)stream;
0196
0197 pcm->stream_tag[direction] = hstream->stream_tag;
0198
0199 return 0;
0200 }
0201
0202 static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,
0203 struct snd_pcm_hw_params *params,
0204 struct snd_soc_dai *dai)
0205 {
0206 struct snd_soc_component *component = dai->component;
0207 struct hdac_hda_priv *hda_pvt;
0208 unsigned int format_val;
0209 unsigned int maxbps;
0210
0211 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0212 maxbps = dai->driver->playback.sig_bits;
0213 else
0214 maxbps = dai->driver->capture.sig_bits;
0215
0216 hda_pvt = snd_soc_component_get_drvdata(component);
0217 format_val = snd_hdac_calc_stream_format(params_rate(params),
0218 params_channels(params),
0219 params_format(params),
0220 maxbps,
0221 0);
0222 if (!format_val) {
0223 dev_err(dai->dev,
0224 "invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n",
0225 params_rate(params), params_channels(params),
0226 params_format(params), maxbps);
0227
0228 return -EINVAL;
0229 }
0230
0231 hda_pvt->pcm[dai->id].format_val[substream->stream] = format_val;
0232 return 0;
0233 }
0234
0235 static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream,
0236 struct snd_soc_dai *dai)
0237 {
0238 struct snd_soc_component *component = dai->component;
0239 struct hdac_hda_priv *hda_pvt;
0240 struct hda_pcm_stream *hda_stream;
0241 struct hda_pcm *pcm;
0242
0243 hda_pvt = snd_soc_component_get_drvdata(component);
0244 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);
0245 if (!pcm)
0246 return -EINVAL;
0247
0248 hda_stream = &pcm->stream[substream->stream];
0249 snd_hda_codec_cleanup(&hda_pvt->codec, hda_stream, substream);
0250
0251 return 0;
0252 }
0253
0254 static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream,
0255 struct snd_soc_dai *dai)
0256 {
0257 struct snd_soc_component *component = dai->component;
0258 struct hda_pcm_stream *hda_stream;
0259 struct hdac_hda_priv *hda_pvt;
0260 struct hdac_device *hdev;
0261 unsigned int format_val;
0262 struct hda_pcm *pcm;
0263 unsigned int stream;
0264 int ret = 0;
0265
0266 hda_pvt = snd_soc_component_get_drvdata(component);
0267 hdev = &hda_pvt->codec.core;
0268 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);
0269 if (!pcm)
0270 return -EINVAL;
0271
0272 hda_stream = &pcm->stream[substream->stream];
0273
0274 stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream];
0275 format_val = hda_pvt->pcm[dai->id].format_val[substream->stream];
0276
0277 ret = snd_hda_codec_prepare(&hda_pvt->codec, hda_stream,
0278 stream, format_val, substream);
0279 if (ret < 0)
0280 dev_err(&hdev->dev, "codec prepare failed %d\n", ret);
0281
0282 return ret;
0283 }
0284
0285 static int hdac_hda_dai_open(struct snd_pcm_substream *substream,
0286 struct snd_soc_dai *dai)
0287 {
0288 struct snd_soc_component *component = dai->component;
0289 struct hdac_hda_priv *hda_pvt;
0290 struct hda_pcm_stream *hda_stream;
0291 struct hda_pcm *pcm;
0292
0293 hda_pvt = snd_soc_component_get_drvdata(component);
0294 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);
0295 if (!pcm)
0296 return -EINVAL;
0297
0298 snd_hda_codec_pcm_get(pcm);
0299
0300 hda_stream = &pcm->stream[substream->stream];
0301
0302 return hda_stream->ops.open(hda_stream, &hda_pvt->codec, substream);
0303 }
0304
0305 static void hdac_hda_dai_close(struct snd_pcm_substream *substream,
0306 struct snd_soc_dai *dai)
0307 {
0308 struct snd_soc_component *component = dai->component;
0309 struct hdac_hda_priv *hda_pvt;
0310 struct hda_pcm_stream *hda_stream;
0311 struct hda_pcm *pcm;
0312
0313 hda_pvt = snd_soc_component_get_drvdata(component);
0314 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);
0315 if (!pcm)
0316 return;
0317
0318 hda_stream = &pcm->stream[substream->stream];
0319
0320 hda_stream->ops.close(hda_stream, &hda_pvt->codec, substream);
0321
0322 snd_hda_codec_pcm_put(pcm);
0323 }
0324
0325 static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,
0326 struct snd_soc_dai *dai)
0327 {
0328 struct hda_codec *hcodec = &hda_pvt->codec;
0329 struct hda_pcm *cpcm;
0330 const char *pcm_name;
0331
0332
0333
0334
0335
0336
0337
0338 switch (dai->id) {
0339 case HDAC_ANALOG_DAI_ID:
0340 pcm_name = "Analog";
0341 break;
0342 case HDAC_DIGITAL_DAI_ID:
0343 pcm_name = "Digital";
0344 break;
0345 case HDAC_ALT_ANALOG_DAI_ID:
0346 pcm_name = "Alt Analog";
0347 break;
0348 case HDAC_HDMI_0_DAI_ID:
0349 pcm_name = "HDMI 0";
0350 break;
0351 case HDAC_HDMI_1_DAI_ID:
0352 pcm_name = "HDMI 1";
0353 break;
0354 case HDAC_HDMI_2_DAI_ID:
0355 pcm_name = "HDMI 2";
0356 break;
0357 case HDAC_HDMI_3_DAI_ID:
0358 pcm_name = "HDMI 3";
0359 break;
0360 default:
0361 dev_err(&hcodec->core.dev, "invalid dai id %d\n", dai->id);
0362 return NULL;
0363 }
0364
0365 list_for_each_entry(cpcm, &hcodec->pcm_list_head, list) {
0366 if (strstr(cpcm->name, pcm_name)) {
0367 if (strcmp(pcm_name, "Analog") == 0) {
0368 if (strstr(cpcm->name, "Alt Analog"))
0369 continue;
0370 }
0371 return cpcm;
0372 }
0373 }
0374
0375 dev_err(&hcodec->core.dev, "didn't find PCM for DAI %s\n", dai->name);
0376 return NULL;
0377 }
0378
0379 static bool is_hdmi_codec(struct hda_codec *hcodec)
0380 {
0381 struct hda_pcm *cpcm;
0382
0383 list_for_each_entry(cpcm, &hcodec->pcm_list_head, list) {
0384 if (cpcm->pcm_type == HDA_PCM_TYPE_HDMI)
0385 return true;
0386 }
0387
0388 return false;
0389 }
0390
0391 static int hdac_hda_codec_probe(struct snd_soc_component *component)
0392 {
0393 struct hdac_hda_priv *hda_pvt =
0394 snd_soc_component_get_drvdata(component);
0395 struct snd_soc_dapm_context *dapm =
0396 snd_soc_component_get_dapm(component);
0397 struct hdac_device *hdev = &hda_pvt->codec.core;
0398 struct hda_codec *hcodec = &hda_pvt->codec;
0399 struct hdac_ext_link *hlink;
0400 hda_codec_patch_t patch;
0401 int ret;
0402
0403 hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev));
0404 if (!hlink) {
0405 dev_err(&hdev->dev, "hdac link not found\n");
0406 return -EIO;
0407 }
0408
0409 snd_hdac_ext_bus_link_get(hdev->bus, hlink);
0410
0411
0412
0413
0414
0415
0416 if (hda_pvt->need_display_power)
0417 snd_hdac_display_power(hdev->bus,
0418 HDA_CODEC_IDX_CONTROLLER, true);
0419
0420 ret = snd_hda_codec_device_new(hcodec->bus, component->card->snd_card,
0421 hdev->addr, hcodec, true);
0422 if (ret < 0) {
0423 dev_err(&hdev->dev, "failed to create hda codec %d\n", ret);
0424 goto error_no_pm;
0425 }
0426
0427
0428
0429
0430
0431 hdev->type = HDA_DEV_ASOC;
0432
0433
0434
0435
0436
0437 pm_runtime_get_noresume(&hdev->dev);
0438
0439 hcodec->bus->card = dapm->card->snd_card;
0440
0441 ret = snd_hda_codec_set_name(hcodec, hcodec->preset->name);
0442 if (ret < 0) {
0443 dev_err(&hdev->dev, "name failed %s\n", hcodec->preset->name);
0444 goto error_pm;
0445 }
0446
0447 ret = snd_hdac_regmap_init(&hcodec->core);
0448 if (ret < 0) {
0449 dev_err(&hdev->dev, "regmap init failed\n");
0450 goto error_pm;
0451 }
0452
0453 patch = (hda_codec_patch_t)hcodec->preset->driver_data;
0454 if (patch) {
0455 ret = patch(hcodec);
0456 if (ret < 0) {
0457 dev_err(&hdev->dev, "patch failed %d\n", ret);
0458 goto error_regmap;
0459 }
0460 } else {
0461 dev_dbg(&hdev->dev, "no patch file found\n");
0462 }
0463
0464
0465 hcodec->mst_no_extra_pcms = 1;
0466
0467 ret = snd_hda_codec_parse_pcms(hcodec);
0468 if (ret < 0) {
0469 dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);
0470 goto error_patch;
0471 }
0472
0473
0474 if (!is_hdmi_codec(hcodec)) {
0475 ret = snd_hda_codec_build_controls(hcodec);
0476 if (ret < 0) {
0477 dev_err(&hdev->dev, "unable to create controls %d\n",
0478 ret);
0479 goto error_patch;
0480 }
0481 }
0482
0483 hcodec->core.lazy_cache = true;
0484
0485 if (hda_pvt->need_display_power)
0486 snd_hdac_display_power(hdev->bus,
0487 HDA_CODEC_IDX_CONTROLLER, false);
0488
0489
0490 pm_runtime_allow(&hdev->dev);
0491
0492
0493
0494
0495
0496
0497 pm_runtime_put(&hdev->dev);
0498 pm_runtime_suspend(&hdev->dev);
0499
0500 return 0;
0501
0502 error_patch:
0503 if (hcodec->patch_ops.free)
0504 hcodec->patch_ops.free(hcodec);
0505 error_regmap:
0506 snd_hdac_regmap_exit(hdev);
0507 error_pm:
0508 pm_runtime_put(&hdev->dev);
0509 error_no_pm:
0510 snd_hdac_ext_bus_link_put(hdev->bus, hlink);
0511 return ret;
0512 }
0513
0514 static void hdac_hda_codec_remove(struct snd_soc_component *component)
0515 {
0516 struct hdac_hda_priv *hda_pvt =
0517 snd_soc_component_get_drvdata(component);
0518 struct hdac_device *hdev = &hda_pvt->codec.core;
0519 struct hda_codec *codec = &hda_pvt->codec;
0520 struct hdac_ext_link *hlink = NULL;
0521
0522 hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev));
0523 if (!hlink) {
0524 dev_err(&hdev->dev, "hdac link not found\n");
0525 return;
0526 }
0527
0528 pm_runtime_disable(&hdev->dev);
0529 snd_hdac_ext_bus_link_put(hdev->bus, hlink);
0530
0531 if (codec->patch_ops.free)
0532 codec->patch_ops.free(codec);
0533
0534 snd_hda_codec_cleanup_for_unbind(codec);
0535 }
0536
0537 static const struct snd_soc_dapm_route hdac_hda_dapm_routes[] = {
0538 {"AIF1TX", NULL, "Codec Input Pin1"},
0539 {"AIF2TX", NULL, "Codec Input Pin2"},
0540 {"AIF3TX", NULL, "Codec Input Pin3"},
0541
0542 {"Codec Output Pin1", NULL, "AIF1RX"},
0543 {"Codec Output Pin2", NULL, "AIF2RX"},
0544 {"Codec Output Pin3", NULL, "AIF3RX"},
0545 };
0546
0547 static const struct snd_soc_dapm_widget hdac_hda_dapm_widgets[] = {
0548
0549 SND_SOC_DAPM_AIF_IN("AIF1RX", "Analog Codec Playback", 0,
0550 SND_SOC_NOPM, 0, 0),
0551 SND_SOC_DAPM_AIF_IN("AIF2RX", "Digital Codec Playback", 0,
0552 SND_SOC_NOPM, 0, 0),
0553 SND_SOC_DAPM_AIF_IN("AIF3RX", "Alt Analog Codec Playback", 0,
0554 SND_SOC_NOPM, 0, 0),
0555 SND_SOC_DAPM_AIF_OUT("AIF1TX", "Analog Codec Capture", 0,
0556 SND_SOC_NOPM, 0, 0),
0557 SND_SOC_DAPM_AIF_OUT("AIF2TX", "Digital Codec Capture", 0,
0558 SND_SOC_NOPM, 0, 0),
0559 SND_SOC_DAPM_AIF_OUT("AIF3TX", "Alt Analog Codec Capture", 0,
0560 SND_SOC_NOPM, 0, 0),
0561
0562
0563 SND_SOC_DAPM_INPUT("Codec Input Pin1"),
0564 SND_SOC_DAPM_INPUT("Codec Input Pin2"),
0565 SND_SOC_DAPM_INPUT("Codec Input Pin3"),
0566
0567
0568 SND_SOC_DAPM_OUTPUT("Codec Output Pin1"),
0569 SND_SOC_DAPM_OUTPUT("Codec Output Pin2"),
0570 SND_SOC_DAPM_OUTPUT("Codec Output Pin3"),
0571 };
0572
0573 static const struct snd_soc_component_driver hdac_hda_codec = {
0574 .probe = hdac_hda_codec_probe,
0575 .remove = hdac_hda_codec_remove,
0576 .dapm_widgets = hdac_hda_dapm_widgets,
0577 .num_dapm_widgets = ARRAY_SIZE(hdac_hda_dapm_widgets),
0578 .dapm_routes = hdac_hda_dapm_routes,
0579 .num_dapm_routes = ARRAY_SIZE(hdac_hda_dapm_routes),
0580 .idle_bias_on = false,
0581 .endianness = 1,
0582 };
0583
0584 static int hdac_hda_dev_probe(struct hdac_device *hdev)
0585 {
0586 struct hdac_ext_link *hlink;
0587 struct hdac_hda_priv *hda_pvt;
0588 int ret;
0589
0590
0591 hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev));
0592 if (!hlink) {
0593 dev_err(&hdev->dev, "hdac link not found\n");
0594 return -EIO;
0595 }
0596 snd_hdac_ext_bus_link_get(hdev->bus, hlink);
0597
0598 hda_pvt = hdac_to_hda_priv(hdev);
0599 if (!hda_pvt)
0600 return -ENOMEM;
0601
0602
0603 ret = devm_snd_soc_register_component(&hdev->dev,
0604 &hdac_hda_codec, hdac_hda_dais,
0605 ARRAY_SIZE(hdac_hda_dais));
0606 if (ret < 0) {
0607 dev_err(&hdev->dev, "failed to register HDA codec %d\n", ret);
0608 return ret;
0609 }
0610
0611 dev_set_drvdata(&hdev->dev, hda_pvt);
0612 snd_hdac_ext_bus_link_put(hdev->bus, hlink);
0613
0614 return ret;
0615 }
0616
0617 static int hdac_hda_dev_remove(struct hdac_device *hdev)
0618 {
0619
0620
0621
0622
0623 return 0;
0624 }
0625
0626 static struct hdac_ext_bus_ops hdac_ops = {
0627 .hdev_attach = hdac_hda_dev_probe,
0628 .hdev_detach = hdac_hda_dev_remove,
0629 };
0630
0631 struct hdac_ext_bus_ops *snd_soc_hdac_hda_get_ops(void)
0632 {
0633 return &hdac_ops;
0634 }
0635 EXPORT_SYMBOL_GPL(snd_soc_hdac_hda_get_ops);
0636
0637 MODULE_LICENSE("GPL v2");
0638 MODULE_DESCRIPTION("ASoC Extensions for legacy HDA Drivers");
0639 MODULE_AUTHOR("Rakesh Ughreja<rakesh.a.ughreja@intel.com>");