summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/da7219-aad.h
blob: fbfbf3e67918de5a2bec48de068063569a3cdb7d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * da7219-aad.h - DA7322 ASoC AAD Driver
 *
 * Copyright (c) 2015 Dialog Semiconductor Ltd.
 *
 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
 */

#ifndef __DA7219_AAD_H
#define __DA7219_AAD_H

#include <linux/timer.h>
#include <linux/mutex.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include <sound/da7219-aad.h>

/*
 * Registers
 */

#define DA7219_ACCDET_STATUS_A		0xC0
#define DA7219_ACCDET_STATUS_B		0xC1
#define DA7219_ACCDET_IRQ_EVENT_A	0xC2
#define DA7219_ACCDET_IRQ_EVENT_B	0xC3
#define DA7219_ACCDET_IRQ_MASK_A	0xC4
#define DA7219_ACCDET_IRQ_MASK_B	0xC5
#define DA7219_ACCDET_CONFIG_1		0xC6
#define DA7219_ACCDET_CONFIG_2		0xC7
#define DA7219_ACCDET_CONFIG_3		0xC8
#define DA7219_ACCDET_CONFIG_4		0xC9
#define DA7219_ACCDET_CONFIG_5		0xCA
#define DA7219_ACCDET_CONFIG_6		0xCB
#define DA7219_ACCDET_CONFIG_7		0xCC
#define DA7219_ACCDET_CONFIG_8		0xCD


/*
 * Bit Fields
 */

/* DA7219_ACCDET_STATUS_A = 0xC0 */
#define DA7219_JACK_INSERTION_STS_SHIFT	0
#define DA7219_JACK_INSERTION_STS_MASK	(0x1 << 0)
#define DA7219_JACK_TYPE_STS_SHIFT	1
#define DA7219_JACK_TYPE_STS_MASK	(0x1 << 1)
#define DA7219_JACK_PIN_ORDER_STS_SHIFT	2
#define DA7219_JACK_PIN_ORDER_STS_MASK	(0x1 << 2)
#define DA7219_MICBIAS_UP_STS_SHIFT	3
#define DA7219_MICBIAS_UP_STS_MASK	(0x1 << 3)

/* DA7219_ACCDET_STATUS_B = 0xC1 */
#define DA7219_BUTTON_TYPE_STS_SHIFT	0
#define DA7219_BUTTON_TYPE_STS_MASK	(0xFF << 0)

/* DA7219_ACCDET_IRQ_EVENT_A = 0xC2 */
#define DA7219_E_JACK_INSERTED_SHIFT		0
#define DA7219_E_JACK_INSERTED_MASK		(0x1 << 0)
#define DA7219_E_JACK_REMOVED_SHIFT		1
#define DA7219_E_JACK_REMOVED_MASK		(0x1 << 1)
#define DA7219_E_JACK_DETECT_COMPLETE_SHIFT	2
#define DA7219_E_JACK_DETECT_COMPLETE_MASK	(0x1 << 2)

/* DA7219_ACCDET_IRQ_EVENT_B = 0xC3 */
#define DA7219_E_BUTTON_A_PRESSED_SHIFT		0
#define DA7219_E_BUTTON_A_PRESSED_MASK		(0x1 << 0)
#define DA7219_E_BUTTON_B_PRESSED_SHIFT		1
#define DA7219_E_BUTTON_B_PRESSED_MASK		(0x1 << 1)
#define DA7219_E_BUTTON_C_PRESSED_SHIFT		2
#define DA7219_E_BUTTON_C_PRESSED_MASK		(0x1 << 2)
#define DA7219_E_BUTTON_D_PRESSED_SHIFT		3
#define DA7219_E_BUTTON_D_PRESSED_MASK		(0x1 << 3)
#define DA7219_E_BUTTON_D_RELEASED_SHIFT	4
#define DA7219_E_BUTTON_D_RELEASED_MASK		(0x1 << 4)
#define DA7219_E_BUTTON_C_RELEASED_SHIFT	5
#define DA7219_E_BUTTON_C_RELEASED_MASK		(0x1 << 5)
#define DA7219_E_BUTTON_B_RELEASED_SHIFT	6
#define DA7219_E_BUTTON_B_RELEASED_MASK		(0x1 << 6)
#define DA7219_E_BUTTON_A_RELEASED_SHIFT	7
#define DA7219_E_BUTTON_A_RELEASED_MASK		(0x1 << 7)

