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