aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.org>2008-12-03 05:44:17 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2008-12-03 07:40:45 -0500
commit6f2a974bfc8d3be7a30674c71e2fef003b39a8d2 (patch)
treee0a981c23de2e36e4dd44c7b93db7d962228588e
parent4b4fffdd9d179677cb030e97869286b62df25adc (diff)
ASoC: tlv320aic3x: headset/button press support
- Add aic3x_set_headset_detection() function to define the headset detection mode for tlv32aic3x chips - added aic3x_button_pressed() - Read from the real-time registers in aic3x_headset_detected() to query headset presence without an occured interrupt Signed-off-by: Daniel Mack <daniel@caiaq.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/codecs/tlv320aic3x.c31
-rw-r--r--sound/soc/codecs/tlv320aic3x.h46
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}
1019EXPORT_SYMBOL_GPL(aic3x_get_gpio); 1019EXPORT_SYMBOL_GPL(aic3x_get_gpio);
1020 1020
1021void 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}
1038EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1039
1021int aic3x_headset_detected(struct snd_soc_codec *codec) 1040int 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}
1027EXPORT_SYMBOL_GPL(aic3x_headset_detected); 1046EXPORT_SYMBOL_GPL(aic3x_headset_detected);
1028 1047
1048int 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}
1054EXPORT_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
234void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); 236void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
235int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); 237int 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. */
245enum {
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
252enum {
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
261enum {
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 */
277void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
278 int headset_debounce, int button_debounce);
236int aic3x_headset_detected(struct snd_soc_codec *codec); 279int aic3x_headset_detected(struct snd_soc_codec *codec);
280int aic3x_button_pressed(struct snd_soc_codec *codec);
237 281
238struct aic3x_setup_data { 282struct aic3x_setup_data {
239 int i2c_bus; 283 int i2c_bus;