/* DA7219_ACCDET_IRQ_MASK_A = 0xC4 */
#define DA7219_M_JACK_INSERTED_SHIFT		0
#define DA7219_M_JACK_INSERTED_MASK		(0x1 << 0)
#define DA7219_M_JACK_REMOVED_SHIFT		1
#define DA7219_M_JACK_REMOVED_MASK		(0x1 << 1)
#define DA7219_M_JACK_DETECT_COMPLETE_SHIFT	2
#define DA7219_M_JACK_DETECT_COMPLETE_MASK	(0x1 << 2)

/* DA7219_ACCDET_IRQ_MASK_B = 0xC5 */
#define DA7219_M_BUTTON_A_PRESSED_SHIFT		0
#define DA7219_M_BUTTON_A_PRESSED_MASK		(0x1 << 0)
#define DA7219_M_BUTTON_B_PRESSED_SHIFT		1
#define DA7219_M_BUTTON_B_PRESSED_MASK		(0x1 << 1)
#define DA7219_M_BUTTON_C_PRESSED_SHIFT		2
#define DA7219_M_BUTTON_C_PRESSED_MASK		(0x1 << 2)
#define DA7219_M_BUTTON_D_PRESSED_SHIFT		3
#define DA7219_M_BUTTON_D_PRESSED_MASK		(0x1 << 3)
#define DA7219_M_BUTTON_D_RELEASED_SHIFT	4
#define DA7219_M_BUTTON_D_RELEASED_MASK		(0x1 << 4)
#define DA7219_M_BUTTON_C_RELEASED_SHIFT	5
#define DA7219_M_BUTTON_C_RELEASED_MASK		(0x1 << 5)
#define DA7219_M_BUTTON_B_RELEASED_SHIFT	6
#define DA7219_M_BUTTON_B_RELEASED_MASK		(0x1 << 6)
#define DA7219_M_BUTTON_A_RELEASED_SHIFT	7
#define DA7219_M_BUTTON_A_RELEASED_MASK		(0x1 << 7)

/* DA7219_ACCDET_CONFIG_1 = 0xC6 */
#define DA7219_ACCDET_EN_SHIFT		0
#define DA7219_ACCDET_EN_MASK		(0x1 << 0)
#define DA7219_BUTTON_CONFIG_SHIFT	1
#define DA7219_BUTTON_CONFIG_MASK	(0x7 << 1)
#define DA7219_MIC_DET_THRESH_SHIFT	4
#define DA7219_MIC_DET_THRESH_MASK	(0x3 << 4)
#define DA7219_JACK_TYPE_DET_EN_SHIFT	6
#define DA7219_JACK_TYPE_DET_EN_MASK	(0x1 << 6)
#define DA7219_PIN_ORDER_DET_EN_SHIFT	7
#define DA7219_PIN_ORDER_DET_EN_MASK	(0x1 << 7)

/* DA7219_ACCDET_CONFIG_2 = 0xC7 */
#define DA7219_ACCDET_PAUSE_SHIFT	0
#define DA7219_ACCDET_PAUSE_MASK	(0x1 << 0)
#define DA7219_JACKDET_DEBOUNCE_SHIFT	1
#define DA7219_JACKDET_DEBOUNCE_MASK	(0x7 << 1)
#define DA7219_JACK_DETECT_RATE_SHIFT	4
#define DA7219_JACK_DETECT_RATE_MASK	(0x3 << 4)
#define DA7219_JACKDET_REM_DEB_SHIFT	6
#define DA7219_JACKDET_REM_DEB_MASK	(0x3 << 6)

/* DA7219_ACCDET_CONFIG_3 = 0xC8 */
#define DA7219_A_D_BUTTON_THRESH_SHIFT	0
#define DA7219_A_D_BUTTON_THRESH_MASK	(0xFF << 0)

