308 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// mt8192-afe-gpio.c -- Mediatek 8192 afe gpio ctrl4//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 14static struct pinctrl *aud_pinctrl;15 16enum 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_NUM52};53 54struct audio_gpio_attr {55 const char *name;56 bool gpio_prepare;57 struct pinctrl_state *gpioctrl;58};59 60static 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 101static DEFINE_MUTEX(gpio_request_mutex);102 103static 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 130int 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}162EXPORT_SYMBOL(mt8192_afe_gpio_init);163 164static 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 175static 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 186static 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 197static 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 208int 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 else217 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 else223 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 else229 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 else235 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 else241 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 else247 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 else253 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 else259 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 else265 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 else271 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 else277 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 else283 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}307EXPORT_SYMBOL(mt8192_afe_gpio_request);308