GNU Linux-libre 5.19-rc6-gnu
[releases.git] / sound / soc / mediatek / mt8192 / mt8192-afe-gpio.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/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);