/* DA7219_ACCDET_CONFIG_4 = 0xC9 */
#define DA7219_D_B_BUTTON_THRESH_SHIFT	0
#define DA7219_D_B_BUTTON_THRESH_MASK	(0xFF << 0)

/* DA7219_ACCDET_CONFIG_5 = 0xCA */
#define DA7219_B_C_BUTTON_THRESH_SHIFT	0
#define DA7219_B_C_BUTTON_THRESH_MASK	(0xFF << 0)

/* DA7219_ACCDET_CONFIG_6 = 0xCB */
#define DA7219_C_MIC_BUTTON_THRESH_SHIFT	0
#define DA7219_C_MIC_BUTTON_THRESH_MASK		(0xFF << 0)

/* DA7219_ACCDET_CONFIG_7 = 0xCC */
#define DA7219_BUTTON_AVERAGE_SHIFT	0
#define DA7219_BUTTON_AVERAGE_MASK	(0x3 << 0)
#define DA7219_ADC_1_BIT_REPEAT_SHIFT	2
#define DA7219_ADC_1_BIT_REPEAT_MASK	(0x3 << 2)
#define DA7219_PIN_ORDER_FORCE_SHIFT	4
#define DA7219_PIN_ORDER_FORCE_MASK	(0x1 << 4)
#define DA7219_JACK_TYPE_FORCE_SHIFT	5
#define DA7219_JACK_TYPE_FORCE_MASK	(0x1 << 5)

/* DA7219_ACCDET_CONFIG_8 = 0xCD */
#define DA7219_HPTEST_EN_SHIFT		0
#define DA7219_HPTEST_EN_MASK		(0x1 << 0)
#define DA7219_HPTEST_RES_SEL_SHIFT	1
#define DA7219_HPTEST_RES_SEL_MASK	(0x3 << 1)
#define DA7219_HPTEST_RES_SEL_1KOHMS	(0x0 << 1)
#define DA7219_HPTEST_COMP_SHIFT	4
#define DA7219_HPTEST_COMP_MASK		(0x1 << 4)


#define DA7219_AAD_MAX_BUTTONS		4
#define DA7219_AAD_REPORT_ALL_MASK	(SND_JACK_MECHANICAL |			\
					 SND_JACK_HEADSET | SND_JACK_LINEOUT |	\
					 SND_JACK_BTN_0 | SND_JACK_BTN_1 |	\
					 SND_JACK_BTN_2 | SND_JACK_BTN_3)

#define DA7219_AAD_MICBIAS_CHK_DELAY	10
#define DA7219_AAD_MICBIAS_CHK_RETRIES	5

#define DA7219_AAD_HPTEST_RAMP_FREQ		0x28
#define DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC	0x4D
#define DA7219_AAD_HPTEST_PERIOD		65
#define DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY	20

enum da7219_aad_event_regs {
	DA7219_AAD_IRQ_REG_A = 0,
	DA7219_AAD_IRQ_REG_B,
	DA7219_AAD_IRQ_REG_MAX,
};

/* Private data */
struct da7219_aad_priv {
	struct snd_soc_component *component;
	int irq;
	int gnd_switch_delay;

	u8 micbias_pulse_lvl;
	u32 micbias_pulse_time;

	u8 btn_cfg;

	struct work_struct btn_det_work;
	struct work_struct hptest_work;
	struct delayed_work jack_det_work;
	struct workqueue_struct *aad_wq;

	struct snd_soc_jack *jack;
	bool micbias_resume_enable;
	bool jack_inserted;
};

/* AAD control */
void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack);

/* Suspend/Resume */
void da7219_aad_suspend(struct snd_soc_component *component);
void da7219_aad_resume(struct snd_soc_component *component);

/* Init/Exit */
int da7219_aad_init(struct snd_soc_component *component);
void da7219_aad_exit(struct snd_soc_component *component);

/* I2C Probe */
int da7219_aad_probe(struct i2c_client *i2c);

#endif /* __DA7219_AAD_H */