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
15static struct pinctrl *aud_pinctrl;
16
17enum 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
55struct audio_gpio_attr {
56	const char *name;
57	bool gpio_prepare;
58	struct pinctrl_state *gpioctrl;
59};
60
61static 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
102static DEFINE_MUTEX(gpio_request_mutex);
103
104static 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
131int 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}
163EXPORT_SYMBOL(mt8192_afe_gpio_init);
164
165static 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
176static 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
187static 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
198static 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
209int 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}
308EXPORT_SYMBOL(mt8192_afe_gpio_request);
309