~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 //
  3 // mt8186-afe-gpio.c  --  Mediatek 8186 afe gpio ctrl
  4 //
  5 // Copyright (c) 2022 MediaTek Inc.
  6 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
  7 
  8 #include <linux/pinctrl/consumer.h>
  9 
 10 #include "mt8186-afe-common.h"
 11 #include "mt8186-afe-gpio.h"
 12 
 13 static struct pinctrl *aud_pinctrl;
 14 
 15 enum mt8186_afe_gpio {
 16         MT8186_AFE_GPIO_CLK_MOSI_OFF,
 17         MT8186_AFE_GPIO_CLK_MOSI_ON,
 18         MT8186_AFE_GPIO_CLK_MISO_OFF,
 19         MT8186_AFE_GPIO_CLK_MISO_ON,
 20         MT8186_AFE_GPIO_DAT_MISO_OFF,
 21         MT8186_AFE_GPIO_DAT_MISO_ON,
 22         MT8186_AFE_GPIO_DAT_MOSI_OFF,
 23         MT8186_AFE_GPIO_DAT_MOSI_ON,
 24         MT8186_AFE_GPIO_I2S0_OFF,
 25         MT8186_AFE_GPIO_I2S0_ON,
 26         MT8186_AFE_GPIO_I2S1_OFF,
 27         MT8186_AFE_GPIO_I2S1_ON,
 28         MT8186_AFE_GPIO_I2S2_OFF,
 29         MT8186_AFE_GPIO_I2S2_ON,
 30         MT8186_AFE_GPIO_I2S3_OFF,
 31         MT8186_AFE_GPIO_I2S3_ON,
 32         MT8186_AFE_GPIO_TDM_OFF,
 33         MT8186_AFE_GPIO_TDM_ON,
 34         MT8186_AFE_GPIO_PCM_OFF,
 35         MT8186_AFE_GPIO_PCM_ON,
 36         MT8186_AFE_GPIO_GPIO_NUM
 37 };
 38 
 39 struct audio_gpio_attr {
 40         const char *name;
 41         bool gpio_prepare;
 42         struct pinctrl_state *gpioctrl;
 43 };
 44 
 45 static struct audio_gpio_attr aud_gpios[MT8186_AFE_GPIO_GPIO_NUM] = {
 46         [MT8186_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL},
 47         [MT8186_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL},
 48         [MT8186_AFE_GPIO_CLK_MISO_OFF] = {"aud_clk_miso_off", false, NULL},
 49         [MT8186_AFE_GPIO_CLK_MISO_ON] = {"aud_clk_miso_on", false, NULL},
 50         [MT8186_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL},
 51         [MT8186_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL},
 52         [MT8186_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL},
 53         [MT8186_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL},
 54         [MT8186_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL},
 55         [MT8186_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
 56         [MT8186_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL},
 57         [MT8186_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
 58         [MT8186_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL},
 59         [MT8186_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
 60         [MT8186_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL},
 61         [MT8186_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
 62         [MT8186_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
 63         [MT8186_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
 64         [MT8186_AFE_GPIO_PCM_OFF] = {"aud_gpio_pcm_off", false, NULL},
 65         [MT8186_AFE_GPIO_PCM_ON] = {"aud_gpio_pcm_on", false, NULL},
 66 };
 67 
 68 static DEFINE_MUTEX(gpio_request_mutex);
 69 
 70 int mt8186_afe_gpio_init(struct device *dev)
 71 {
 72         int i, j, ret;
 73 
 74         aud_pinctrl = devm_pinctrl_get(dev);
 75         if (IS_ERR(aud_pinctrl)) {
 76                 ret = PTR_ERR(aud_pinctrl);
 77                 dev_err(dev, "%s(), ret %d, cannot get aud_pinctrl!\n",
 78                         __func__, ret);
 79                 return ret;
 80         }
 81 
 82         for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
 83                 aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl,
 84                                                              aud_gpios[i].name);
 85                 if (IS_ERR(aud_gpios[i].gpioctrl)) {
 86                         ret = PTR_ERR(aud_gpios[i].gpioctrl);
 87                         dev_dbg(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n",
 88                                  __func__, aud_gpios[i].name, ret);
 89                 } else {
 90                         aud_gpios[i].gpio_prepare = true;
 91                 }
 92         }
 93 
 94         /* gpio status init */
 95         for (i = MT8186_DAI_ADDA; i <= MT8186_DAI_TDM_IN; i++) {
 96                 for (j = 0; j <= 1; j++)
 97                         mt8186_afe_gpio_request(dev, false, i, j);
 98         }
 99 
100         return 0;
101 }
102 EXPORT_SYMBOL_GPL(mt8186_afe_gpio_init);
103 
104 static int mt8186_afe_gpio_select(struct device *dev,
105                                   enum mt8186_afe_gpio type)
106 {
107         int ret = 0;
108 
109         if (type < 0 || type >= MT8186_AFE_GPIO_GPIO_NUM) {
110                 dev_dbg(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_dbg(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                 return ret;
127         }
128 
129         return 0;
130 }
131 
132 static int mt8186_afe_gpio_adda_dl(struct device *dev, bool enable)
133 {
134         int ret;
135 
136         if (enable) {
137                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_ON);
138                 if (ret) {
139                         dev_dbg(dev, "%s(), MOSI CLK ON select fail!\n", __func__);
140                         return ret;
141                 }
142 
143                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_ON);
144                 if (ret) {
145                         dev_dbg(dev, "%s(), MOSI DAT ON select fail!\n", __func__);
146                         return ret;
147                 }
148         } else {
149                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_OFF);
150                 if (ret) {
151                         dev_dbg(dev, "%s(), MOSI DAT OFF select fail!\n", __func__);
152                         return ret;
153                 }
154 
155                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_OFF);
156                 if (ret) {
157                         dev_dbg(dev, "%s(), MOSI CLK ON select fail!\n", __func__);
158                         return ret;
159                 }
160         }
161 
162         return 0;
163 }
164 
165 static int mt8186_afe_gpio_adda_ul(struct device *dev, bool enable)
166 {
167         int ret;
168 
169         if (enable) {
170                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_ON);
171                 if (ret) {
172                         dev_dbg(dev, "%s(), MISO CLK ON select fail!\n", __func__);
173                         return ret;
174                 }
175 
176                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_ON);
177                 if (ret) {
178                         dev_dbg(dev, "%s(), MISO DAT ON select fail!\n", __func__);
179                         return ret;
180                 }
181         } else {
182                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_OFF);
183                 if (ret) {
184                         dev_dbg(dev, "%s(), MISO DAT OFF select fail!\n", __func__);
185                         return ret;
186                 }
187 
188                 ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_OFF);
189                 if (ret) {
190                         dev_dbg(dev, "%s(), MISO CLK OFF select fail!\n", __func__);
191                         return ret;
192                 }
193         }
194 
195         return 0;
196 }
197 
198 int mt8186_afe_gpio_request(struct device *dev, bool enable,
199                             int dai, int uplink)
200 {
201         enum mt8186_afe_gpio sel;
202         int ret = -EINVAL;
203 
204         mutex_lock(&gpio_request_mutex);
205 
206         switch (dai) {
207         case MT8186_DAI_ADDA:
208                 if (uplink)
209                         ret = mt8186_afe_gpio_adda_ul(dev, enable);
210                 else
211                         ret = mt8186_afe_gpio_adda_dl(dev, enable);
212                 goto unlock;
213         case MT8186_DAI_I2S_0:
214                 sel = enable ? MT8186_AFE_GPIO_I2S0_ON : MT8186_AFE_GPIO_I2S0_OFF;
215                 break;
216         case MT8186_DAI_I2S_1:
217                 sel = enable ? MT8186_AFE_GPIO_I2S1_ON : MT8186_AFE_GPIO_I2S1_OFF;
218                 break;
219         case MT8186_DAI_I2S_2:
220                 sel = enable ? MT8186_AFE_GPIO_I2S2_ON : MT8186_AFE_GPIO_I2S2_OFF;
221                 break;
222         case MT8186_DAI_I2S_3:
223                 sel = enable ? MT8186_AFE_GPIO_I2S3_ON : MT8186_AFE_GPIO_I2S3_OFF;
224                 break;
225         case MT8186_DAI_TDM_IN:
226                 sel = enable ? MT8186_AFE_GPIO_TDM_ON : MT8186_AFE_GPIO_TDM_OFF;
227                 break;
228         case MT8186_DAI_PCM:
229                 sel = enable ? MT8186_AFE_GPIO_PCM_ON : MT8186_AFE_GPIO_PCM_OFF;
230                 break;
231         default:
232                 dev_dbg(dev, "%s(), invalid dai %d\n", __func__, dai);
233                 goto unlock;
234         }
235 
236         ret = mt8186_afe_gpio_select(dev, sel);
237 
238 unlock:
239         mutex_unlock(&gpio_request_mutex);
240 
241         return ret;
242 }
243 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php