679 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright(c) 2015-18 Intel Corporation.3 4/*5 * hdac_hda.c - ASoC extensions to reuse the legacy HDA codec drivers6 * with ASoC platform drivers. These APIs are called by the legacy HDA7 * codec drivers using hdac_ext_bus_ops ops.8 */9 10#include <linux/firmware.h>11#include <linux/init.h>12#include <linux/delay.h>13#include <linux/module.h>14#include <linux/pm_runtime.h>15#include <sound/pcm_params.h>16#include <sound/soc.h>17#include <sound/hdaudio_ext.h>18#include <sound/hda_i915.h>19#include <sound/hda_codec.h>20#include <sound/hda_register.h>21 22#include "hdac_hda.h"23 24#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \25 SNDRV_PCM_FMTBIT_U8 | \26 SNDRV_PCM_FMTBIT_S16_LE | \27 SNDRV_PCM_FMTBIT_U16_LE | \28 SNDRV_PCM_FMTBIT_S24_LE | \29 SNDRV_PCM_FMTBIT_U24_LE | \30 SNDRV_PCM_FMTBIT_S32_LE | \31 SNDRV_PCM_FMTBIT_U32_LE | \32 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)33 34#define STUB_HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\35 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\36 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\37 SNDRV_PCM_RATE_192000)38 39#ifdef CONFIG_SND_HDA_PATCH_LOADER40static char *loadable_patch[HDA_MAX_CODECS];41 42module_param_array_named(patch, loadable_patch, charp, NULL, 0444);43MODULE_PARM_DESC(patch, "Patch file array for Intel HD audio interface. The array index is the codec address.");44#endif45 46static int hdac_hda_dai_open(struct snd_pcm_substream *substream,47 struct snd_soc_dai *dai);48static void hdac_hda_dai_close(struct snd_pcm_substream *substream,49 struct snd_soc_dai *dai);50static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream,51 struct snd_soc_dai *dai);52static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,53 struct snd_pcm_hw_params *params,54 struct snd_soc_dai *dai);55static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream,56 struct snd_soc_dai *dai);57static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai, void *stream,58 int direction);59static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,60 struct snd_soc_dai *dai);61 62static const struct snd_soc_dai_ops hdac_hda_dai_ops = {63 .startup = hdac_hda_dai_open,64 .shutdown = hdac_hda_dai_close,65 .prepare = hdac_hda_dai_prepare,66 .hw_params = hdac_hda_dai_hw_params,67 .hw_free = hdac_hda_dai_hw_free,68 .set_stream = hdac_hda_dai_set_stream,69};70 71static struct snd_soc_dai_driver hdac_hda_dais[] = {72{73 .id = HDAC_ANALOG_DAI_ID,74 .name = "Analog Codec DAI",75 .ops = &hdac_hda_dai_ops,76 .playback = {77 .stream_name = "Analog Codec Playback",78 .channels_min = 1,79 .channels_max = 16,80 .rates = SNDRV_PCM_RATE_8000_192000,81 .formats = STUB_FORMATS,82 .sig_bits = 24,83 },84 .capture = {85 .stream_name = "Analog Codec Capture",86 .channels_min = 1,87 .channels_max = 16,88 .rates = SNDRV_PCM_RATE_8000_192000,89 .formats = STUB_FORMATS,90 .sig_bits = 24,91 },92},93{94 .id = HDAC_DIGITAL_DAI_ID,95 .name = "Digital Codec DAI",96 .ops = &hdac_hda_dai_ops,97 .playback = {98 .stream_name = "Digital Codec Playback",99 .channels_min = 1,100 .channels_max = 16,101 .rates = SNDRV_PCM_RATE_8000_192000,102 .formats = STUB_FORMATS,103 .sig_bits = 24,104 },105 .capture = {106 .stream_name = "Digital Codec Capture",107 .channels_min = 1,108 .channels_max = 16,109 .rates = SNDRV_PCM_RATE_8000_192000,110 .formats = STUB_FORMATS,111 .sig_bits = 24,112 },113},114{115 .id = HDAC_ALT_ANALOG_DAI_ID,116 .name = "Alt Analog Codec DAI",117 .ops = &hdac_hda_dai_ops,118 .playback = {119 .stream_name = "Alt Analog Codec Playback",120 .channels_min = 1,121 .channels_max = 16,122 .rates = SNDRV_PCM_RATE_8000_192000,123 .formats = STUB_FORMATS,124 .sig_bits = 24,125 },126 .capture = {127 .stream_name = "Alt Analog Codec Capture",128 .channels_min = 1,129 .channels_max = 16,130 .rates = SNDRV_PCM_RATE_8000_192000,131 .formats = STUB_FORMATS,132 .sig_bits = 24,133 },134},135};136 137static struct snd_soc_dai_driver hdac_hda_hdmi_dais[] = {138{139 .id = HDAC_HDMI_0_DAI_ID,140 .name = "intel-hdmi-hifi1",141 .ops = &hdac_hda_dai_ops,142 .playback = {143 .stream_name = "hifi1",144 .channels_min = 1,145 .channels_max = 32,146 .rates = STUB_HDMI_RATES,147 .formats = STUB_FORMATS,148 .sig_bits = 24,149 },150},151{152 .id = HDAC_HDMI_1_DAI_ID,153 .name = "intel-hdmi-hifi2",154 .ops = &hdac_hda_dai_ops,155 .playback = {156 .stream_name = "hifi2",157 .channels_min = 1,158 .channels_max = 32,159 .rates = STUB_HDMI_RATES,160 .formats = STUB_FORMATS,161 .sig_bits = 24,162 },163},164{165 .id = HDAC_HDMI_2_DAI_ID,166 .name = "intel-hdmi-hifi3",167 .ops = &hdac_hda_dai_ops,168 .playback = {169 .stream_name = "hifi3",170 .channels_min = 1,171 .channels_max = 32,172 .rates = STUB_HDMI_RATES,173 .formats = STUB_FORMATS,174 .sig_bits = 24,175 },176},177{178 .id = HDAC_HDMI_3_DAI_ID,179 .name = "intel-hdmi-hifi4",180 .ops = &hdac_hda_dai_ops,181 .playback = {182 .stream_name = "hifi4",183 .channels_min = 1,184 .channels_max = 32,185 .rates = STUB_HDMI_RATES,186 .formats = STUB_FORMATS,187 .sig_bits = 24,188 },189},190 191};192 193static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai,194 void *stream, int direction)195{196 struct snd_soc_component *component = dai->component;197 struct hdac_hda_priv *hda_pvt;198 struct hdac_hda_pcm *pcm;199 struct hdac_stream *hstream;200 201 if (!stream)202 return -EINVAL;203 204 hda_pvt = snd_soc_component_get_drvdata(component);205 pcm = &hda_pvt->pcm[dai->id];206 hstream = (struct hdac_stream *)stream;207 208 pcm->stream_tag[direction] = hstream->stream_tag;209 210 return 0;211}212 213static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,214 struct snd_pcm_hw_params *params,215 struct snd_soc_dai *dai)216{217 struct snd_soc_component *component = dai->component;218 struct hdac_hda_priv *hda_pvt;219 unsigned int format_val;220 unsigned int maxbps;221 unsigned int bits;222 223 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)224 maxbps = dai->driver->playback.sig_bits;225 else226 maxbps = dai->driver->capture.sig_bits;227 bits = snd_hdac_stream_format_bits(params_format(params), SNDRV_PCM_SUBFORMAT_STD, maxbps);228 229 hda_pvt = snd_soc_component_get_drvdata(component);230 format_val = snd_hdac_stream_format(params_channels(params), bits, params_rate(params));231 if (!format_val) {232 dev_err(dai->dev,233 "%s: invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n",234 __func__,235 params_rate(params), params_channels(params),236 params_format(params), maxbps);237 238 return -EINVAL;239 }240 241 hda_pvt->pcm[dai->id].format_val[substream->stream] = format_val;242 return 0;243}244 245static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream,246 struct snd_soc_dai *dai)247{248 struct snd_soc_component *component = dai->component;249 struct hdac_hda_priv *hda_pvt;250 struct hda_pcm_stream *hda_stream;251 struct hda_pcm *pcm;252 253 hda_pvt = snd_soc_component_get_drvdata(component);254 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);255 if (!pcm)256 return -EINVAL;257 258 hda_stream = &pcm->stream[substream->stream];259 snd_hda_codec_cleanup(hda_pvt->codec, hda_stream, substream);260 261 return 0;262}263 264static int hdac_hda_dai_prepare(struct snd_pcm_substream *substream,265 struct snd_soc_dai *dai)266{267 struct snd_soc_component *component = dai->component;268 struct hda_pcm_stream *hda_stream;269 struct hdac_hda_priv *hda_pvt;270 unsigned int format_val;271 struct hda_pcm *pcm;272 unsigned int stream;273 int ret = 0;274 275 hda_pvt = snd_soc_component_get_drvdata(component);276 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);277 if (!pcm)278 return -EINVAL;279 280 hda_stream = &pcm->stream[substream->stream];281 282 stream = hda_pvt->pcm[dai->id].stream_tag[substream->stream];283 format_val = hda_pvt->pcm[dai->id].format_val[substream->stream];284 285 ret = snd_hda_codec_prepare(hda_pvt->codec, hda_stream,286 stream, format_val, substream);287 if (ret < 0)288 dev_err(dai->dev, "%s: failed %d\n", __func__, ret);289 290 return ret;291}292 293static int hdac_hda_dai_open(struct snd_pcm_substream *substream,294 struct snd_soc_dai *dai)295{296 struct snd_soc_component *component = dai->component;297 struct hdac_hda_priv *hda_pvt;298 struct hda_pcm_stream *hda_stream;299 struct hda_pcm *pcm;300 int ret;301 302 hda_pvt = snd_soc_component_get_drvdata(component);303 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);304 if (!pcm)305 return -EINVAL;306 307 snd_hda_codec_pcm_get(pcm);308 309 hda_stream = &pcm->stream[substream->stream];310 311 ret = hda_stream->ops.open(hda_stream, hda_pvt->codec, substream);312 if (ret < 0)313 dev_err(dai->dev, "%s: failed %d\n", __func__, ret);314 315 return ret;316}317 318static void hdac_hda_dai_close(struct snd_pcm_substream *substream,319 struct snd_soc_dai *dai)320{321 struct snd_soc_component *component = dai->component;322 struct hdac_hda_priv *hda_pvt;323 struct hda_pcm_stream *hda_stream;324 struct hda_pcm *pcm;325 326 hda_pvt = snd_soc_component_get_drvdata(component);327 pcm = snd_soc_find_pcm_from_dai(hda_pvt, dai);328 if (!pcm)329 return;330 331 hda_stream = &pcm->stream[substream->stream];332 333 hda_stream->ops.close(hda_stream, hda_pvt->codec, substream);334 335 snd_hda_codec_pcm_put(pcm);336}337 338static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,339 struct snd_soc_dai *dai)340{341 struct hda_codec *hcodec = hda_pvt->codec;342 struct hda_pcm *cpcm;343 const char *pcm_name;344 345 /*346 * map DAI ID to the closest matching PCM name, using the naming347 * scheme used by hda-codec snd_hda_gen_build_pcms() and for348 * HDMI in hda_codec patch_hdmi.c)349 */350 351 switch (dai->id) {352 case HDAC_ANALOG_DAI_ID:353 pcm_name = "Analog";354 break;355 case HDAC_DIGITAL_DAI_ID:356 pcm_name = "Digital";357 break;358 case HDAC_ALT_ANALOG_DAI_ID:359 pcm_name = "Alt Analog";360 break;361 case HDAC_HDMI_0_DAI_ID:362 pcm_name = "HDMI 0";363 break;364 case HDAC_HDMI_1_DAI_ID:365 pcm_name = "HDMI 1";366 break;367 case HDAC_HDMI_2_DAI_ID:368 pcm_name = "HDMI 2";369 break;370 case HDAC_HDMI_3_DAI_ID:371 pcm_name = "HDMI 3";372 break;373 default:374 dev_err(dai->dev, "%s: invalid dai id %d\n", __func__, dai->id);375 return NULL;376 }377 378 list_for_each_entry(cpcm, &hcodec->pcm_list_head, list) {379 if (strstr(cpcm->name, pcm_name)) {380 if (strcmp(pcm_name, "Analog") == 0) {381 if (strstr(cpcm->name, "Alt Analog"))382 continue;383 }384 return cpcm;385 }386 }387 388 dev_err(dai->dev, "%s: didn't find PCM for DAI %s\n", __func__, dai->name);389 return NULL;390}391 392static bool is_hdmi_codec(struct hda_codec *hcodec)393{394 struct hda_pcm *cpcm;395 396 list_for_each_entry(cpcm, &hcodec->pcm_list_head, list) {397 if (cpcm->pcm_type == HDA_PCM_TYPE_HDMI)398 return true;399 }400 401 return false;402}403 404static int hdac_hda_codec_probe(struct snd_soc_component *component)405{406 struct hdac_hda_priv *hda_pvt =407 snd_soc_component_get_drvdata(component);408 struct snd_soc_dapm_context *dapm =409 snd_soc_component_get_dapm(component);410 struct hdac_device *hdev = &hda_pvt->codec->core;411 struct hda_codec *hcodec = hda_pvt->codec;412 struct hdac_ext_link *hlink;413 hda_codec_patch_t patch;414 int ret;415 416 hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));417 if (!hlink) {418 dev_err(&hdev->dev, "%s: hdac link not found\n", __func__);419 return -EIO;420 }421 422 snd_hdac_ext_bus_link_get(hdev->bus, hlink);423 424 /*425 * Ensure any HDA display is powered at codec probe.426 * After snd_hda_codec_device_new(), display power is427 * managed by runtime PM.428 */429 if (hda_pvt->need_display_power)430 snd_hdac_display_power(hdev->bus,431 HDA_CODEC_IDX_CONTROLLER, true);432 433 ret = snd_hda_codec_device_new(hcodec->bus, component->card->snd_card,434 hdev->addr, hcodec, true);435 if (ret < 0) {436 dev_err(&hdev->dev, "%s: failed to create hda codec %d\n", __func__, ret);437 goto error_no_pm;438 }439 440#ifdef CONFIG_SND_HDA_PATCH_LOADER441 if (loadable_patch[hda_pvt->dev_index] && *loadable_patch[hda_pvt->dev_index]) {442 const struct firmware *fw;443 444 dev_info(&hdev->dev, "Applying patch firmware '%s'\n",445 loadable_patch[hda_pvt->dev_index]);446 ret = request_firmware(&fw, loadable_patch[hda_pvt->dev_index],447 &hdev->dev);448 if (ret < 0)449 goto error_no_pm;450 if (fw) {451 ret = snd_hda_load_patch(hcodec->bus, fw->size, fw->data);452 if (ret < 0) {453 dev_err(&hdev->dev, "%s: failed to load hda patch %d\n", __func__, ret);454 goto error_no_pm;455 }456 release_firmware(fw);457 }458 }459#endif460 /*461 * Overwrite type to HDA_DEV_ASOC since it is a ASoC driver462 * hda_codec.c will check this flag to determine if unregister463 * device is needed.464 */465 hdev->type = HDA_DEV_ASOC;466 467 /*468 * snd_hda_codec_device_new decrements the usage count so call get pm469 * else the device will be powered off470 */471 pm_runtime_get_noresume(&hdev->dev);472 473 hcodec->bus->card = dapm->card->snd_card;474 475 ret = snd_hda_codec_set_name(hcodec, hcodec->preset->name);476 if (ret < 0) {477 dev_err(&hdev->dev, "%s: name failed %s\n", __func__, hcodec->preset->name);478 goto error_pm;479 }480 481 ret = snd_hdac_regmap_init(&hcodec->core);482 if (ret < 0) {483 dev_err(&hdev->dev, "%s: regmap init failed\n", __func__);484 goto error_pm;485 }486 487 patch = (hda_codec_patch_t)hcodec->preset->driver_data;488 if (patch) {489 ret = patch(hcodec);490 if (ret < 0) {491 dev_err(&hdev->dev, "%s: patch failed %d\n", __func__, ret);492 goto error_regmap;493 }494 } else {495 dev_dbg(&hdev->dev, "%s: no patch file found\n", __func__);496 }497 498 ret = snd_hda_codec_parse_pcms(hcodec);499 if (ret < 0) {500 dev_err(&hdev->dev, "%s: unable to map pcms to dai %d\n", __func__, ret);501 goto error_patch;502 }503 504 /* HDMI controls need to be created in machine drivers */505 if (!is_hdmi_codec(hcodec)) {506 ret = snd_hda_codec_build_controls(hcodec);507 if (ret < 0) {508 dev_err(&hdev->dev, "%s: unable to create controls %d\n",509 __func__, ret);510 goto error_patch;511 }512 }513 514 hcodec->core.lazy_cache = true;515 516 if (hda_pvt->need_display_power)517 snd_hdac_display_power(hdev->bus,518 HDA_CODEC_IDX_CONTROLLER, false);519 520 /* match for forbid call in snd_hda_codec_device_new() */521 pm_runtime_allow(&hdev->dev);522 523 /*524 * hdac_device core already sets the state to active and calls525 * get_noresume. So enable runtime and set the device to suspend.526 * pm_runtime_enable is also called during codec registeration527 */528 pm_runtime_put(&hdev->dev);529 pm_runtime_suspend(&hdev->dev);530 531 return 0;532 533error_patch:534 if (hcodec->patch_ops.free)535 hcodec->patch_ops.free(hcodec);536error_regmap:537 snd_hdac_regmap_exit(hdev);538error_pm:539 pm_runtime_put(&hdev->dev);540error_no_pm:541 snd_hdac_ext_bus_link_put(hdev->bus, hlink);542 return ret;543}544 545static void hdac_hda_codec_remove(struct snd_soc_component *component)546{547 struct hdac_hda_priv *hda_pvt =548 snd_soc_component_get_drvdata(component);549 struct hdac_device *hdev = &hda_pvt->codec->core;550 struct hda_codec *codec = hda_pvt->codec;551 struct hdac_ext_link *hlink = NULL;552 553 hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));554 if (!hlink) {555 dev_err(&hdev->dev, "%s: hdac link not found\n", __func__);556 return;557 }558 559 pm_runtime_disable(&hdev->dev);560 snd_hdac_ext_bus_link_put(hdev->bus, hlink);561 562 if (codec->patch_ops.free)563 codec->patch_ops.free(codec);564 565 snd_hda_codec_cleanup_for_unbind(codec);566}567 568static const struct snd_soc_dapm_route hdac_hda_dapm_routes[] = {569 {"AIF1TX", NULL, "Codec Input Pin1"},570 {"AIF2TX", NULL, "Codec Input Pin2"},571 {"AIF3TX", NULL, "Codec Input Pin3"},572 573 {"Codec Output Pin1", NULL, "AIF1RX"},574 {"Codec Output Pin2", NULL, "AIF2RX"},575 {"Codec Output Pin3", NULL, "AIF3RX"},576};577 578static const struct snd_soc_dapm_widget hdac_hda_dapm_widgets[] = {579 /* Audio Interface */580 SND_SOC_DAPM_AIF_IN("AIF1RX", "Analog Codec Playback", 0,581 SND_SOC_NOPM, 0, 0),582 SND_SOC_DAPM_AIF_IN("AIF2RX", "Digital Codec Playback", 0,583 SND_SOC_NOPM, 0, 0),584 SND_SOC_DAPM_AIF_IN("AIF3RX", "Alt Analog Codec Playback", 0,585 SND_SOC_NOPM, 0, 0),586 SND_SOC_DAPM_AIF_OUT("AIF1TX", "Analog Codec Capture", 0,587 SND_SOC_NOPM, 0, 0),588 SND_SOC_DAPM_AIF_OUT("AIF2TX", "Digital Codec Capture", 0,589 SND_SOC_NOPM, 0, 0),590 SND_SOC_DAPM_AIF_OUT("AIF3TX", "Alt Analog Codec Capture", 0,591 SND_SOC_NOPM, 0, 0),592 593 /* Input Pins */594 SND_SOC_DAPM_INPUT("Codec Input Pin1"),595 SND_SOC_DAPM_INPUT("Codec Input Pin2"),596 SND_SOC_DAPM_INPUT("Codec Input Pin3"),597 598 /* Output Pins */599 SND_SOC_DAPM_OUTPUT("Codec Output Pin1"),600 SND_SOC_DAPM_OUTPUT("Codec Output Pin2"),601 SND_SOC_DAPM_OUTPUT("Codec Output Pin3"),602};603 604static const struct snd_soc_component_driver hdac_hda_codec = {605 .probe = hdac_hda_codec_probe,606 .remove = hdac_hda_codec_remove,607 .dapm_widgets = hdac_hda_dapm_widgets,608 .num_dapm_widgets = ARRAY_SIZE(hdac_hda_dapm_widgets),609 .dapm_routes = hdac_hda_dapm_routes,610 .num_dapm_routes = ARRAY_SIZE(hdac_hda_dapm_routes),611 .idle_bias_on = false,612 .endianness = 1,613};614 615static const struct snd_soc_component_driver hdac_hda_hdmi_codec = {616 .probe = hdac_hda_codec_probe,617 .remove = hdac_hda_codec_remove,618 .idle_bias_on = false,619 .endianness = 1,620};621 622static int hdac_hda_dev_probe(struct hdac_device *hdev)623{624 struct hdac_hda_priv *hda_pvt = dev_get_drvdata(&hdev->dev);625 struct hdac_ext_link *hlink;626 int ret;627 628 /* hold the ref while we probe */629 hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));630 if (!hlink) {631 dev_err(&hdev->dev, "%s: hdac link not found\n", __func__);632 return -EIO;633 }634 snd_hdac_ext_bus_link_get(hdev->bus, hlink);635 636 /* ASoC specific initialization */637 if (hda_pvt->need_display_power)638 ret = devm_snd_soc_register_component(&hdev->dev,639 &hdac_hda_hdmi_codec, hdac_hda_hdmi_dais,640 ARRAY_SIZE(hdac_hda_hdmi_dais));641 else642 ret = devm_snd_soc_register_component(&hdev->dev,643 &hdac_hda_codec, hdac_hda_dais,644 ARRAY_SIZE(hdac_hda_dais));645 646 if (ret < 0) {647 dev_err(&hdev->dev, "%s: failed to register HDA codec %d\n", __func__, ret);648 return ret;649 }650 651 snd_hdac_ext_bus_link_put(hdev->bus, hlink);652 653 return ret;654}655 656static int hdac_hda_dev_remove(struct hdac_device *hdev)657{658 /*659 * Resources are freed in hdac_hda_codec_remove(). This660 * function is kept to keep hda_codec_driver_remove() happy.661 */662 return 0;663}664 665static struct hdac_ext_bus_ops hdac_ops = {666 .hdev_attach = hdac_hda_dev_probe,667 .hdev_detach = hdac_hda_dev_remove,668};669 670struct hdac_ext_bus_ops *snd_soc_hdac_hda_get_ops(void)671{672 return &hdac_ops;673}674EXPORT_SYMBOL_GPL(snd_soc_hdac_hda_get_ops);675 676MODULE_LICENSE("GPL v2");677MODULE_DESCRIPTION("ASoC Extensions for legacy HDA Drivers");678MODULE_AUTHOR("Rakesh Ughreja<rakesh.a.ughreja@intel.com>");679