1 // SPDX-License-Identifier: GPL-2.0-only
3 * tegra_wm8753.c - Tegra machine ASoC driver for boards using WM8753 codec.
5 * Author: Stephen Warren <swarren@nvidia.com>
6 * Copyright (C) 2010-2012 - NVIDIA, Inc.
8 * Based on code copyright/by:
10 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
12 * Copyright 2007 Wolfson Microelectronics PLC.
13 * Author: Graeme Gregory
14 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 #include <linux/gpio.h>
21 #include <linux/of_gpio.h>
23 #include <sound/core.h>
24 #include <sound/jack.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/soc.h>
29 #include "../codecs/wm8753.h"
31 #include "tegra_asoc_utils.h"
33 #define DRV_NAME "tegra-snd-wm8753"
36 struct tegra_asoc_utils_data util_data
;
39 static int tegra_wm8753_hw_params(struct snd_pcm_substream
*substream
,
40 struct snd_pcm_hw_params
*params
)
42 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
43 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
44 struct snd_soc_card
*card
= rtd
->card
;
45 struct tegra_wm8753
*machine
= snd_soc_card_get_drvdata(card
);
49 srate
= params_rate(params
);
62 err
= tegra_asoc_utils_set_rate(&machine
->util_data
, srate
, mclk
);
64 dev_err(card
->dev
, "Can't configure clocks\n");
68 err
= snd_soc_dai_set_sysclk(codec_dai
, WM8753_MCLK
, mclk
,
71 dev_err(card
->dev
, "codec_dai clock not set\n");
78 static const struct snd_soc_ops tegra_wm8753_ops
= {
79 .hw_params
= tegra_wm8753_hw_params
,
82 static const struct snd_soc_dapm_widget tegra_wm8753_dapm_widgets
[] = {
83 SND_SOC_DAPM_HP("Headphone Jack", NULL
),
84 SND_SOC_DAPM_MIC("Mic Jack", NULL
),
87 SND_SOC_DAILINK_DEFS(pcm
,
88 DAILINK_COMP_ARRAY(COMP_EMPTY()),
89 DAILINK_COMP_ARRAY(COMP_CODEC(NULL
, "wm8753-hifi")),
90 DAILINK_COMP_ARRAY(COMP_EMPTY()));
92 static struct snd_soc_dai_link tegra_wm8753_dai
= {
94 .stream_name
= "WM8753 PCM",
95 .ops
= &tegra_wm8753_ops
,
96 .dai_fmt
= SND_SOC_DAIFMT_I2S
|
97 SND_SOC_DAIFMT_NB_NF
|
98 SND_SOC_DAIFMT_CBS_CFS
,
99 SND_SOC_DAILINK_REG(pcm
),
102 static struct snd_soc_card snd_soc_tegra_wm8753
= {
103 .name
= "tegra-wm8753",
104 .owner
= THIS_MODULE
,
105 .dai_link
= &tegra_wm8753_dai
,
108 .dapm_widgets
= tegra_wm8753_dapm_widgets
,
109 .num_dapm_widgets
= ARRAY_SIZE(tegra_wm8753_dapm_widgets
),
110 .fully_routed
= true,
113 static int tegra_wm8753_driver_probe(struct platform_device
*pdev
)
115 struct device_node
*np
= pdev
->dev
.of_node
;
116 struct snd_soc_card
*card
= &snd_soc_tegra_wm8753
;
117 struct tegra_wm8753
*machine
;
120 machine
= devm_kzalloc(&pdev
->dev
, sizeof(struct tegra_wm8753
),
125 card
->dev
= &pdev
->dev
;
126 snd_soc_card_set_drvdata(card
, machine
);
128 ret
= snd_soc_of_parse_card_name(card
, "nvidia,model");
132 ret
= snd_soc_of_parse_audio_routing(card
, "nvidia,audio-routing");
136 tegra_wm8753_dai
.codecs
->of_node
= of_parse_phandle(np
,
137 "nvidia,audio-codec", 0);
138 if (!tegra_wm8753_dai
.codecs
->of_node
) {
140 "Property 'nvidia,audio-codec' missing or invalid\n");
145 tegra_wm8753_dai
.cpus
->of_node
= of_parse_phandle(np
,
146 "nvidia,i2s-controller", 0);
147 if (!tegra_wm8753_dai
.cpus
->of_node
) {
149 "Property 'nvidia,i2s-controller' missing or invalid\n");
154 tegra_wm8753_dai
.platforms
->of_node
= tegra_wm8753_dai
.cpus
->of_node
;
156 ret
= tegra_asoc_utils_init(&machine
->util_data
, &pdev
->dev
);
160 ret
= snd_soc_register_card(card
);
162 dev_err(&pdev
->dev
, "snd_soc_register_card failed (%d)\n",
170 tegra_asoc_utils_fini(&machine
->util_data
);
175 static int tegra_wm8753_driver_remove(struct platform_device
*pdev
)
177 struct snd_soc_card
*card
= platform_get_drvdata(pdev
);
178 struct tegra_wm8753
*machine
= snd_soc_card_get_drvdata(card
);
180 snd_soc_unregister_card(card
);
182 tegra_asoc_utils_fini(&machine
->util_data
);
187 static const struct of_device_id tegra_wm8753_of_match
[] = {
188 { .compatible
= "nvidia,tegra-audio-wm8753", },
192 static struct platform_driver tegra_wm8753_driver
= {
195 .pm
= &snd_soc_pm_ops
,
196 .of_match_table
= tegra_wm8753_of_match
,
198 .probe
= tegra_wm8753_driver_probe
,
199 .remove
= tegra_wm8753_driver_remove
,
201 module_platform_driver(tegra_wm8753_driver
);
203 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
204 MODULE_DESCRIPTION("Tegra+WM8753 machine ASoC driver");
205 MODULE_LICENSE("GPL");
206 MODULE_ALIAS("platform:" DRV_NAME
);
207 MODULE_DEVICE_TABLE(of
, tegra_wm8753_of_match
);