ASoC: Add support for NAU8825 codec to ASoC
PATCH 1/1 ASoC: Add support for NAU8825 codec to ASoC
The NAU88L25 is an ultra-low power high performance audio codec designed for smartphone, tablet PC, and other portable devices by Nuvoton, now add linux driver support for it.
--- include/sound/nau8825_plat.h | 22 ++ sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/nau8825.c | 593 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/nau8825.h | 150 +++++++++++ 5 files changed, 772 insertions(+) create mode 100644 include/sound/nau8825_plat.h create mode 100644 sound/soc/codecs/nau8825.c create mode 100644 sound/soc/codecs/nau8825.h
include/sound/nau8825_plat.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +* linux/sound/snd_nau8825.h -- Platform data for NAU8825 +* +* Copyright 2015 Nuvoton Technology Corp. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __LINUX_SND_NAU8825_H +#define __LINUX_SND_NAU8825_H + +struct nau8825_platform_data { +unsigned int audio_mclk1; +unsigned int gpio_irq; +int naudint_irq; +int headset_detect; +int button_press_detect; +}; + +#endif
sound/soc/codecs/Kconfig +5 -0
@@ -75,6 +75,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX9877 if I2C select SND_SOC_MC13783 if MFD_MC13XXX select SND_SOC_ML26124 if I2C + select SND_SOC_NAU8825 if I2C select SND_SOC_HDMI_CODEC select SND_SOC_PCM1681 if I2C select SND_SOC_PCM1792A if SPI_MASTER
@@ -464,6 +465,10 @@ config SND_SOC_MAX98357A config SND_SOC_MAX9850 tristate +config SND_SOC_NAU8825 + tristate "Nuvoton NAU8825 CODEC" + depends on I2C + config SND_SOC_PCM1681 tristate "Texas Instruments PCM1681 CODEC" depends on I2C
sound/soc/codecs/Makefile +2 -0
@@ -68,6 +68,7 @@ snd-soc-max98357a-objs := max98357a.o snd-soc-max9850-objs := max9850.o snd-soc-mc13783-objs := mc13783.o snd-soc-ml26124-objs := ml26124.o +snd-soc-nau8825-objs := nau8825.o snd-soc-hdmi-codec-objs := hdmi.o snd-soc-pcm1681-objs := pcm1681.o snd-soc-pcm1792a-codec-objs := pcm1792a.o
@@ -252,6 +253,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o +obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
sound/soc/codecs/nau8825.c new file +593 -0
593 lines not on this page · raw message
sound/soc/codecs/nau8825.h new file +150 -0
150 lines not on this page · raw message
Signature · 6 lines
1.9.3 --- Avast 防毒軟體已檢查此封電子郵件的病毒。 http://www.avast.com
include/sound/nau8825_plat.h
Quoted 21 lines · Chih-Chiang Chang
The NAU88L25 is an ultra-low power high performance audio codec designed for smartphone, tablet PC, and other portable devices by Nuvoton, now add linux driver support for it.
Signed-off-by Chih-Chiang Chang <[email protected]>--- include/sound/nau8825_plat.h | 22 ++ sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/nau8825.c | 593 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/nau8825.h | 150 +++++++++++ 5 files changed, 772 insertions(+)create mode 100644
include/sound/nau8825_plat.h
create mode 100644sound/soc/codecs/nau8825.c
create mode 100644sound/soc/codecs/nau8825.hinclude/sound/nau8825_plat.h new file +0
-0
the preferred place for platform_data files is include/linux/platform_data/, but the driver doesn't seem to use the platform data anyway, so maybe drop it?
[...]
sound/soc/codecs/nau8825.c line 2
Quoted 8 lines
sound/soc/codecs/nau8825.c new file +2
-0@@ -0,0 +1,593 @@ +/* +* linux/sound/soc/codecs/nau8825.c
No need to include the file path in the header of the file, this will just become outdated if the file is ever moved.
[...]
sound/soc/codecs/nau8825.c line 43
Quoted 9 lines
sound/soc/codecs/nau8825.c new file +9
-0+static int nau8825_hw_params (struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params, +struct snd_soc_dai *dai); +static int nau8825_set_dai_fmt (struct snd_soc_dai *codec_dai, +unsigned int fmt); +static int nau8825_set_bias_level (struct snd_soc_codec *codec, +enum snd_soc_bias_level level); +static int nau8825_dai_set_sysclk (struct snd_soc_dai *dai,int clk_id, +unsigned int freq,int dir);
These forward declarations don't seem to be necessary.
[...]
sound/soc/codecs/nau8825.c line 59
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +4
-0+static const struct snd_kcontrol_new nau8825_snd_controls[] = { + +SOC_SINGLE ("HP Class OP" ,NAU8825_CLASS_G_CTRL ,NAU8825_CLASS_G_SHIFT , +1 ,0 ),
What is "Class OP"?
sound/soc/codecs/nau8825.c line 61
Quoted 2 lines
sound/soc/codecs/nau8825.c new file +2
-0+SOC_SINGLE ("DAC Right" ,NAU8825_DAC_CTRL ,NAU8825_DAC_R_SFT ,1 ,0 ), + SOC_SINGLE("DAC Left", NAU8825_DAC_CTRL, NAU8825_DAC_L_SFT, 1, 0),
The same bits are controlled by the DAC DAPM widgets, there shouldn't be any controls for them.
sound/soc/codecs/nau8825.c line 65
Quoted 4 lines
sound/soc/codecs/nau8825.c new file +4
-0+SOC_SINGLE ("DAC Right Clock" ,NAU8825_DAC_CTRL ,NAU8825_DAC_CLK_R_SFT , +1 ,0 ), +SOC_SINGLE ("DAC Left Clock" ,NAU8825_DAC_CTRL ,NAU8825_DAC_CLK_L_SFT , + 1, 0),
The clock controls should probably not be user controllable but rather be DAPM supply widgets.
sound/soc/codecs/nau8825.c line 77
Quoted 12 lines
sound/soc/codecs/nau8825.c new file +12
-0+}; + +static const struct snd_kcontrol_new nau8825_hpo_mix[] = { +SOC_DAPM_SINGLE ("HP L Switch" ,NAU8825_HSVOL_CTRL , +NAU8825_L_MUTE_SFT ,1 ,1 ), +SOC_DAPM_SINGLE ("HP R Switch" ,NAU8825_HSVOL_CTRL , +NAU8825_R_MUTE_SFT ,1 ,1 ), +}; + +static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = { + +SND_SOC_DAPM_INPUT ("Mic Jack" ),
Input and output widgets should have the same name as the matching pin of the CODEC.
sound/soc/codecs/nau8825.c line 78
Quoted 1 line
sound/soc/codecs/nau8825.c new file +1
-0+ SND_SOC_DAPM_MICBIAS("MIC BIAS", NAU8825_BOOST, NAU8825_G_BIAS_SFT, 0),
New drivers shouldn't use DAPM_MICBIAS widgets as they are known to be broken. Use a DAPM_SUPPLY widget instead.
sound/soc/codecs/nau8825.c line 83
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+SND_SOC_DAPM_SUPPLY ("micbias" ,SND_SOC_NOPM ,0 ,0 , +NULL ,SND_SOC_DAPM_PRE_PMU + |SND_SOC_DAPM_POST_PMD ), +SND_SOC_DAPM_SUPPLY ("vmid" ,SND_SOC_NOPM ,0 ,0 ,NULL , + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
Both the vmid and micbias supply seem to be unused and don't do anything either.
sound/soc/codecs/nau8825.c line 88
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+/* ADCs */ +SND_SOC_DAPM_ADC ("ADC L" ,NULL ,SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_ADC ("ADC R" ,NULL ,SND_SOC_NOPM ,0 ,0 ), +/* ADC IF1 */ + SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
This one seems to be unused, and doesn't do anything either.
sound/soc/codecs/nau8825.c line 95
Quoted 7 lines
sound/soc/codecs/nau8825.c new file +7
-0+/* Audio Interface */ +SND_SOC_DAPM_AIF_IN ("AIF1RX" ,"AIF1 Playback" ,0 ,SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_AIF_OUT ("AIF1TX" ,"AIF1 Capture" ,0 ,SND_SOC_NOPM ,0 ,0 ), +/* DACs */ +SND_SOC_DAPM_DAC_E ("DAC L1" ,NULL ,NAU8825_DAC_CTRL , +NAU8825_DAC_L_SFT ,0 ,NULL , + SND_SOC_DAPM_PRE_PMD),
Just use DAC instead of DAC_E if you don't have to implement a callback
sound/soc/codecs/nau8825.c line 98
Quoted 3 lines
sound/soc/codecs/nau8825.c new file +3
-0+SND_SOC_DAPM_DAC_E ("DAC R1" ,NULL ,NAU8825_DAC_CTRL , +NAU8825_DAC_R_SFT ,0 ,NULL , + SND_SOC_DAPM_PRE_PMD),
Same here.
sound/soc/codecs/nau8825.c line 103
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+/* SPO/HPO/LOUT/Mono Mixer */ +SND_SOC_DAPM_MIXER ("HPO MIX" ,SND_SOC_NOPM ,0 ,0 , nau8825_hpo_mix, +ARRAY_SIZE (nau8825_hpo_mix)), +SND_SOC_DAPM_PGA_S ("HP amp" ,1 ,NAU8825_CLASS_G_CTRL , + NAU8825_CLASS_G_SHIFT, 0, NULL, 0),
No need for _S if there is no sub-sequencing involved.
sound/soc/codecs/nau8825.c line 108
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+/* Output Lines */ +SND_SOC_DAPM_OUTPUT ("HPOL" ), + SND_SOC_DAPM_OUTPUT("HPOR"), +}; +
[...
sound/soc/codecs/nau8825.c line 129
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +6
-0+static int nau8825_hw_params (struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params, +struct snd_soc_dai *tmp) +{ +struct snd_soc_pcm_runtime *rtd = substream->private_data; +struct snd_soc_codec *codec = rtd->codec;
rtd->codec does not necessarily point to your CODEC device, use dai->codec instead. As rule of thumb you should never have to look at the snd_soc_pcm_runtime in a CODEC driver.
[...]
sound/soc/codecs/nau8825.c line 218
Quoted 10 lines
sound/soc/codecs/nau8825.c new file +10
-0+ +static void config_fll_clk_12m (struct snd_soc_codec *codec) +{ +snd_soc_update_bits (codec,NAU8825_CLK_DIVIDER ,0x000F ,0x0003 ); +snd_soc_update_bits (codec,NAU8825_FL_1 ,0x007F ,0x0001 ); +snd_soc_write (codec,NAU8825_FL_2 ,0xC49B ); +snd_soc_update_bits (codec,NAU8825_FL_3 ,0x03FF ,0x0020 ); +snd_soc_update_bits (codec,NAU8825_FL_4 ,0x0C00 ,0x0800 ); +snd_soc_update_bits (codec,NAU8825_FL_5 ,0x2000 ,0x0000 ); +snd_soc_update_bits (codec,NAU8825_FL_6 ,0x4000 ,0x4000 );
So what do these magic values do?
sound/soc/codecs/nau8825.c line 221
Quoted 3 lines
sound/soc/codecs/nau8825.c new file +3
-0+} + +void set_sys_clk (struct snd_soc_codec *codec,int sys_clk)
static
sound/soc/codecs/nau8825.c
Quoted 2 lines
sound/soc/codecs/nau8825.c new file +2
-0+{ +pr_debug ("%s :: sys_clk=%x\n" , __func__, sys_clk);
[...
sound/soc/codecs/nau8825.c line 291
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+static int nau8825_codec_suspend (struct snd_soc_codec *codec) +{ +nau8825_set_bias_level (codec,SND_SOC_BIAS_OFF ); +return 0 ; +}
set the suspend_bias_off flag in your codec driver to let the core take care of this.
sound/soc/codecs/nau8825.c line 297
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +6
-0+ +static int nau8825_resume (struct snd_soc_codec *codec) +{ +nau8825_set_bias_level (codec,SND_SOC_BIAS_STANDBY ); +return 0 ; +}
This is not necessary the core already takes care of it.
Quoted 1 line
+
[...]
sound/soc/codecs/nau8825.c line 361
Quoted 10 lines
sound/soc/codecs/nau8825.c new file +10
-0+static int nau8825_codec_probe (struct snd_soc_codec *codec) +{ +int i; +struct nau8825_priv *nau8825; + + nau8825 =snd_soc_codec_get_drvdata (codec); + nau8825->codec = codec; +/*writing initial register values to the codec*/ +for (i =0 ; i <ARRAY_SIZE (nau8825_reg); i++) +snd_soc_write (codec, nau8825_reg[i].reg, nau8825_reg[i].def);
If that is really necessary use regmap_sync() and preferably in the i2c probe function. But I'd expect that a soft reset should put the device in the default register configuration?
Quoted 3 lines
sound/soc/codecs/nau8825.c new file +3
-0+return 0 ; +} +
[...]
Quoted 1 line
+static struct
snd_soc_codec_driversoc_codec_driver_nau8825= {
const
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+ .probe = nau8825_codec_probe, + .remove = nau8825_codec_remove, + .suspend = nau8825_codec_suspend, + .resume = nau8825_resume, + .set_bias_level = nau8825_set_bias_level,
sound/soc/codecs/nau8825.c
Quoted 10 lines
sound/soc/codecs/nau8825.c new file +9
-0+ .controls = nau8825_snd_controls, + .num_controls = ARRAY_SIZE(nau8825_snd_controls), + .dapm_widgets = nau8825_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), + .dapm_routes = nau8825_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), +}; + +static struct snd_soc_dai_ops nau8825_dai_ops = {
const
Quoted 26 lines
sound/soc/codecs/nau8825.c new file +26
-0+ .hw_params = nau8825_hw_params, + .set_sysclk = nau8825_dai_set_sysclk, + .set_fmt = nau8825_set_dai_fmt, + .digital_mute = nau8825_dac_mute, +}; + +static struct snd_soc_dai_driver nau8825_dai_driver[] = { + { + .name ="nau8825-aif1" , + .playback = { + .stream_name ="AIF1 Playback" , + .channels_min =1 , + .channels_max =2 , + .rates =NAU8825_RATES , + .formats =NAU8825_FORMATS , + }, + .capture = { + .stream_name ="AIF1 Capture" , + .channels_min =1 , + .channels_max =2 , + .rates =NAU8825_RATES , + .formats =NAU8825_FORMATS , + }, + .ops = &nau8825_dai_ops, + } +};
sound/soc/codecs/nau8825.c line 538
Quoted 10 lines
sound/soc/codecs/nau8825.c new file +10
-0+ + +static int nau8825_i2c_probe (struct i2c_client *i2c, +const struct i2c_device_id *i2c_id) +{ +struct nau8825_platform_data *pdata =dev_get_platdata (&i2c->dev); +struct nau8825_priv *nau8825; +int ret; + + nau8825 = devm_kzalloc(&i2c->dev, sizeof(struct nau8825_priv),
preferred form for this is sizeof(*nau8825)
[...]
sound/soc/codecs/nau8825.c line 593
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+MODULE_DESCRIPTION ("ASoC NAU8825 codec driver" ); +MODULE_AUTHOR ("Nuvoton" ); +MODULE_LICENSE ("GPL v2" ); + +
No need for the extra new lines at the end
Quoted 7 lines
sound/soc/codecs/nau8825.h new file +1
-0@@ -0,0 +1,150 @@ +/*
[...]
Quoted 7 lines
sound/soc/codecs/nau8825.h new file +7
-0+ +struct nau8825_priv { +struct snd_soc_codec *codec; +struct nau8825_platform_data pdata; +struct regmap *regmap; +struct i2c_client *i2c; +struct snd_soc_jack *hp_jack;
sound/soc/codecs/nau8825.h line 149
Quoted 10 lines
sound/soc/codecs/nau8825.h new file +10
-0+struct snd_soc_jack *mic_jack; +struct delayed_work delayed_work; + +struct workqueue_struct *workqueue; +struct mutex mutex; +unsigned int irq; +bool jd_status; +bool bp_status; +int jack_type; +};
It looks like pretty much all of the fields in the struct are not used by the driver.
Quoted 2 lines
+#endif /*
_NAU8825_H*/
Quoted 17 lines · Lars-Peter Clausen
Quoted 16 lines · Chih-Chiang Chang
The NAU88L25 is an ultra-low power high performance audio codec designed for smartphone, tablet PC, and other portable devices by Nuvoton, now add linux driver support for it.
Signed-off-by Chih-Chiang Chang <[email protected]>--- include/sound/nau8825_plat.h | 22 ++ sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/nau8825.c | 593 +++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/nau8825.h | 150 +++++++++++ 5 files changed, 772 insertions(+)create mode 100644
include/sound/nau8825_plat.h
create mode 100644sound/soc/codecs/nau8825.c
create mode 100644sound/soc/codecs/nau8825.h
Quoted 8 lines
include/sound/nau8825_plat.h
Quoted 5 lines
include/sound/nau8825_plat.h new file +0
-0the preferred place for
platform_datafiles isinclude/linux/platform_data/, but the driver doesn't seem to use the platform data anyway, so maybe drop it?
The data is reserved for future use, so drop it now.
For the preferred place for platform_data files, there are more than 300 files in the sound/soc/codecs folder. But I find only few files refer the platform_data files in include/linux/platform_data/ folder, most files put platform_data files in include/sound/ folder.
cczhang@MS00-Linux:~/broonie_linux/sound/sound/soc/codecs$ grep -nr "linux/platform_data/" * adau1761.c:20:#include <linux/platform_data/adau17x1.h> adau1781.c:20:#include <linux/platform_data/adau17x1.h> adau17x1.h:5:#include <linux/platform_data/adau17x1.h> adau1977.c:16:#include <linux/platform_data/adau1977.h> ssm2518.c:17:#include <linux/platform_data/ssm2518.h>
Quoted 13 lines
[...]
sound/soc/codecs/nau8825.c line 2
Quoted 8 lines
sound/soc/codecs/nau8825.c new file +2
-0@@ -0,0 +1,593 @@ +/* +* linux/sound/soc/codecs/nau8825.c No need to include the file path in the header of the file, this will just become outdated if the file is ever moved.
Removed the file path in source.
Quoted 13 lines
[...]
sound/soc/codecs/nau8825.c line 43
Quoted 9 lines
sound/soc/codecs/nau8825.c new file +9
-0+static int nau8825_hw_params (struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params, +struct snd_soc_dai *dai); +static int nau8825_set_dai_fmt (struct snd_soc_dai *codec_dai, +unsigned int fmt); +static int nau8825_set_bias_level (struct snd_soc_codec *codec, +enum snd_soc_bias_level level); +static int nau8825_dai_set_sysclk (struct snd_soc_dai *dai,int clk_id, +unsigned int freq,int dir);These forward declarations don't seem to be necessary.
Removed.
Quoted 9 lines
[...]
sound/soc/codecs/nau8825.c line 59
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +4
-0+static const struct snd_kcontrol_new nau8825_snd_controls[] = { + +SOC_SINGLE ("HP Class OP" ,NAU8825_CLASS_G_CTRL ,NAU8825_CLASS_G_SHIFT , +1 ,0 ),What is "Class OP"?
"Class OP" means amplifier. The code is removed due to DAC DAPM widgets have the same bit control for NAU8825_CLASS_G_CTRL.
Quoted 6 lines
sound/soc/codecs/nau8825.c line 61
Quoted 3 lines
sound/soc/codecs/nau8825.c new file +2
-0+SOC_SINGLE ("DAC Right" ,NAU8825_DAC_CTRL ,NAU8825_DAC_R_SFT ,1 ,0 ), + SOC_SINGLE("DAC Left", NAU8825_DAC_CTRL, NAU8825_DAC_L_SFT, 1, 0),The same bits are controlled by the DAC DAPM widgets, there shouldn't be any controls for them.
Removed.
Quoted 8 lines
sound/soc/codecs/nau8825.c line 65
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +4
-0+SOC_SINGLE ("DAC Right Clock" ,NAU8825_DAC_CTRL ,NAU8825_DAC_CLK_R_SFT , +1 ,0 ), +SOC_SINGLE ("DAC Left Clock" ,NAU8825_DAC_CTRL ,NAU8825_DAC_CLK_L_SFT , + 1, 0),The clock controls should probably not be user controllable but rather be DAPM supply widgets.
The code is not used, removed.
Quoted 16 lines
sound/soc/codecs/nau8825.c line 77
Quoted 13 lines
sound/soc/codecs/nau8825.c new file +12
-0+}; + +static const struct snd_kcontrol_new nau8825_hpo_mix[] = { +SOC_DAPM_SINGLE ("HP L Switch" ,NAU8825_HSVOL_CTRL , +NAU8825_L_MUTE_SFT ,1 ,1 ), +SOC_DAPM_SINGLE ("HP R Switch" ,NAU8825_HSVOL_CTRL , +NAU8825_R_MUTE_SFT ,1 ,1 ), +}; + +static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = { + +SND_SOC_DAPM_INPUT ("Mic Jack" ),Input and output widgets should have the same name as the matching pin of the CODEC.
Modified as below.
SND_SOC_DAPM_INPUT("MIC"),Quoted 5 lines
sound/soc/codecs/nau8825.c line 78
Quoted 2 lines
sound/soc/codecs/nau8825.c new file +1
-0+ SND_SOC_DAPM_MICBIAS("MIC BIAS", NAU8825_BOOST, NAU8825_G_BIAS_SFT, 0),New drivers shouldn't use
DAPM_MICBIASwidgets as they are known to be broken. Use aDAPM_SUPPLYwidget instead.
Modified as below.
SND_SOC_DAPM_SUPPLY("MIC BIAS", NAU8825_BOOST, NAU8825_G_BIAS_SFT, 0,
NULL, 0),Quoted 8 lines
sound/soc/codecs/nau8825.c line 83
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +5
-0+SND_SOC_DAPM_SUPPLY ("micbias" ,SND_SOC_NOPM ,0 ,0 , +NULL ,SND_SOC_DAPM_PRE_PMU + |SND_SOC_DAPM_POST_PMD ), +SND_SOC_DAPM_SUPPLY ("vmid" ,SND_SOC_NOPM ,0 ,0 ,NULL , + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),Both the vmid and micbias supply seem to be unused and don't do anything either.
Removed.
Quoted 8 lines
sound/soc/codecs/nau8825.c line 88
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +5
-0+/* ADCs */ +SND_SOC_DAPM_ADC ("ADC L" ,NULL ,SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_ADC ("ADC R" ,NULL ,SND_SOC_NOPM ,0 ,0 ), +/* ADC IF1 */ + SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),This one seems to be unused, and doesn't do anything either.
Removed.
Quoted 10 lines
sound/soc/codecs/nau8825.c line 95
Quoted 8 lines
sound/soc/codecs/nau8825.c new file +7
-0+/* Audio Interface */ +SND_SOC_DAPM_AIF_IN ("AIF1RX" ,"AIF1 Playback" ,0 ,SND_SOC_NOPM ,0 ,0 ), +SND_SOC_DAPM_AIF_OUT ("AIF1TX" ,"AIF1 Capture" ,0 ,SND_SOC_NOPM ,0 ,0 ), +/* DACs */ +SND_SOC_DAPM_DAC_E ("DAC L1" ,NULL ,NAU8825_DAC_CTRL , +NAU8825_DAC_L_SFT ,0 ,NULL , + SND_SOC_DAPM_PRE_PMD),Just use DAC instead of
DAC_Eif you don't have to implement a callback
Modified as below.
SND_SOC_DAPM_DAC("DAC L1", NULL, NAU8825_DAC_CTRL,
NAU8825_DAC_L_SFT, 0),Quoted 6 lines
sound/soc/codecs/nau8825.c line 98
Quoted 4 lines
sound/soc/codecs/nau8825.c new file +3
-0+SND_SOC_DAPM_DAC_E ("DAC R1" ,NULL ,NAU8825_DAC_CTRL , +NAU8825_DAC_R_SFT ,0 ,NULL , + SND_SOC_DAPM_PRE_PMD),Same here.
Modified as below.
SND_SOC_DAPM_DAC("DAC R1", NULL, NAU8825_DAC_CTRL,
NAU8825_DAC_R_SFT, 0),Quoted 8 lines
sound/soc/codecs/nau8825.c line 103
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +5
-0+/* SPO/HPO/LOUT/Mono Mixer */ +SND_SOC_DAPM_MIXER ("HPO MIX" ,SND_SOC_NOPM ,0 ,0 , nau8825_hpo_mix, +ARRAY_SIZE (nau8825_hpo_mix)), +SND_SOC_DAPM_PGA_S ("HP amp" ,1 ,NAU8825_CLASS_G_CTRL , + NAU8825_CLASS_G_SHIFT, 0, NULL, 0),No need for _S if there is no sub-sequencing involved.
Modified as below.
SND_SOC_DAPM_SUPPLY("HP amp", NAU8825_CLASS_G_CTRL,
NAU8825_CLASS_G_SHIFT, 0, NULL, 0),Quoted 7 lines
sound/soc/codecs/nau8825.c line 108
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +5
-0+/* Output Lines */ +SND_SOC_DAPM_OUTPUT ("HPOL" ), + SND_SOC_DAPM_OUTPUT("HPOR"), +}; +[...
Quoted 12 lines
sound/soc/codecs/nau8825.c line 129
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +6
-0+static int nau8825_hw_params (struct snd_pcm_substream *substream, +struct snd_pcm_hw_params *params, +struct snd_soc_dai *tmp) +{ +struct snd_soc_pcm_runtime *rtd = substream->private_data; +struct snd_soc_codec *codec = rtd->codec;
rtd->codecdoes not necessarily point to your CODEC device, usedai->codecinstead. As rule of thumb you should never have to look at thesnd_soc_pcm_runtimein a CODEC driver.
Modified as below.
static int nau8825_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;Quoted 14 lines
[...]
sound/soc/codecs/nau8825.c line 218
Quoted 10 lines
sound/soc/codecs/nau8825.c new file +10
-0+ +static void config_fll_clk_12m (struct snd_soc_codec *codec) +{ +snd_soc_update_bits (codec,NAU8825_CLK_DIVIDER ,0x000F ,0x0003 ); +snd_soc_update_bits (codec,NAU8825_FL_1 ,0x007F ,0x0001 ); +snd_soc_write (codec,NAU8825_FL_2 ,0xC49B ); +snd_soc_update_bits (codec,NAU8825_FL_3 ,0x03FF ,0x0020 ); +snd_soc_update_bits (codec,NAU8825_FL_4 ,0x0C00 ,0x0800 ); +snd_soc_update_bits (codec,NAU8825_FL_5 ,0x2000 ,0x0000 ); +snd_soc_update_bits (codec,NAU8825_FL_6 ,0x4000 ,0x4000 );So what do these magic values do?
Modified as below, add definition and remark.
static void config_fll_clk_12m(struct snd_soc_codec *codec)
{
struct nau8825_priv *nau8825 = snd_soc_codec_get_drvdata(codec);
regmap_update_bits(nau8825->regmap, NAU8825_CLK_DIVIDER,
NAU8825_CLK_MCLK_SRC_MASK, 0x0003);
regmap_update_bits(nau8825->regmap, NAU8825_FLL_1,
NAU8825_FLL_RATIO_MASK, 0x0001);
/* FLL 16-bit fractional input */
regmap_write(nau8825->regmap, NAU8825_FLL_2, 0xC49B);
/* FLL 10-bit integer input */
regmap_update_bits(nau8825->regmap, NAU8825_FLL_3,
NAU8825_FLL_INTEGER_MASK, 0x0020);
/* FLL pre-scaler */
regmap_update_bits(nau8825->regmap, NAU8825_FLL_4,
NAU8825_FLL_REF_DIV_MASK, 0x0800);
/* select divied VCO input */
regmap_update_bits(nau8825->regmap, NAU8825_FLL_5,
NAU8825_FLL_FILTER_SW_MASK, 0x0000);
/* FLL sigma delta modulator enable */
regmap_update_bits(nau8825->regmap, NAU8825_FLL_6,
NAU8825_SDM_EN_MASK, 0x4000);Quoted 6 lines
sound/soc/codecs/nau8825.c line 221
Quoted 4 lines
sound/soc/codecs/nau8825.c new file +3
-0+} + +void set_sys_clk (struct snd_soc_codec *codec,int sys_clk)static
Modified as below.
static void set_sys_clk(struct snd_soc_codec *codec, int sys_clk)
Quoted 4 lines
sound/soc/codecs/nau8825.c
Quoted 3 lines
sound/soc/codecs/nau8825.c new file +2
-0+{ +pr_debug ("%s :: sys_clk=%x\n" , __func__, sys_clk);[...
Quoted 8 lines
sound/soc/codecs/nau8825.c line 291
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+static int nau8825_codec_suspend (struct snd_soc_codec *codec) +{ +nau8825_set_bias_level (codec,SND_SOC_BIAS_OFF ); +return 0 ; +}set the
suspend_bias_offflag in your codec driver to let the core take care of this.
Removed nau8825_codec_suspend() and added suspend_bias_off flag in soc_codec_driver_nau8825.
.remove = nau8825_codec_remove,
- .suspend = nau8825_codec_suspend,
- .resume = nau8825_resume,
+ .suspend_bias_off = true,
.set_bias_level = nau8825_set_bias_level,
.controls = nau8825_snd_controls,
.num_controls = ARRAY_SIZE(nau8825_snd_controls),Quoted 9 lines
sound/soc/codecs/nau8825.c line 297
Quoted 7 lines
sound/soc/codecs/nau8825.c new file +6
-0+ +static int nau8825_resume (struct snd_soc_codec *codec) +{ +nau8825_set_bias_level (codec,SND_SOC_BIAS_STANDBY ); +return 0 ; +}This is not necessary the core already takes care of it.
Removed.
Quoted 17 lines
Quoted 2 lines
+
[...]
sound/soc/codecs/nau8825.c line 361
Quoted 10 lines
sound/soc/codecs/nau8825.c new file +10
-0+static int nau8825_codec_probe (struct snd_soc_codec *codec) +{ +int i; +struct nau8825_priv *nau8825; + + nau8825 =snd_soc_codec_get_drvdata (codec); + nau8825->codec = codec; +/*writing initial register values to the codec*/ +for (i =0 ; i <ARRAY_SIZE (nau8825_reg); i++) +snd_soc_write (codec, nau8825_reg[i].reg, nau8825_reg[i].def);If that is really necessary use
regmap_sync()and preferably in the i2c probe function. But I'd expect that a soft reset should put the device in the default register configuration?
About the regmap_sync(), I cannot find it in Linux. Do you mean the regcache_sync()? But it is used to sync the register cache with the hardware, not set reg_defaults array to hardware.
Remove nau8825_codec_probe() and add below code in nau8825_i2c_probe().
dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
goto err_enable;
}
+ /* software reset */
+ regmap_write(nau8825->regmap, NAU8825_RESET, 0x01);
+ regmap_write(nau8825->regmap, NAU8825_RESET, 0x02);
+ /*writing initial register values to the codec*/
+ for (i = 0; i < ARRAY_SIZE(nau8825_reg); i++)
+ regmap_write(nau8825->regmap, nau8825_reg[i].reg,
+ nau8825_reg[i].def);
+
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_driver_nau8825,
nau8825_dai_driver,
ARRAY_SIZE(nau8825_dai_driver));Quoted 8 lines
Quoted 4 lines
sound/soc/codecs/nau8825.c new file +3
-0+return 0 ; +} +[...]
Quoted 1 line
+static struct
snd_soc_codec_driversoc_codec_driver_nau8825= {const
Modified as below.
static const struct snd_soc_codec_driver soc_codec_driver_nau8825 = {
Quoted 15 lines
Quoted 14 lines
sound/soc/codecs/nau8825.c new file +13
-0+ .probe = nau8825_codec_probe, + .remove = nau8825_codec_remove, + .suspend = nau8825_codec_suspend, + .resume = nau8825_resume, + .set_bias_level = nau8825_set_bias_level, + .controls = nau8825_snd_controls, + .num_controls = ARRAY_SIZE(nau8825_snd_controls), + .dapm_widgets = nau8825_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), + .dapm_routes = nau8825_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), +}; +
Quoted 3 lines
Quoted 1 line
+static struct
snd_soc_dai_opsnau8825_dai_ops= {const
Modified as below.
static const struct snd_soc_dai_ops nau8825_dai_ops = {
Quoted 31 lines
Quoted 31 lines
sound/soc/codecs/nau8825.c new file +30
-0+ .hw_params = nau8825_hw_params, + .set_sysclk = nau8825_dai_set_sysclk, + .set_fmt = nau8825_set_dai_fmt, + .digital_mute = nau8825_dac_mute, +}; + +static struct snd_soc_dai_driver nau8825_dai_driver[] = { + { + .name ="nau8825-aif1" , + .playback = { + .stream_name ="AIF1 Playback" , + .channels_min =1 , + .channels_max =2 , + .rates =NAU8825_RATES , + .formats =NAU8825_FORMATS , + }, + .capture = { + .stream_name ="AIF1 Capture" , + .channels_min =1 , + .channels_max =2 , + .rates =NAU8825_RATES , + .formats =NAU8825_FORMATS , + }, + .ops = &nau8825_dai_ops, + } +}; + + +static int nau8825_i2c_probe (struct i2c_client *i2c, +const struct i2c_device_id *i2c_id)
Quoted 8 lines
sound/soc/codecs/nau8825.c line 538
Quoted 6 lines
sound/soc/codecs/nau8825.c new file +6
-0+{ +struct nau8825_platform_data *pdata =dev_get_platdata (&i2c->dev); +struct nau8825_priv *nau8825; +int ret; + + nau8825 = devm_kzalloc(&i2c->dev, sizeof(struct nau8825_priv),preferred form for this is
sizeof(*nau8825)
Modified as below.
nau8825 = devm_kzalloc(&i2c->dev, sizeof(*nau8825),
Quoted 9 lines
[...]
sound/soc/codecs/nau8825.c line 593
Quoted 5 lines
sound/soc/codecs/nau8825.c new file +5
-0+MODULE_DESCRIPTION ("ASoC NAU8825 codec driver" ); +MODULE_AUTHOR ("Nuvoton" ); +MODULE_LICENSE ("GPL v2" ); + +No need for the extra new lines at the end
Removed the new lines.
Quoted 21 lines
Quoted 8 lines
sound/soc/codecs/nau8825.h new file +1
-0@@ -0,0 +1,150 @@ +/* [...]
Quoted 12 lines
sound/soc/codecs/nau8825.h new file +12
-0+ +struct nau8825_priv { +struct snd_soc_codec *codec; +struct nau8825_platform_data pdata; +struct regmap *regmap; +struct i2c_client *i2c; +struct snd_soc_jack *hp_jack; +struct snd_soc_jack *mic_jack; +struct delayed_work delayed_work; + +struct workqueue_struct *workqueue; +struct mutex mutex;
Quoted 8 lines
sound/soc/codecs/nau8825.h line 149
Quoted 5 lines
sound/soc/codecs/nau8825.h new file +5
-0+unsigned int irq; +bool jd_status; +bool bp_status; +int jack_type; +};It looks like pretty much all of the fields in the struct are not used by the driver.
Removed some field and modified as below.
@@ -136,15 +163,7 @@ struct nau8825_priv {
struct nau8825_platform_data pdata;
struct regmap *regmap;
struct i2c_client *i2c;
- struct snd_soc_jack *hp_jack;
- struct snd_soc_jack *mic_jack;
- struct delayed_work delayed_work;
-
- struct workqueue_struct *workqueue;
- struct mutex mutex;
- unsigned int irq;
- bool jd_status;
- bool bp_status;
- int jack_type;
+ struct snd_soc_jack *jack;
+ struct delayed_work jack_detect_work;};
Quoted 4 lines
Quoted 3 lines
+#endif /*
_NAU8825_H*/