168 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// nau8315.c -- NAU8315 ALSA SoC Audio Amplifier Driver4//5// Copyright 2020 Nuvoton Technology Crop.6//7// Author: David Lin <ctlin0@nuvoton.com>8//9// Based on MAX98357A.c10 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>18#include <linux/of.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>24 25struct nau8315_priv {26 struct gpio_desc *enable;27 int enpin_switch;28};29 30static int nau8315_daiops_trigger(struct snd_pcm_substream *substream,31 int cmd, struct snd_soc_dai *dai)32{33 struct snd_soc_component *component = dai->component;34 struct nau8315_priv *nau8315 =35 snd_soc_component_get_drvdata(component);36 37 if (!nau8315->enable)38 return 0;39 40 switch (cmd) {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");47 }48 break;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");54 break;55 }56 57 return 0;58}59 60static int nau8315_enpin_event(struct snd_soc_dapm_widget *w,61 struct snd_kcontrol *kcontrol, int event)62{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);67 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;72 73 return 0;74}75 76static 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,79 nau8315_enpin_event,80 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),81};82 83static const struct snd_soc_dapm_route nau8315_dapm_routes[] = {84 {"EN_Pin", NULL, "HiFi Playback"},85 {"Speaker", NULL, "EN_Pin"},86};87 88static 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),93 .idle_bias_on = 1,94 .use_pmdown_time = 1,95 .endianness = 1,96};97 98static const struct snd_soc_dai_ops nau8315_dai_ops = {99 .trigger = nau8315_daiops_trigger,100};101 102#define NAU8315_RATES SNDRV_PCM_RATE_8000_96000103#define NAU8315_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE)104 105static struct snd_soc_dai_driver nau8315_dai_driver = {106 .name = "nau8315-hifi",107 .playback = {108 .stream_name = "HiFi Playback",109 .formats = NAU8315_FORMATS,110 .rates = NAU8315_RATES,111 .channels_min = 1,112 .channels_max = 2,113 },114 .ops = &nau8315_dai_ops,115};116 117static int nau8315_platform_probe(struct platform_device *pdev)118{119 struct nau8315_priv *nau8315;120 121 nau8315 = devm_kzalloc(&pdev->dev, sizeof(*nau8315), GFP_KERNEL);122 if (!nau8315)123 return -ENOMEM;124 125 nau8315->enable = devm_gpiod_get_optional(&pdev->dev,126 "enable", GPIOD_OUT_LOW);127 if (IS_ERR(nau8315->enable))128 return PTR_ERR(nau8315->enable);129 130 dev_set_drvdata(&pdev->dev, nau8315);131 132 return devm_snd_soc_register_component(&pdev->dev,133 &nau8315_component_driver,134 &nau8315_dai_driver, 1);135}136 137#ifdef CONFIG_OF138static const struct of_device_id nau8315_device_id[] = {139 { .compatible = "nuvoton,nau8315" },140 { .compatible = "nuvoton,nau8318" },141 {}142};143MODULE_DEVICE_TABLE(of, nau8315_device_id);144#endif145 146#ifdef CONFIG_ACPI147static const struct acpi_device_id nau8315_acpi_match[] = {148 { "NVTN2010", 0 },149 { "NVTN2012", 0},150 {},151};152MODULE_DEVICE_TABLE(acpi, nau8315_acpi_match);153#endif154 155static struct platform_driver nau8315_platform_driver = {156 .driver = {157 .name = "nau8315",158 .of_match_table = of_match_ptr(nau8315_device_id),159 .acpi_match_table = ACPI_PTR(nau8315_acpi_match),160 },161 .probe = nau8315_platform_probe,162};163module_platform_driver(nau8315_platform_driver);164 165MODULE_DESCRIPTION("ASoC NAU8315 Mono Class-D Amplifier Driver");166MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");167MODULE_LICENSE("GPL v2");168