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); 309