Skip to content

Commit 64c3259

Browse files
David Raubroonie
David Rau
authored andcommitted
ASoC: da7213: Add new kcontrol for tonegen
Add new kcontrol for tone generator Signed-off-by: David Rau <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 9a4bf1f commit 64c3259

File tree

2 files changed

+233
-2
lines changed

2 files changed

+233
-2
lines changed

sound/soc/codecs/da7213.c

+170-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);
5555
static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0);
5656
static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0);
5757
static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0);
58+
static const DECLARE_TLV_DB_SCALE(da7213_tonegen_gain_tlv, -4500, 300, 0);
5859

5960
/* ADC and DAC voice mode (8kHz) high pass cutoff value */
6061
static const char * const da7213_voice_hpf_corner_txt[] = {
@@ -86,6 +87,23 @@ static SOC_ENUM_SINGLE_DECL(da7213_adc_audio_hpf_corner,
8687
DA7213_AUDIO_HPF_CORNER_SHIFT,
8788
da7213_audio_hpf_corner_txt);
8889

90+
static const char * const da7213_tonegen_dtmf_key_txt[] = {
91+
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
92+
"*", "#"
93+
};
94+
95+
static const struct soc_enum da7213_tonegen_dtmf_key =
96+
SOC_ENUM_SINGLE(DA7213_TONE_GEN_CFG1, DA7213_DTMF_REG_SHIFT,
97+
DA7213_DTMF_REG_MAX, da7213_tonegen_dtmf_key_txt);
98+
99+
static const char * const da7213_tonegen_swg_sel_txt[] = {
100+
"Sum", "SWG1", "SWG2", "Sum"
101+
};
102+
103+
static const struct soc_enum da7213_tonegen_swg_sel =
104+
SOC_ENUM_SINGLE(DA7213_TONE_GEN_CFG2, DA7213_SWG_SEL_SHIFT,
105+
DA7213_SWG_SEL_MAX, da7213_tonegen_swg_sel_txt);
106+
89107
/* Gain ramping rate value */
90108
static const char * const da7213_gain_ramp_rate_txt[] = {
91109
"nominal rate * 8", "nominal rate * 16", "nominal rate / 16",
@@ -191,6 +209,64 @@ static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
191209
* Control Functions
192210
*/
193211

212+
/* Locked Kcontrol calls */
213+
static int da7213_volsw_locked_get(struct snd_kcontrol *kcontrol,
214+
struct snd_ctl_elem_value *ucontrol)
215+
{
216+
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
217+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
218+
int ret;
219+
220+
mutex_lock(&da7213->ctrl_lock);
221+
ret = snd_soc_get_volsw(kcontrol, ucontrol);
222+
mutex_unlock(&da7213->ctrl_lock);
223+
224+
return ret;
225+
}
226+
227+
static int da7213_volsw_locked_put(struct snd_kcontrol *kcontrol,
228+
struct snd_ctl_elem_value *ucontrol)
229+
{
230+
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
231+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
232+
int ret;
233+
234+
mutex_lock(&da7213->ctrl_lock);
235+
ret = snd_soc_put_volsw(kcontrol, ucontrol);
236+
mutex_unlock(&da7213->ctrl_lock);
237+
238+
return ret;
239+
}
240+
241+
static int da7213_enum_locked_get(struct snd_kcontrol *kcontrol,
242+
struct snd_ctl_elem_value *ucontrol)
243+
{
244+
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
245+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
246+
int ret;
247+
248+
mutex_lock(&da7213->ctrl_lock);
249+
ret = snd_soc_get_enum_double(kcontrol, ucontrol);
250+
mutex_unlock(&da7213->ctrl_lock);
251+
252+
return ret;
253+
}
254+
255+
static int da7213_enum_locked_put(struct snd_kcontrol *kcontrol,
256+
struct snd_ctl_elem_value *ucontrol)
257+
{
258+
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
259+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
260+
int ret;
261+
262+
mutex_lock(&da7213->ctrl_lock);
263+
ret = snd_soc_put_enum_double(kcontrol, ucontrol);
264+
mutex_unlock(&da7213->ctrl_lock);
265+
266+
return ret;
267+
}
268+
269+
/* ALC */
194270
static int da7213_get_alc_data(struct snd_soc_component *component, u8 reg_val)
195271
{
196272
int mid_data, top_data;
@@ -376,6 +452,64 @@ static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol,
376452
return snd_soc_put_volsw(kcontrol, ucontrol);
377453
}
378454

455+
/* ToneGen */
456+
static int da7213_tonegen_freq_get(struct snd_kcontrol *kcontrol,
457+
struct snd_ctl_elem_value *ucontrol)
458+
{
459+
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
460+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
461+
struct soc_mixer_control *mixer_ctrl =
462+
(struct soc_mixer_control *) kcontrol->private_value;
463+
unsigned int reg = mixer_ctrl->reg;
464+
__le16 val;
465+
int ret;
466+
467+
mutex_lock(&da7213->ctrl_lock);
468+
ret = regmap_raw_read(da7213->regmap, reg, &val, sizeof(val));
469+
mutex_unlock(&da7213->ctrl_lock);
470+
471+
if (ret)
472+
return ret;
473+
474+
/*
475+
* Frequency value spans two 8-bit registers, lower then upper byte.
476+
* Therefore we need to convert to host endianness here.
477+
*/
478+
ucontrol->value.integer.value[0] = le16_to_cpu(val);
479+
480+
return 0;
481+
}
482+
483+
static int da7213_tonegen_freq_put(struct snd_kcontrol *kcontrol,
484+
struct snd_ctl_elem_value *ucontrol)
485+
{
486+
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
487+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
488+
struct soc_mixer_control *mixer_ctrl =
489+
(struct soc_mixer_control *) kcontrol->private_value;
490+
unsigned int reg = mixer_ctrl->reg;
491+
__le16 val_new, val_old;
492+
int ret;
493+
494+
/*
495+
* Frequency value spans two 8-bit registers, lower then upper byte.
496+
* Therefore we need to convert to little endian here to align with
497+
* HW registers.
498+
*/
499+
val_new = cpu_to_le16(ucontrol->value.integer.value[0]);
500+
501+
mutex_lock(&da7213->ctrl_lock);
502+
ret = regmap_raw_read(da7213->regmap, reg, &val_old, sizeof(val_old));
503+
if (ret == 0 && (val_old != val_new))
504+
ret = regmap_raw_write(da7213->regmap, reg,
505+
&val_new, sizeof(val_new));
506+
mutex_unlock(&da7213->ctrl_lock);
507+
508+
if (ret < 0)
509+
return ret;
510+
511+
return val_old != val_new;
512+
}
379513

380514
/*
381515
* KControls
@@ -477,6 +611,37 @@ static const struct snd_kcontrol_new da7213_snd_controls[] = {
477611
SOC_DOUBLE_R("Headphone ZC Switch", DA7213_HP_L_CTRL, DA7213_HP_R_CTRL,
478612
DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX, DA7213_NO_INVERT),
479613

614+
/* Tone Generator */
615+
SOC_SINGLE_EXT_TLV("ToneGen Volume", DA7213_TONE_GEN_CFG2,
616+
DA7213_TONE_GEN_GAIN_SHIFT, DA7213_TONE_GEN_GAIN_MAX,
617+
DA7213_NO_INVERT, da7213_volsw_locked_get,
618+
da7213_volsw_locked_put, da7213_tonegen_gain_tlv),
619+
SOC_ENUM_EXT("ToneGen DTMF Key", da7213_tonegen_dtmf_key,
620+
da7213_enum_locked_get, da7213_enum_locked_put),
621+
SOC_SINGLE_EXT("ToneGen DTMF Switch", DA7213_TONE_GEN_CFG1,
622+
DA7213_DTMF_EN_SHIFT, DA7213_SWITCH_EN_MAX,
623+
DA7213_NO_INVERT, da7213_volsw_locked_get,
624+
da7213_volsw_locked_put),
625+
SOC_SINGLE_EXT("ToneGen Start", DA7213_TONE_GEN_CFG1,
626+
DA7213_START_STOPN_SHIFT, DA7213_SWITCH_EN_MAX,
627+
DA7213_NO_INVERT, da7213_volsw_locked_get,
628+
da7213_volsw_locked_put),
629+
SOC_ENUM_EXT("ToneGen Sinewave Gen Type", da7213_tonegen_swg_sel,
630+
da7213_enum_locked_get, da7213_enum_locked_put),
631+
SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7213_TONE_GEN_FREQ1_L,
632+
DA7213_FREQ1_L_SHIFT, DA7213_FREQ_MAX, DA7213_NO_INVERT,
633+
da7213_tonegen_freq_get, da7213_tonegen_freq_put),
634+
SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7213_TONE_GEN_FREQ2_L,
635+
DA7213_FREQ2_L_SHIFT, DA7213_FREQ_MAX, DA7213_NO_INVERT,
636+
da7213_tonegen_freq_get, da7213_tonegen_freq_put),
637+
SOC_SINGLE_EXT("ToneGen On Time", DA7213_TONE_GEN_ON_PER,
638+
DA7213_BEEP_ON_PER_SHIFT, DA7213_BEEP_ON_OFF_MAX,
639+
DA7213_NO_INVERT, da7213_volsw_locked_get,
640+
da7213_volsw_locked_put),
641+
SOC_SINGLE("ToneGen Off Time", DA7213_TONE_GEN_OFF_PER,
642+
DA7213_BEEP_OFF_PER_SHIFT, DA7213_BEEP_ON_OFF_MAX,
643+
DA7213_NO_INVERT),
644+
480645
/* Gain Ramping controls */
481646
SOC_DOUBLE_R("Aux Gain Ramping Switch", DA7213_AUX_L_CTRL,
482647
DA7213_AUX_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
@@ -765,7 +930,7 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
765930
/* Check SRM has locked */
766931
do {
767932
pll_status = snd_soc_component_read(component, DA7213_PLL_STATUS);
768-
if (pll_status & DA7219_PLL_SRM_LOCK) {
933+
if (pll_status & DA7213_PLL_SRM_LOCK) {
769934
srm_lock = true;
770935
} else {
771936
++i;
@@ -1949,6 +2114,9 @@ static int da7213_probe(struct snd_soc_component *component)
19492114
da7213->fixed_clk_auto_pll = true;
19502115
}
19512116

2117+
/* Default infinite tone gen, start/stop by Kcontrol */
2118+
snd_soc_component_write(component, DA7213_TONE_GEN_CYCLES, DA7213_BEEP_CYCLES_MASK);
2119+
19522120
return 0;
19532121
}
19542122

@@ -2096,4 +2264,5 @@ module_i2c_driver(da7213_i2c_driver);
20962264

20972265
MODULE_DESCRIPTION("ASoC DA7213 Codec driver");
20982266
MODULE_AUTHOR("Adam Thomson <[email protected]>");
2267+
MODULE_AUTHOR("David Rau <[email protected]>");
20992268
MODULE_LICENSE("GPL");

sound/soc/codecs/da7213.h

+63-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (c) 2013 Dialog Semiconductor
66
*
77
* Author: Adam Thomson <[email protected]>
8+
* Author: David Rau <[email protected]>
89
*/
910

1011
#ifndef _DA7213_H
@@ -135,13 +136,24 @@
135136
#define DA7213_DAC_NG_ON_THRESHOLD 0xB1
136137
#define DA7213_DAC_NG_CTRL 0xB2
137138

139+
#define DA7213_TONE_GEN_CFG1 0xB4
140+
#define DA7213_TONE_GEN_CFG2 0xB5
141+
#define DA7213_TONE_GEN_CYCLES 0xB6
142+
#define DA7213_TONE_GEN_FREQ1_L 0xB7
143+
#define DA7213_TONE_GEN_FREQ1_U 0xB8
144+
#define DA7213_TONE_GEN_FREQ2_L 0xB9
145+
#define DA7213_TONE_GEN_FREQ2_U 0xBA
146+
#define DA7213_TONE_GEN_ON_PER 0xBB
147+
#define DA7213_TONE_GEN_OFF_PER 0xBC
138148

139149
/*
140150
* Bit fields
141151
*/
142152

153+
#define DA7213_SWITCH_EN_MAX 0x1
154+
143155
/* DA7213_PLL_STATUS = 0x03 */
144-
#define DA7219_PLL_SRM_LOCK (0x1 << 1)
156+
#define DA7213_PLL_SRM_LOCK (0x1 << 1)
145157

146158
/* DA7213_SR = 0x22 */
147159
#define DA7213_SR_8000 (0x1 << 0)
@@ -484,6 +496,55 @@
484496
#define DA7213_DAC_NG_EN_SHIFT 7
485497
#define DA7213_DAC_NG_EN_MAX 0x1
486498

499+
/* DA7213_TONE_GEN_CFG1 = 0xB4 */
500+
#define DA7213_DTMF_REG_SHIFT 0
501+
#define DA7213_DTMF_REG_MASK (0xF << 0)
502+
#define DA7213_DTMF_REG_MAX 16
503+
#define DA7213_DTMF_EN_SHIFT 4
504+
#define DA7213_DTMF_EN_MASK (0x1 << 4)
505+
#define DA7213_START_STOPN_SHIFT 7
506+
#define DA7213_START_STOPN_MASK (0x1 << 7)
507+
508+
/* DA7213_TONE_GEN_CFG2 = 0xB5 */
509+
#define DA7213_SWG_SEL_SHIFT 0
510+
#define DA7213_SWG_SEL_MASK (0x3 << 0)
511+
#define DA7213_SWG_SEL_MAX 4
512+
#define DA7213_SWG_SEL_SRAMP (0x3 << 0)
513+
#define DA7213_TONE_GEN_GAIN_SHIFT 4
514+
#define DA7213_TONE_GEN_GAIN_MASK (0xF << 4)
515+
#define DA7213_TONE_GEN_GAIN_MAX 0xF
516+
#define DA7213_TONE_GEN_GAIN_MINUS_9DB (0x3 << 4)
517+
#define DA7213_TONE_GEN_GAIN_MINUS_15DB (0x5 << 4)
518+
519+
/* DA7213_TONE_GEN_CYCLES = 0xB6 */
520+
#define DA7213_BEEP_CYCLES_SHIFT 0
521+
#define DA7213_BEEP_CYCLES_MASK (0x7 << 0)
522+
523+
/* DA7213_TONE_GEN_FREQ1_L = 0xB7 */
524+
#define DA7213_FREQ1_L_SHIFT 0
525+
#define DA7213_FREQ1_L_MASK (0xFF << 0)
526+
#define DA7213_FREQ_MAX 0xFFFF
527+
528+
/* DA7213_TONE_GEN_FREQ1_U = 0xB8 */
529+
#define DA7213_FREQ1_U_SHIFT 0
530+
#define DA7213_FREQ1_U_MASK (0xFF << 0)
531+
532+
/* DA7213_TONE_GEN_FREQ2_L = 0xB9 */
533+
#define DA7213_FREQ2_L_SHIFT 0
534+
#define DA7213_FREQ2_L_MASK (0xFF << 0)
535+
536+
/* DA7213_TONE_GEN_FREQ2_U = 0xBA */
537+
#define DA7213_FREQ2_U_SHIFT 0
538+
#define DA7213_FREQ2_U_MASK (0xFF << 0)
539+
540+
/* DA7213_TONE_GEN_ON_PER = 0xBB */
541+
#define DA7213_BEEP_ON_PER_SHIFT 0
542+
#define DA7213_BEEP_ON_PER_MASK (0x3F << 0)
543+
#define DA7213_BEEP_ON_OFF_MAX 0x3F
544+
545+
/* DA7213_TONE_GEN_OFF_PER = 0xBC */
546+
#define DA7213_BEEP_OFF_PER_SHIFT 0
547+
#define DA7213_BEEP_OFF_PER_MASK (0x3F << 0)
487548

488549
/*
489550
* General defines
@@ -534,6 +595,7 @@ enum da7213_supplies {
534595
/* Codec private data */
535596
struct da7213_priv {
536597
struct regmap *regmap;
598+
struct mutex ctrl_lock;
537599
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
538600
struct clk *mclk;
539601
unsigned int mclk_rate;

0 commit comments

Comments
 (0)