1 // SPDX-License-Identifier: GPL-2.0-only
3 * trimslice.c - TrimSlice machine ASoC driver
5 * Copyright (C) 2011 - CompuLab, Ltd.
6 * Author: Mike Rapoport <mike@compulab.co.il>
8 * Based on code copyright/by:
9 * Author: Stephen Warren <swarren@nvidia.com>
10 * Copyright (C) 2010-2011 - NVIDIA, Inc.
13 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
18 #include <sound/core.h>
19 #include <sound/jack.h>
20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h>
22 #include <sound/soc.h>
24 #include "../codecs/tlv320aic23.h"
26 #include "tegra_asoc_utils.h"
28 #define DRV_NAME "tegra-snd-trimslice"
30 struct tegra_trimslice
{
31 struct tegra_asoc_utils_data util_data
;
34 static int trimslice_asoc_hw_params(struct snd_pcm_substream
*substream
,
35 struct snd_pcm_hw_params
*params
)
37 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
38 struct snd_soc_dai
*codec_dai
= asoc_rtd_to_codec(rtd
, 0);
39 struct snd_soc_card
*card
= rtd
->card
;
40 struct tegra_trimslice
*trimslice
= snd_soc_card_get_drvdata(card
);
44 srate
= params_rate(params
);
47 err
= tegra_asoc_utils_set_rate(&trimslice
->util_data
, srate
, mclk
);
49 dev_err(card
->dev
, "Can't configure clocks\n");
53 err
= snd_soc_dai_set_sysclk(codec_dai
, 0, mclk
,
56 dev_err(card
->dev
, "codec_dai clock not set\n");
63 static const struct snd_soc_ops trimslice_asoc_ops
= {
64 .hw_params
= trimslice_asoc_hw_params
,
67 static const struct snd_soc_dapm_widget trimslice_dapm_widgets
[] = {
68 SND_SOC_DAPM_HP("Line Out", NULL
),
69 SND_SOC_DAPM_LINE("Line In", NULL
),
72 static const struct snd_soc_dapm_route trimslice_audio_map
[] = {
73 {"Line Out", NULL
, "LOUT"},
74 {"Line Out", NULL
, "ROUT"},
76 {"LLINEIN", NULL
, "Line In"},
77 {"RLINEIN", NULL
, "Line In"},
80 SND_SOC_DAILINK_DEFS(single_dsp
,
81 DAILINK_COMP_ARRAY(COMP_EMPTY()),
82 DAILINK_COMP_ARRAY(COMP_CODEC(NULL
, "tlv320aic23-hifi")),
83 DAILINK_COMP_ARRAY(COMP_EMPTY()));
85 static struct snd_soc_dai_link trimslice_tlv320aic23_dai
= {
86 .name
= "TLV320AIC23",
87 .stream_name
= "AIC23",
88 .ops
= &trimslice_asoc_ops
,
89 .dai_fmt
= SND_SOC_DAIFMT_I2S
|
90 SND_SOC_DAIFMT_NB_NF
|
91 SND_SOC_DAIFMT_CBS_CFS
,
92 SND_SOC_DAILINK_REG(single_dsp
),
95 static struct snd_soc_card snd_soc_trimslice
= {
96 .name
= "tegra-trimslice",
98 .dai_link
= &trimslice_tlv320aic23_dai
,
101 .dapm_widgets
= trimslice_dapm_widgets
,
102 .num_dapm_widgets
= ARRAY_SIZE(trimslice_dapm_widgets
),
103 .dapm_routes
= trimslice_audio_map
,
104 .num_dapm_routes
= ARRAY_SIZE(trimslice_audio_map
),
105 .fully_routed
= true,
108 static int tegra_snd_trimslice_probe(struct platform_device
*pdev
)
110 struct device_node
*np
= pdev
->dev
.of_node
;
111 struct snd_soc_card
*card
= &snd_soc_trimslice
;
112 struct tegra_trimslice
*trimslice
;
115 trimslice
= devm_kzalloc(&pdev
->dev
, sizeof(struct tegra_trimslice
),
120 card
->dev
= &pdev
->dev
;
121 snd_soc_card_set_drvdata(card
, trimslice
);
123 trimslice_tlv320aic23_dai
.codecs
->of_node
= of_parse_phandle(np
,
124 "nvidia,audio-codec", 0);
125 if (!trimslice_tlv320aic23_dai
.codecs
->of_node
) {
127 "Property 'nvidia,audio-codec' missing or invalid\n");
131 trimslice_tlv320aic23_dai
.cpus
->of_node
= of_parse_phandle(np
,
132 "nvidia,i2s-controller", 0);
133 if (!trimslice_tlv320aic23_dai
.cpus
->of_node
) {
135 "Property 'nvidia,i2s-controller' missing or invalid\n");
139 trimslice_tlv320aic23_dai
.platforms
->of_node
=
140 trimslice_tlv320aic23_dai
.cpus
->of_node
;
142 ret
= tegra_asoc_utils_init(&trimslice
->util_data
, &pdev
->dev
);
146 ret
= devm_snd_soc_register_card(&pdev
->dev
, card
);
148 return dev_err_probe(&pdev
->dev
, ret
,
149 "snd_soc_register_card failed\n");
154 static const struct of_device_id trimslice_of_match
[] = {
155 { .compatible
= "nvidia,tegra-audio-trimslice", },
158 MODULE_DEVICE_TABLE(of
, trimslice_of_match
);
160 static struct platform_driver tegra_snd_trimslice_driver
= {
163 .of_match_table
= trimslice_of_match
,
165 .probe
= tegra_snd_trimslice_probe
,
167 module_platform_driver(tegra_snd_trimslice_driver
);
169 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
170 MODULE_DESCRIPTION("Trimslice machine ASoC driver");
171 MODULE_LICENSE("GPL");
172 MODULE_ALIAS("platform:" DRV_NAME
);