File Index
Files and directories
Sign in
FILE

mt8192-afe-gpio.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/mediatek/mt8192/mt8192-afe-gpio.c C
  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/pinctrl/consumer.h>
 10
 11#include "mt8192-afe-common.h"
 12#include "mt8192-afe-gpio.h"
 13
 14static struct pinctrl *aud_pinctrl;
 15
 16enum 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
 54struct audio_gpio_attr {
 55	const char *name;
 56	bool gpio_prepare;
 57	struct pinctrl_state *gpioctrl;
 58};
 59
 60static 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
101static DEFINE_MUTEX(gpio_request_mutex);
102
103static 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
130int 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}
162EXPORT_SYMBOL(mt8192_afe_gpio_init);
163
164static 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
175static 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
186static 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
197static 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
208int 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}
307EXPORT_SYMBOL(mt8192_afe_gpio_request);
~/ Read-only file preview.