diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 31 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.h | 46 |
2 files changed, 74 insertions, 3 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 0f4067bdd4a3..341e1adc9167 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1018,14 +1018,41 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio) | |||
1018 | } | 1018 | } |
1019 | EXPORT_SYMBOL_GPL(aic3x_get_gpio); | 1019 | EXPORT_SYMBOL_GPL(aic3x_get_gpio); |
1020 | 1020 | ||
1021 | void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, | ||
1022 | int headset_debounce, int button_debounce) | ||
1023 | { | ||
1024 | u8 val; | ||
1025 | |||
1026 | val = ((detect & AIC3X_HEADSET_DETECT_MASK) | ||
1027 | << AIC3X_HEADSET_DETECT_SHIFT) | | ||
1028 | ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK) | ||
1029 | << AIC3X_HEADSET_DEBOUNCE_SHIFT) | | ||
1030 | ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK) | ||
1031 | << AIC3X_BUTTON_DEBOUNCE_SHIFT); | ||
1032 | |||
1033 | if (detect & AIC3X_HEADSET_DETECT_MASK) | ||
1034 | val |= AIC3X_HEADSET_DETECT_ENABLED; | ||
1035 | |||
1036 | aic3x_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); | ||
1037 | } | ||
1038 | EXPORT_SYMBOL_GPL(aic3x_set_headset_detection); | ||
1039 | |||
1021 | int aic3x_headset_detected(struct snd_soc_codec *codec) | 1040 | int aic3x_headset_detected(struct snd_soc_codec *codec) |
1022 | { | 1041 | { |
1023 | u8 val; | 1042 | u8 val; |
1024 | aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val); | 1043 | aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); |
1025 | return (val >> 2) & 1; | 1044 | return (val >> 4) & 1; |
1026 | } | 1045 | } |
1027 | EXPORT_SYMBOL_GPL(aic3x_headset_detected); | 1046 | EXPORT_SYMBOL_GPL(aic3x_headset_detected); |
1028 | 1047 | ||
1048 | int aic3x_button_pressed(struct snd_soc_codec *codec) | ||
1049 | { | ||
1050 | u8 val; | ||
1051 | aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); | ||
1052 | return (val >> 5) & 1; | ||
1053 | } | ||
1054 | EXPORT_SYMBOL_GPL(aic3x_button_pressed); | ||
1055 | |||
1029 | #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 | 1056 | #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 |
1030 | #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 1057 | #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1031 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) | 1058 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) |
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 7e982acf3996..73e35b6ec929 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h | |||
@@ -39,7 +39,9 @@ | |||
39 | #define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 | 39 | #define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 |
40 | /* Audio codec digital filter control register */ | 40 | /* Audio codec digital filter control register */ |
41 | #define AIC3X_CODEC_DFILT_CTRL 12 | 41 | #define AIC3X_CODEC_DFILT_CTRL 12 |
42 | 42 | /* Headset/button press detection register */ | |
43 | #define AIC3X_HEADSET_DETECT_CTRL_A 13 | ||
44 | #define AIC3X_HEADSET_DETECT_CTRL_B 14 | ||
43 | /* ADC PGA Gain control registers */ | 45 | /* ADC PGA Gain control registers */ |
44 | #define LADC_VOL 15 | 46 | #define LADC_VOL 15 |
45 | #define RADC_VOL 16 | 47 | #define RADC_VOL 16 |
@@ -233,7 +235,49 @@ enum { | |||
233 | 235 | ||
234 | void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); | 236 | void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); |
235 | int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); | 237 | int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); |
238 | |||
239 | /* headset detection / button API */ | ||
240 | |||
241 | /* The AIC3x supports detection of stereo headsets (GND + left + right signal) | ||
242 | * and cellular headsets (GND + speaker output + microphone input). | ||
243 | * It is recommended to enable MIC bias for this function to work properly. | ||
244 | * For more information, please refer to the datasheet. */ | ||
245 | enum { | ||
246 | AIC3X_HEADSET_DETECT_OFF = 0, | ||
247 | AIC3X_HEADSET_DETECT_STEREO = 1, | ||
248 | AIC3X_HEADSET_DETECT_CELLULAR = 2, | ||
249 | AIC3X_HEADSET_DETECT_BOTH = 3 | ||
250 | }; | ||
251 | |||
252 | enum { | ||
253 | AIC3X_HEADSET_DEBOUNCE_16MS = 0, | ||
254 | AIC3X_HEADSET_DEBOUNCE_32MS = 1, | ||
255 | AIC3X_HEADSET_DEBOUNCE_64MS = 2, | ||
256 | AIC3X_HEADSET_DEBOUNCE_128MS = 3, | ||
257 | AIC3X_HEADSET_DEBOUNCE_256MS = 4, | ||
258 | AIC3X_HEADSET_DEBOUNCE_512MS = 5 | ||
259 | }; | ||
260 | |||
261 | enum { | ||
262 | AIC3X_BUTTON_DEBOUNCE_0MS = 0, | ||
263 | AIC3X_BUTTON_DEBOUNCE_8MS = 1, | ||
264 | AIC3X_BUTTON_DEBOUNCE_16MS = 2, | ||
265 | AIC3X_BUTTON_DEBOUNCE_32MS = 3 | ||
266 | }; | ||
267 | |||
268 | #define AIC3X_HEADSET_DETECT_ENABLED 0x80 | ||
269 | #define AIC3X_HEADSET_DETECT_SHIFT 5 | ||
270 | #define AIC3X_HEADSET_DETECT_MASK 3 | ||
271 | #define AIC3X_HEADSET_DEBOUNCE_SHIFT 2 | ||
272 | #define AIC3X_HEADSET_DEBOUNCE_MASK 7 | ||
273 | #define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 | ||
274 | #define AIC3X_BUTTON_DEBOUNCE_MASK 3 | ||
275 | |||
276 | /* see the enums above for valid parameters to this function */ | ||
277 | void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, | ||
278 | int headset_debounce, int button_debounce); | ||
236 | int aic3x_headset_detected(struct snd_soc_codec *codec); | 279 | int aic3x_headset_detected(struct snd_soc_codec *codec); |
280 | int aic3x_button_pressed(struct snd_soc_codec *codec); | ||
237 | 281 | ||
238 | struct aic3x_setup_data { | 282 | struct aic3x_setup_data { |
239 | int i2c_bus; | 283 | int i2c_bus; |