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 14 static struct pinctrl *aud_pinctrl; 15 16 enum 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 54 struct audio_gpio_attr { 55 const char *name; 56 bool gpio_prepare; 57 struct pinctrl_state *gpioctrl; 58 }; 59 60 static 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 101 static DEFINE_MUTEX(gpio_request_mutex); 102 103 static 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 130 int 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 } 162 EXPORT_SYMBOL(mt8192_afe_gpio_init); 163 164 static 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 175 static 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 186 static 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 197 static 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 208 int 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 } 307 EXPORT_SYMBOL(mt8192_afe_gpio_request); 308