1 // SPDX-License-Identifier: GPL-2.0-only
3 // nau8315.c -- NAU8315 ALSA SoC Audio Amplifier Driver
5 // Copyright 2020 Nuvoton Technology Crop.
7 // Author: David Lin <ctlin0@nuvoton.com>
9 // Based on MAX98357A.c
11 #include <linux/acpi.h>
12 #include <linux/device.h>
13 #include <linux/err.h>
14 #include <linux/gpio.h>
15 #include <linux/gpio/consumer.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <sound/pcm.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dai.h>
23 #include <sound/soc-dapm.h>
26 struct gpio_desc
*enable
;
30 static int nau8315_daiops_trigger(struct snd_pcm_substream
*substream
,
31 int cmd
, struct snd_soc_dai
*dai
)
33 struct snd_soc_component
*component
= dai
->component
;
34 struct nau8315_priv
*nau8315
=
35 snd_soc_component_get_drvdata(component
);
41 case SNDRV_PCM_TRIGGER_START
:
42 case SNDRV_PCM_TRIGGER_RESUME
:
43 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
44 if (nau8315
->enpin_switch
) {
45 gpiod_set_value(nau8315
->enable
, 1);
46 dev_dbg(component
->dev
, "set enable to 1");
49 case SNDRV_PCM_TRIGGER_STOP
:
50 case SNDRV_PCM_TRIGGER_SUSPEND
:
51 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
52 gpiod_set_value(nau8315
->enable
, 0);
53 dev_dbg(component
->dev
, "set enable to 0");
60 static int nau8315_enpin_event(struct snd_soc_dapm_widget
*w
,
61 struct snd_kcontrol
*kcontrol
, int event
)
63 struct snd_soc_component
*component
=
64 snd_soc_dapm_to_component(w
->dapm
);
65 struct nau8315_priv
*nau8315
=
66 snd_soc_component_get_drvdata(component
);
68 if (event
& SND_SOC_DAPM_PRE_PMU
)
69 nau8315
->enpin_switch
= 1;
70 else if (event
& SND_SOC_DAPM_POST_PMD
)
71 nau8315
->enpin_switch
= 0;
76 static const struct snd_soc_dapm_widget nau8315_dapm_widgets
[] = {
77 SND_SOC_DAPM_OUTPUT("Speaker"),
78 SND_SOC_DAPM_OUT_DRV_E("EN_Pin", SND_SOC_NOPM
, 0, 0, NULL
, 0,
80 SND_SOC_DAPM_PRE_PMU
| SND_SOC_DAPM_POST_PMD
),
83 static const struct snd_soc_dapm_route nau8315_dapm_routes
[] = {
84 {"EN_Pin", NULL
, "HiFi Playback"},
85 {"Speaker", NULL
, "EN_Pin"},
88 static const struct snd_soc_component_driver nau8315_component_driver
= {
89 .dapm_widgets
= nau8315_dapm_widgets
,
90 .num_dapm_widgets
= ARRAY_SIZE(nau8315_dapm_widgets
),
91 .dapm_routes
= nau8315_dapm_routes
,
92 .num_dapm_routes
= ARRAY_SIZE(nau8315_dapm_routes
),
96 .non_legacy_dai_naming
= 1,
99 static const struct snd_soc_dai_ops nau8315_dai_ops
= {
100 .trigger
= nau8315_daiops_trigger
,
103 #define NAU8315_RATES SNDRV_PCM_RATE_8000_96000
104 #define NAU8315_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE)
106 static struct snd_soc_dai_driver nau8315_dai_driver
= {
107 .name
= "nau8315-hifi",
109 .stream_name
= "HiFi Playback",
110 .formats
= NAU8315_FORMATS
,
111 .rates
= NAU8315_RATES
,
115 .ops
= &nau8315_dai_ops
,
118 static int nau8315_platform_probe(struct platform_device
*pdev
)
120 struct nau8315_priv
*nau8315
;
122 nau8315
= devm_kzalloc(&pdev
->dev
, sizeof(*nau8315
), GFP_KERNEL
);
126 nau8315
->enable
= devm_gpiod_get_optional(&pdev
->dev
,
127 "enable", GPIOD_OUT_LOW
);
128 if (IS_ERR(nau8315
->enable
))
129 return PTR_ERR(nau8315
->enable
);
131 dev_set_drvdata(&pdev
->dev
, nau8315
);
133 return devm_snd_soc_register_component(&pdev
->dev
,
134 &nau8315_component_driver
,
135 &nau8315_dai_driver
, 1);
139 static const struct of_device_id nau8315_device_id
[] = {
140 { .compatible
= "nuvoton,nau8315" },
143 MODULE_DEVICE_TABLE(of
, nau8315_device_id
);
147 static const struct acpi_device_id nau8315_acpi_match
[] = {
151 MODULE_DEVICE_TABLE(acpi
, nau8315_acpi_match
);
154 static struct platform_driver nau8315_platform_driver
= {
157 .of_match_table
= of_match_ptr(nau8315_device_id
),
158 .acpi_match_table
= ACPI_PTR(nau8315_acpi_match
),
160 .probe
= nau8315_platform_probe
,
162 module_platform_driver(nau8315_platform_driver
);
164 MODULE_DESCRIPTION("ASoC NAU8315 Mono Class-D Amplifier Driver");
165 MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
166 MODULE_LICENSE("GPL v2");