@@ -55,6 +55,7 @@ static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);
55
55
static const DECLARE_TLV_DB_SCALE (lineout_vol_tlv , -4800 , 100 , 0 ) ;
56
56
static const DECLARE_TLV_DB_SCALE (alc_threshold_tlv , -9450 , 150 , 0 ) ;
57
57
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 ) ;
58
59
59
60
/* ADC and DAC voice mode (8kHz) high pass cutoff value */
60
61
static const char * const da7213_voice_hpf_corner_txt [] = {
@@ -86,6 +87,23 @@ static SOC_ENUM_SINGLE_DECL(da7213_adc_audio_hpf_corner,
86
87
DA7213_AUDIO_HPF_CORNER_SHIFT ,
87
88
da7213_audio_hpf_corner_txt ) ;
88
89
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
+
89
107
/* Gain ramping rate value */
90
108
static const char * const da7213_gain_ramp_rate_txt [] = {
91
109
"nominal rate * 8" , "nominal rate * 16" , "nominal rate / 16" ,
@@ -191,6 +209,64 @@ static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
191
209
* Control Functions
192
210
*/
193
211
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 */
194
270
static int da7213_get_alc_data (struct snd_soc_component * component , u8 reg_val )
195
271
{
196
272
int mid_data , top_data ;
@@ -376,6 +452,64 @@ static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol,
376
452
return snd_soc_put_volsw (kcontrol , ucontrol );
377
453
}
378
454
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
+ }
379
513
380
514
/*
381
515
* KControls
@@ -477,6 +611,37 @@ static const struct snd_kcontrol_new da7213_snd_controls[] = {
477
611
SOC_DOUBLE_R ("Headphone ZC Switch" , DA7213_HP_L_CTRL , DA7213_HP_R_CTRL ,
478
612
DA7213_ZC_EN_SHIFT , DA7213_ZC_EN_MAX , DA7213_NO_INVERT ),
479
613
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
+
480
645
/* Gain Ramping controls */
481
646
SOC_DOUBLE_R ("Aux Gain Ramping Switch" , DA7213_AUX_L_CTRL ,
482
647
DA7213_AUX_R_CTRL , DA7213_GAIN_RAMP_EN_SHIFT ,
@@ -765,7 +930,7 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
765
930
/* Check SRM has locked */
766
931
do {
767
932
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 ) {
769
934
srm_lock = true;
770
935
} else {
771
936
++ i ;
@@ -1949,6 +2114,9 @@ static int da7213_probe(struct snd_soc_component *component)
1949
2114
da7213 -> fixed_clk_auto_pll = true;
1950
2115
}
1951
2116
2117
+ /* Default infinite tone gen, start/stop by Kcontrol */
2118
+ snd_soc_component_write (component , DA7213_TONE_GEN_CYCLES , DA7213_BEEP_CYCLES_MASK );
2119
+
1952
2120
return 0 ;
1953
2121
}
1954
2122
@@ -2096,4 +2264,5 @@ module_i2c_driver(da7213_i2c_driver);
2096
2264
2097
2265
MODULE_DESCRIPTION ("ASoC DA7213 Codec driver" );
2098
2266
MODULE_AUTHOR (
"Adam Thomson <[email protected] >" );
2267
+ MODULE_AUTHOR (
"David Rau <[email protected] >" );
2099
2268
MODULE_LICENSE ("GPL" );
0 commit comments