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