Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8192/mt8192-afe-gpio.c
26488 views
1
// SPDX-License-Identifier: GPL-2.0
2
//
3
// mt8192-afe-gpio.c -- Mediatek 8192 afe gpio ctrl
4
//
5
// Copyright (c) 2020 MediaTek Inc.
6
// Author: Shane Chien <[email protected]>
7
//
8
9
#include <linux/pinctrl/consumer.h>
10
11
#include "mt8192-afe-common.h"
12
#include "mt8192-afe-gpio.h"
13
14
static struct pinctrl *aud_pinctrl;
15
16
enum mt8192_afe_gpio {
17
MT8192_AFE_GPIO_DAT_MISO_OFF,
18
MT8192_AFE_GPIO_DAT_MISO_ON,
19
MT8192_AFE_GPIO_DAT_MOSI_OFF,
20
MT8192_AFE_GPIO_DAT_MOSI_ON,
21
MT8192_AFE_GPIO_DAT_MISO_CH34_OFF,
22
MT8192_AFE_GPIO_DAT_MISO_CH34_ON,
23
MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF,
24
MT8192_AFE_GPIO_DAT_MOSI_CH34_ON,
25
MT8192_AFE_GPIO_I2S0_OFF,
26
MT8192_AFE_GPIO_I2S0_ON,
27
MT8192_AFE_GPIO_I2S1_OFF,
28
MT8192_AFE_GPIO_I2S1_ON,
29
MT8192_AFE_GPIO_I2S2_OFF,
30
MT8192_AFE_GPIO_I2S2_ON,
31
MT8192_AFE_GPIO_I2S3_OFF,
32
MT8192_AFE_GPIO_I2S3_ON,
33
MT8192_AFE_GPIO_I2S5_OFF,
34
MT8192_AFE_GPIO_I2S5_ON,
35
MT8192_AFE_GPIO_I2S6_OFF,
36
MT8192_AFE_GPIO_I2S6_ON,
37
MT8192_AFE_GPIO_I2S7_OFF,
38
MT8192_AFE_GPIO_I2S7_ON,
39
MT8192_AFE_GPIO_I2S8_OFF,
40
MT8192_AFE_GPIO_I2S8_ON,
41
MT8192_AFE_GPIO_I2S9_OFF,
42
MT8192_AFE_GPIO_I2S9_ON,
43
MT8192_AFE_GPIO_VOW_DAT_OFF,
44
MT8192_AFE_GPIO_VOW_DAT_ON,
45
MT8192_AFE_GPIO_VOW_CLK_OFF,
46
MT8192_AFE_GPIO_VOW_CLK_ON,
47
MT8192_AFE_GPIO_CLK_MOSI_OFF,
48
MT8192_AFE_GPIO_CLK_MOSI_ON,
49
MT8192_AFE_GPIO_TDM_OFF,
50
MT8192_AFE_GPIO_TDM_ON,
51
MT8192_AFE_GPIO_GPIO_NUM
52
};
53
54
struct audio_gpio_attr {
55
const char *name;
56
bool gpio_prepare;
57
struct pinctrl_state *gpioctrl;
58
};
59
60
static struct audio_gpio_attr aud_gpios[MT8192_AFE_GPIO_GPIO_NUM] = {
61
[MT8192_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL},
62
[MT8192_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL},
63
[MT8192_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL},
64
[MT8192_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL},
65
[MT8192_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL},
66
[MT8192_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
67
[MT8192_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL},
68
[MT8192_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
69
[MT8192_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL},
70
[MT8192_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
71
[MT8192_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL},
72
[MT8192_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
73
[MT8192_AFE_GPIO_I2S5_OFF] = {"aud_gpio_i2s5_off", false, NULL},
74
[MT8192_AFE_GPIO_I2S5_ON] = {"aud_gpio_i2s5_on", false, NULL},
75
[MT8192_AFE_GPIO_I2S6_OFF] = {"aud_gpio_i2s6_off", false, NULL},
76
[MT8192_AFE_GPIO_I2S6_ON] = {"aud_gpio_i2s6_on", false, NULL},
77
[MT8192_AFE_GPIO_I2S7_OFF] = {"aud_gpio_i2s7_off", false, NULL},
78
[MT8192_AFE_GPIO_I2S7_ON] = {"aud_gpio_i2s7_on", false, NULL},
79
[MT8192_AFE_GPIO_I2S8_OFF] = {"aud_gpio_i2s8_off", false, NULL},
80
[MT8192_AFE_GPIO_I2S8_ON] = {"aud_gpio_i2s8_on", false, NULL},
81
[MT8192_AFE_GPIO_I2S9_OFF] = {"aud_gpio_i2s9_off", false, NULL},
82
[MT8192_AFE_GPIO_I2S9_ON] = {"aud_gpio_i2s9_on", false, NULL},
83
[MT8192_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
84
[MT8192_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
85
[MT8192_AFE_GPIO_VOW_DAT_OFF] = {"vow_dat_miso_off", false, NULL},
86
[MT8192_AFE_GPIO_VOW_DAT_ON] = {"vow_dat_miso_on", false, NULL},
87
[MT8192_AFE_GPIO_VOW_CLK_OFF] = {"vow_clk_miso_off", false, NULL},
88
[MT8192_AFE_GPIO_VOW_CLK_ON] = {"vow_clk_miso_on", false, NULL},
89
[MT8192_AFE_GPIO_DAT_MISO_CH34_OFF] = {"aud_dat_miso_ch34_off",
90
false, NULL},
91
[MT8192_AFE_GPIO_DAT_MISO_CH34_ON] = {"aud_dat_miso_ch34_on",
92
false, NULL},
93
[MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF] = {"aud_dat_mosi_ch34_off",
94
false, NULL},
95
[MT8192_AFE_GPIO_DAT_MOSI_CH34_ON] = {"aud_dat_mosi_ch34_on",
96
false, NULL},
97
[MT8192_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL},
98
[MT8192_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL},
99
};
100
101
static DEFINE_MUTEX(gpio_request_mutex);
102
103
static int mt8192_afe_gpio_select(struct device *dev,
104
enum mt8192_afe_gpio type)
105
{
106
int ret;
107
108
if (type < 0 || type >= MT8192_AFE_GPIO_GPIO_NUM) {
109
dev_err(dev, "%s(), error, invalid gpio type %d\n",
110
__func__, type);
111
return -EINVAL;
112
}
113
114
if (!aud_gpios[type].gpio_prepare) {
115
dev_warn(dev, "%s(), error, gpio type %d not prepared\n",
116
__func__, type);
117
return -EIO;
118
}
119
120
ret = pinctrl_select_state(aud_pinctrl,
121
aud_gpios[type].gpioctrl);
122
if (ret) {
123
dev_dbg(dev, "%s(), error, can not set gpio type %d\n",
124
__func__, type);
125
}
126
127
return ret;
128
}
129
130
int mt8192_afe_gpio_init(struct device *dev)
131
{
132
int i, ret;
133
134
aud_pinctrl = devm_pinctrl_get(dev);
135
if (IS_ERR(aud_pinctrl)) {
136
ret = PTR_ERR(aud_pinctrl);
137
dev_err(dev, "%s(), ret %d, cannot get aud_pinctrl!\n",
138
__func__, ret);
139
return ret;
140
}
141
142
for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
143
aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl,
144
aud_gpios[i].name);
145
if (IS_ERR(aud_gpios[i].gpioctrl)) {
146
ret = PTR_ERR(aud_gpios[i].gpioctrl);
147
dev_dbg(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n",
148
__func__, aud_gpios[i].name, ret);
149
} else {
150
aud_gpios[i].gpio_prepare = true;
151
}
152
}
153
154
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_CLK_MOSI_ON);
155
156
/* gpio status init */
157
mt8192_afe_gpio_request(dev, false, MT8192_DAI_ADDA, 0);
158
mt8192_afe_gpio_request(dev, false, MT8192_DAI_ADDA, 1);
159
160
return 0;
161
}
162
EXPORT_SYMBOL(mt8192_afe_gpio_init);
163
164
static int mt8192_afe_gpio_adda_dl(struct device *dev, bool enable)
165
{
166
if (enable) {
167
return mt8192_afe_gpio_select(dev,
168
MT8192_AFE_GPIO_DAT_MOSI_ON);
169
} else {
170
return mt8192_afe_gpio_select(dev,
171
MT8192_AFE_GPIO_DAT_MOSI_OFF);
172
}
173
}
174
175
static int mt8192_afe_gpio_adda_ul(struct device *dev, bool enable)
176
{
177
if (enable) {
178
return mt8192_afe_gpio_select(dev,
179
MT8192_AFE_GPIO_DAT_MISO_ON);
180
} else {
181
return mt8192_afe_gpio_select(dev,
182
MT8192_AFE_GPIO_DAT_MISO_OFF);
183
}
184
}
185
186
static int mt8192_afe_gpio_adda_ch34_dl(struct device *dev, bool enable)
187
{
188
if (enable) {
189
return mt8192_afe_gpio_select(dev,
190
MT8192_AFE_GPIO_DAT_MOSI_CH34_ON);
191
} else {
192
return mt8192_afe_gpio_select(dev,
193
MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF);
194
}
195
}
196
197
static int mt8192_afe_gpio_adda_ch34_ul(struct device *dev, bool enable)
198
{
199
if (enable) {
200
return mt8192_afe_gpio_select(dev,
201
MT8192_AFE_GPIO_DAT_MISO_CH34_ON);
202
} else {
203
return mt8192_afe_gpio_select(dev,
204
MT8192_AFE_GPIO_DAT_MISO_CH34_OFF);
205
}
206
}
207
208
int mt8192_afe_gpio_request(struct device *dev, bool enable,
209
int dai, int uplink)
210
{
211
mutex_lock(&gpio_request_mutex);
212
switch (dai) {
213
case MT8192_DAI_ADDA:
214
if (uplink)
215
mt8192_afe_gpio_adda_ul(dev, enable);
216
else
217
mt8192_afe_gpio_adda_dl(dev, enable);
218
break;
219
case MT8192_DAI_ADDA_CH34:
220
if (uplink)
221
mt8192_afe_gpio_adda_ch34_ul(dev, enable);
222
else
223
mt8192_afe_gpio_adda_ch34_dl(dev, enable);
224
break;
225
case MT8192_DAI_I2S_0:
226
if (enable)
227
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S0_ON);
228
else
229
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S0_OFF);
230
break;
231
case MT8192_DAI_I2S_1:
232
if (enable)
233
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S1_ON);
234
else
235
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S1_OFF);
236
break;
237
case MT8192_DAI_I2S_2:
238
if (enable)
239
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S2_ON);
240
else
241
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S2_OFF);
242
break;
243
case MT8192_DAI_I2S_3:
244
if (enable)
245
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S3_ON);
246
else
247
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S3_OFF);
248
break;
249
case MT8192_DAI_I2S_5:
250
if (enable)
251
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S5_ON);
252
else
253
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S5_OFF);
254
break;
255
case MT8192_DAI_I2S_6:
256
if (enable)
257
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S6_ON);
258
else
259
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S6_OFF);
260
break;
261
case MT8192_DAI_I2S_7:
262
if (enable)
263
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S7_ON);
264
else
265
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S7_OFF);
266
break;
267
case MT8192_DAI_I2S_8:
268
if (enable)
269
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S8_ON);
270
else
271
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S8_OFF);
272
break;
273
case MT8192_DAI_I2S_9:
274
if (enable)
275
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S9_ON);
276
else
277
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S9_OFF);
278
break;
279
case MT8192_DAI_TDM:
280
if (enable)
281
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_TDM_ON);
282
else
283
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_TDM_OFF);
284
break;
285
case MT8192_DAI_VOW:
286
if (enable) {
287
mt8192_afe_gpio_select(dev,
288
MT8192_AFE_GPIO_VOW_CLK_ON);
289
mt8192_afe_gpio_select(dev,
290
MT8192_AFE_GPIO_VOW_DAT_ON);
291
} else {
292
mt8192_afe_gpio_select(dev,
293
MT8192_AFE_GPIO_VOW_CLK_OFF);
294
mt8192_afe_gpio_select(dev,
295
MT8192_AFE_GPIO_VOW_DAT_OFF);
296
}
297
break;
298
default:
299
mutex_unlock(&gpio_request_mutex);
300
dev_warn(dev, "%s(), invalid dai %d\n", __func__, dai);
301
return -EINVAL;
302
}
303
mutex_unlock(&gpio_request_mutex);
304
305
return 0;
306
}
307
EXPORT_SYMBOL(mt8192_afe_gpio_request);
308
309