From patchwork Sat Nov 6 10:52:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Trimarchi X-Patchwork-Id: 1728 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 26F003F054 for ; Sat, 6 Nov 2021 11:52:50 +0100 (CET) Received: by mail-ed1-f69.google.com with SMTP id i22-20020a05640242d600b003e28aecc0afsf11071744edc.1 for ; Sat, 06 Nov 2021 03:52:50 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1636195969; cv=pass; d=google.com; s=arc-20160816; b=1AVK5nnw60hFd78/xwxpN+NTnpn7kAPg8txTQWKQHwdHmUm/jX3V0HYBrYJgUA/PRH K6R893IRMyjANeM7yDAcmnP80ZuNrTGDLCcc9Wkk2P+h5z3TgVsw9VlIGfqW5cOCauTK 6TwKPjjKWG8IWYwQJIHSHQi7O8x4hPxeo2XfeB3q2LKWYc780Q6u9Dq4mGOwJWo4WO2u xDmzzm2/+y1TrzyKweiC2vAC0F/oD8jw9cTAp40+3AGe2mdsYg7OA4tFHVfN35ahz/f7 vDIBcDqdLJ5CD1QIDbw3g0MoMkMN5Gql2tEBJaw0Vlt6Z9Gnfz7wltGb1UTcZYAm6s42 qDWQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:message-id:date:subject:cc:to :from:dkim-signature; bh=0d/LaEIBW+mT0Xo5xTMOoe0SV0oCofWKKEQvg3Mjuyg=; b=Clq9S7pLoMGPhx2mH+3kHvbPAck27g0J0hguf9xGm6NVbgdHret2ckt8iCn0JNDRvS Ew9iSCAeCJeL50Oru1Cd3PWJ5+tpcqyfuhQ83V4hlobFyBFnwNb/PDCAT/HQ9LuK3ZUR i8QbivqwVPciuiK3Zg95W6Y0CVsUuTk3BiSddmbHYzDNxvgx5PqtYFLTYItFOm9+YC3t IPiNsBu2WwnqmhOUBMh1lQ0QFoYG7zjuYH13wyI0v7ecIbbvZkmdty4hpH5Uw1y7CoBj LHL9RY05+B9GZeaepw9Le9k0CHHNhgrhk+0uFt+W6yp80TVDcjY5pwdzYueMSwa4sQEv EVYQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="pw/hBWOl"; spf=pass (google.com: domain of michael@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=michael@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=0d/LaEIBW+mT0Xo5xTMOoe0SV0oCofWKKEQvg3Mjuyg=; b=NhzLAcinhHhm032uTcSC58EbSnXntazGea51tcqHsP5u6FOqJHP/WpPcrmZsfDqmJn MfJL7rzP0fkIZSxbO3fC4imWjD17prXvQn5P896YNbSq7LhMqWIx97F4lTChuzjW+ViV kSm7vKcGGCdB1jOSHYu7f1XomO6IqKed1cRuM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help :list-archive:list-unsubscribe; bh=0d/LaEIBW+mT0Xo5xTMOoe0SV0oCofWKKEQvg3Mjuyg=; b=K+VNlS45sWOiIWF+eP2UJCmZBmHoahQJu+ooo2qkmAoqWxwRDkIT09P/hYHDWKGq+U Una2QeAOf0HXjLqppSyNks+FG73iJUw0NK00XSyDVZUFwVyeBbsGn/7L/HPSUqYz8IYe 7+fyceo0STt3gXXJ4C2Dq3VoN3n6LOZKMYfm6EyvDxYg3RlppnVYCo/7xMYIcmN1PHsm MkXTo7cFjpcNTBOfE4tCo6LsFqvlfRn7pBpRPLqWNuXVw7CgVsr9H3CnMsIiCbsjT9lU XmJ3Ncnxjga/RiM4EgBY6HwGdzOaRDMmfZFC61GTB080jXMS2I5CyvfAjHxGovFVTa0T E5oQ== X-Gm-Message-State: AOAM532eQR3Lx9R7Uyv+upWN0i9TDcF/ypndZU6ZN0B1DuP2Ldy8UWjw 1jyZ8tSlgqsyGAHe8SVEhvSvbkew X-Google-Smtp-Source: ABdhPJwogQ3m4kfp3inec53DLBBiYLYQK4d0hlrxSEiH/c6wqouTVIFPVG+n4LwC8mZlgxMGMEPfeQ== X-Received: by 2002:a17:907:1b16:: with SMTP id mp22mr80661463ejc.503.1636195969766; Sat, 06 Nov 2021 03:52:49 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:907:960d:: with SMTP id gb13ls5355795ejc.11.gmail; Sat, 06 Nov 2021 03:52:48 -0700 (PDT) X-Received: by 2002:a17:907:3c16:: with SMTP id gh22mr26639857ejc.344.1636195968569; Sat, 06 Nov 2021 03:52:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1636195968; cv=none; d=google.com; s=arc-20160816; b=Ef/gVfIRds9OjNnA/52FDRyA+pfFCfCRk5GPTqwG85k1tT16M4tGDDEmtfPVpDMOhd IoLXIfgUMcBUpr981upGrd1DqgIgoSNPN736Ljl8BHXptNJUVQZ24yVDCnpqd0VjDpB/ WktsWD8Pt1lOsXzcJx1K7daD4qRJXs5jqhW6BRIXXBUcvl6h+KC0vHq8ckVcOTWyXZkA U/i7Ws8VFWO8vi92pZXxDAdHyAH6+Gt5qfAEiYAugcz6rVjvKdtXIOmolOENS27z+35M jHXcVVrA9bK7y4Nod+qz6JghKXYBvSJ8UNHRkMNhFNbE2aCArvrs9p7Nxs7MHfp5G/tx UmyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=Y10zRYT9D/kBkdwz8lSXXK6hwV07Dd2LWUsRRIct1Wk=; b=JkzafBH2d5B5Vu8G6aJO8HvKDUOKQ5JF/fxvNkLR3HUtJEL7b6H8bSUuFT5z2ObkRA Llwan2tVWvKt0pOODTkEKIHNMWysIDTLSZz9eu2L2mQy6svy6hPlNmt8BlH1NCCHPnG0 BVCtICNM6M3+3NU7e1+7f4p4f0YVcMqc19eohB+DJ3tS9KDlh8Hn6Sl3KOxRzmDcCJu+ qZ7gpH1tusO+KRwC/2u0pxFhU+WD0hwbS+8Dj+y1c/sGAEUvQ9Jqu95cSnEqezKOqHa9 iSWKeAXw3MmSB9z+bYPPhrzDkEorYMmiXfVzXMDqTtaoW8T3FT0BYoi8DvhBWni8UZ5q vdgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="pw/hBWOl"; spf=pass (google.com: domain of michael@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=michael@amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id o1sor6934325ejy.45.2021.11.06.03.52.48 for (Google Transport Security); Sat, 06 Nov 2021 03:52:48 -0700 (PDT) Received-SPF: pass (google.com: domain of michael@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a17:906:5006:: with SMTP id s6mr14939253ejj.258.1636195967950; Sat, 06 Nov 2021 03:52:47 -0700 (PDT) Received: from localhost.localdomain ([2.198.175.50]) by smtp.gmail.com with ESMTPSA id x22sm884183ejc.97.2021.11.06.03.52.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Nov 2021 03:52:47 -0700 (PDT) From: Michael Trimarchi To: Ariel D'Alessandro Cc: linux-amarula@amarulasolutions.com, Anthony Brandon Subject: [PATCH] ASoC: fsl: add smm-s2-pro audio driver Date: Sat, 6 Nov 2021 11:52:44 +0100 Message-Id: <20211106105244.998605-1-michael@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Original-Sender: michael@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b="pw/hBWOl"; spf=pass (google.com: domain of michael@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=michael@amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The smm-tlv320aic31xx driver implement audio support of smm-s2-pro BSH system master. Signed-off-by: Michael Trimarchi --- sound/soc/fsl/Kconfig | 11 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/smm-tlv320aic31xx.c | 316 ++++++++++++++++++++++++++++++ 3 files changed, 329 insertions(+) create mode 100644 sound/soc/fsl/smm-tlv320aic31xx.c diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 8e05d092790e..74430bc1e640 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -364,6 +364,17 @@ config SND_SOC_IMX_CARD with OF-graph DT bindings. It also support DPCM of single CPU multi Codec ststem. +config SND_SOC_SMM2_CARD + tristate "SoC Audio Card for SMM2 pro BSH device" + depends on OF && I2C + select SND_SOC_FSL_EASRC + select SND_SOC_TLV320AIC31XX + select SND_SOC_IMX_PCM_DMA + select SND_SOC_FSL_SAI + select SND_SIMPLE_CARD_UTILS + help + This option enables audio sound card support for BSH SMM2 Pro + endif # SND_IMX_SOC endmenu diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index b54beb1a66fa..e85d7f6be709 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -72,6 +72,7 @@ snd-soc-imx-audmix-objs := imx-audmix.o snd-soc-imx-hdmi-objs := imx-hdmi.o snd-soc-imx-rpmsg-objs := imx-rpmsg.o snd-soc-imx-card-objs := imx-card.o +snd-soc-smm-tlv320aic31xx-objs := smm-tlv320aic31xx.o obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o @@ -81,3 +82,4 @@ obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o obj-$(CONFIG_SND_SOC_IMX_RPMSG) += snd-soc-imx-rpmsg.o obj-$(CONFIG_SND_SOC_IMX_CARD) += snd-soc-imx-card.o +obj-$(CONFIG_SND_SOC_SMM2_CARD) += snd-soc-smm-tlv320aic31xx.o diff --git a/sound/soc/fsl/smm-tlv320aic31xx.c b/sound/soc/fsl/smm-tlv320aic31xx.c new file mode 100644 index 000000000000..364b31e33a6c --- /dev/null +++ b/sound/soc/fsl/smm-tlv320aic31xx.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// BSH smm2-pro audio card +// +// Copyright (C) 2021 BSH Hausgeraete GmbH +// +// Author: Michael Trimarchi + +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_sai.h" +#include "../codecs/tlv320aic31xx.h" + +/** + * struct smm_card_priv - Freescale Generic ASOC card private data + * @dai_link: DAI link structure including normal one and DPCM link + * @pdev: platform device pointer + * @card: ASoC card structure + * @sample_rate: Current sample rate + * @sample_format: Current sample format + * @asrc_rate: ASRC sample rate used by Back-Ends + * @asrc_format: ASRC sample format used by Back-Ends + * @dai_fmt: DAI format between CPU and CODEC + * @name: Card name + */ + +struct smm_card_priv { + struct snd_soc_dai_link dai_link[2]; + struct platform_device *pdev; + struct snd_soc_card card; + u32 sample_rate; + snd_pcm_format_t sample_format; + u32 asrc_rate; + snd_pcm_format_t asrc_format; + u32 dai_fmt; + char name[32]; +}; + +static const struct snd_soc_dapm_route audio_map[] = { + /* 1st half -- Normal DAPM routes */ + {"Playback", NULL, "CPU-Playback"}, + /* 2nd half -- ASRC DAPM routes */ + {"CPU-Playback", NULL, "ASRC-Playback"}, +}; + +/* Add all possible widgets into here without being redundant */ +static const struct snd_soc_dapm_widget smm_card_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct smm_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct device *dev = rtd->card->dev; + int ret; + + priv->sample_rate = params_rate(params); + priv->sample_format = params_format(params); + + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 32); + if (ret && ret != -ENOTSUPP) { + dev_err(dev, "failed to set TDM slot for cpu dai\n"); + goto fail; + } + + ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), AIC31XX_PLL_CLKIN_BCKL, + priv->sample_rate * 256, SND_SOC_CLOCK_IN); + if (ret && ret != -ENOTSUPP) { + dev_err(dev, "failed to set SYSCLK: %d\n", ret); + goto fail; + } + + return 0; + +fail: + return ret; +} + +static const struct snd_soc_ops fsl_asoc_card_ops = { + .hw_params = fsl_asoc_card_hw_params, +}; + +static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct smm_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct snd_interval *rate; + struct snd_mask *mask; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + rate->max = rate->min = priv->asrc_rate; + + mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + snd_mask_none(mask); + snd_mask_set_format(mask, priv->asrc_format); + + return 0; +} + +SND_SOC_DAILINK_DEFS(hifi, + DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(hifi_fe, + DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(hifi_be, + DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_DUMMY())); + +static struct snd_soc_dai_link fsl_asoc_card_dai[] = { + /* DPCM Link between Front-End and Back-End */ + { + .name = "HiFi-ASRC-FE", + .stream_name = "HiFi-ASRC-FE", + .dpcm_playback = 1, + .dpcm_capture = 0, + .dynamic = 1, + SND_SOC_DAILINK_REG(hifi_fe), + }, + { + .name = "HiFi-ASRC-BE", + .stream_name = "HiFi-ASRC-BE", + .be_hw_params_fixup = be_hw_params_fixup, + .ops = &fsl_asoc_card_ops, + .dpcm_playback = 1, + .dpcm_capture = 0, + .no_pcm = 1, + SND_SOC_DAILINK_REG(hifi_be), + }, +}; + +static int smm_card_probe(struct platform_device *pdev) +{ + struct device_node *cpu_np, *codec_np, *asrc_np; + struct device_node *np = pdev->dev.of_node; + struct platform_device *asrc_pdev = NULL; + struct device_node *bitclkprovider = NULL; + struct device_node *frameprovider = NULL; + struct platform_device *cpu_pdev; + struct smm_card_priv *priv; + struct device *codec_dev = NULL; + const char *codec_dai_name; + const char *codec_dev_name; + u32 width; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + cpu_np = of_parse_phandle(np, "audio-cpu", 0); + if (!cpu_np) { + dev_err(&pdev->dev, "CPU phandle missing or invalid\n"); + ret = -EINVAL; + goto fail; + } + + cpu_pdev = of_find_device_by_node(cpu_np); + if (!cpu_pdev) { + dev_err(&pdev->dev, "failed to find CPU DAI device\n"); + ret = -EINVAL; + goto fail; + } + + codec_np = of_parse_phandle(np, "audio-codec", 0); + if (codec_np) { + struct platform_device *codec_pdev; + struct i2c_client *codec_i2c; + + codec_i2c = of_find_i2c_device_by_node(codec_np); + if (codec_i2c) { + codec_dev = &codec_i2c->dev; + codec_dev_name = codec_i2c->name; + } + if (!codec_dev) { + codec_pdev = of_find_device_by_node(codec_np); + if (codec_pdev) { + codec_dev = &codec_pdev->dev; + codec_dev_name = codec_pdev->name; + } + } + } + + asrc_np = of_parse_phandle(np, "audio-asrc", 0); + if (asrc_np) + asrc_pdev = of_find_device_by_node(asrc_np); + + if (!asrc_pdev) { + dev_err(&pdev->dev, "Unable to register the ASRC DAI device\n"); + ret = -EINVAL; + goto fail; + } + + /* Default sample rate and format, will be updated in hw_params() */ + priv->sample_rate = 48000; + priv->sample_format = SNDRV_PCM_FORMAT_S32_LE; + priv->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; + + memcpy(priv->dai_link, fsl_asoc_card_dai, + sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link)); + + codec_dai_name = "tlv320dac31xx-hifi"; + priv->card.dapm_routes = audio_map; + priv->card.num_dapm_routes = ARRAY_SIZE(audio_map); + + /* Initialize sound card */ + priv->pdev = pdev; + priv->card.dev = &pdev->dev; + priv->card.owner = THIS_MODULE; + ret = snd_soc_of_parse_card_name(&priv->card, "model"); + if (ret) { + snprintf(priv->name, sizeof(priv->name), "%s-audio", codec_dev_name); + priv->card.name = priv->name; + } + priv->card.dai_link = priv->dai_link; + priv->card.dapm_widgets = smm_card_dapm_widgets; + priv->card.num_dapm_widgets = ARRAY_SIZE(smm_card_dapm_widgets); + + if (of_property_read_bool(np, "audio-routing")) { + ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing"); + if (ret) { + dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret); + goto asrc_fail; + } + } + + /* DPCM DAI Links */ + priv->dai_link[0].cpus->of_node = asrc_np; + priv->dai_link[0].platforms->of_node = asrc_np; + priv->dai_link[1].codecs->dai_name = codec_dai_name; + priv->dai_link[1].codecs->of_node = codec_np; + priv->dai_link[1].codecs->name = priv->dai_link[0].codecs->name; + priv->dai_link[1].cpus->of_node = cpu_np; + priv->dai_link[1].dai_fmt = priv->dai_fmt; + priv->card.num_links = 2; + + ret = of_property_read_u32(asrc_np, "fsl,asrc-rate", + &priv->asrc_rate); + if (ret) { + dev_err(&pdev->dev, "failed to get output rate\n"); + ret = -EINVAL; + goto asrc_fail; + } + + ret = of_property_read_u32(asrc_np, "fsl,asrc-format", + &priv->asrc_format); + if (ret) { + /* Fallback to old binding; translate to asrc_format */ + ret = of_property_read_u32(asrc_np, "fsl,asrc-width", + &width); + if (ret) { + dev_err(&pdev->dev, + "failed to decide output format\n"); + goto asrc_fail; + } + + if (width == 24) + priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; + else + priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; + } + + /* Finish card registering */ + platform_set_drvdata(pdev, priv); + snd_soc_card_set_drvdata(&priv->card, priv); + + ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); + if (ret) { + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + goto asrc_fail; + } + +asrc_fail: + of_node_put(asrc_np); + of_node_put(codec_np); + put_device(&cpu_pdev->dev); +fail: + of_node_put(cpu_np); + + return ret; +} + +static const struct of_device_id smm_card_dt_ids[] = { + { .compatible = "bsh,imx-audio-tlv320aic31xx", }, + {} +}; +MODULE_DEVICE_TABLE(of, smm_card_dt_ids); + +static struct platform_driver smm_bsh_card_driver = { + .probe = smm_card_probe, + .driver = { + .name = "smm-tlv320aic31xx", + .pm = &snd_soc_pm_ops, + .of_match_table = smm_card_dt_ids, + }, +}; +module_platform_driver(smm_bsh_card_driver); + +MODULE_DESCRIPTION("BSH smm2-pro audio card"); +MODULE_AUTHOR("Michael Trimarchi "); +MODULE_ALIAS("platform:smm-tlv320aic31xx"); +MODULE_LICENSE("GPL");