| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /*
- * Copyright (C) 2011-2014 MediaTek Inc.
- *
- * This program is free software: you can redistribute it and/or modify it under the terms of the
- * GNU General Public License version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with this program.
- * If not, see <http://www.gnu.org/licenses/>.
- */
- #include <mtk_rtc.h>
- #ifdef DFT_TAG
- #undef DFT_TAG
- #endif
- #define DFT_TAG "[WMT-DETECT]"
- #include "wmt_detect.h"
- #include "wmt_gpio.h"
- #define INVALID_PIN_ID (0xFFFFFFFF)
- /*copied form WMT module*/
- static int wmt_detect_dump_pin_conf(void)
- {
- WMT_DETECT_INFO_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("LDO(GPIO%d)\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num);
- } else
- WMT_DETECT_INFO_FUNC("LDO(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("PMU(GPIO%d)\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num);
- } else
- WMT_DETECT_INFO_FUNC("PMU(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("PMUV28(GPIO%d)\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num);
- } else
- WMT_DETECT_INFO_FUNC("PMUV28(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("RST(GPIO%d)\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num);
- } else
- WMT_DETECT_INFO_FUNC("RST(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("BGF_EINT(GPIO%d)\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num);
- } else
- WMT_DETECT_INFO_FUNC("BGF_EINT(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("BGF_EINT_NUM(%d)\n",
- gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num));
- } else
- WMT_DETECT_INFO_FUNC("BGF_EINT_NUM(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d)\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num);
- } else
- WMT_DETECT_INFO_FUNC("WIFI_EINT(not defined)\n");
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
- WMT_DETECT_INFO_FUNC("WIFI_EINT_NUM(%d)\n",
- gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num));
- } else
- WMT_DETECT_INFO_FUNC("WIFI_EINT_NUM(not defined)\n");
- WMT_DETECT_INFO_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n");
- return 0;
- }
- int _wmt_detect_output_low(unsigned int id)
- {
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
- gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0);
- WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n",
- gpio_ctrl_info.gpio_ctrl_state[id].gpio_num,
- gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num));
- }
- return 0;
- }
- int _wmt_detect_output_high(unsigned int id)
- {
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
- gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1);
- WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n",
- gpio_ctrl_info.gpio_ctrl_state[id].gpio_num,
- gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num));
- }
- return 0;
- }
- int _wmt_detect_read_gpio_input(unsigned int id)
- {
- int retval = 0;
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) {
- retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num);
- WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n",
- gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval);
- }
- return retval;
- }
- /*This power on sequence must support all combo chip's basic power on sequence
- * 1. LDO control is a must, if external LDO exist
- * 2. PMU control is a must
- * 3. RST control is a must
- * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup
- * 5. RTC32k clock control is a must
- * */
- static int wmt_detect_chip_pwr_on(void)
- {
- int retval = -1;
- /*setting validiation check*/
- if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) ||
- (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) ||
- (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) {
- WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n",
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num,
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num,
- gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num);
- return retval;
- }
- /*set LDO/PMU/RST to output 0, no pull*/
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
- _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN);
- if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) {
- pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]);
- WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n");
- } else
- WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n");
- _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN);
- if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) {
- pinctrl_select_state(gpio_ctrl_info.pinctrl_info,
- gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]);
- WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n");
- } else
- WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n");
- _wmt_detect_output_low(GPIO_COMBO_RST_PIN);
- #if 0
- _wmt_detect_output_high(GPIO_WIFI_EINT_PIN);
- #endif
- /*pull high LDO*/
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
- _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN);
- /*sleep for LDO stable time*/
- msleep(MAX_LDO_STABLE_TIME);
- /*export RTC clock, sleep for RTC stable time*/
- rtc_gpio_enable_32k(RTC_GPIO_USER_GPS);
- msleep(MAX_RTC_STABLE_TIME);
- /*PMU output low, RST output low, to make chip power off completely*/
- /*always done*/
- /*sleep for power off stable time*/
- msleep(MAX_OFF_STABLE_TIME);
- /*PMU output high, and sleep for reset stable time*/
- _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN);
- #ifdef CONFIG_MTK_COMBO_COMM_NPWR
- if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) &&
- (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) {
- msleep(20);
- _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN);
- msleep(20);
- _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN);
- msleep(20);
- _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN);
- msleep(20);
- _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN);
- msleep(20);
- }
- #endif
- msleep(MAX_RST_STABLE_TIME);
- /*RST output high, and sleep for power on stable time */
- _wmt_detect_output_high(GPIO_COMBO_RST_PIN);
- msleep(MAX_ON_STABLE_TIME);
- retval = 0;
- return retval;
- }
- static int wmt_detect_chip_pwr_off(void)
- {
- /*set RST pin to input low status*/
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num)
- _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN);
- /*set RST pin to input low status*/
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)
- _wmt_detect_output_low(GPIO_COMBO_RST_PIN);
- /*set PMU pin to input low status*/
- if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)
- _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN);
- return 0;
- }
- int wmt_detect_read_ext_cmb_status(void)
- {
- int retval = 0;
- /*read WIFI_EINT pin status*/
- if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) {
- retval = 0;
- WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n");
- } else {
- retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN);
- WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval);
- }
- return retval;
- }
- int wmt_detect_chip_pwr_ctrl(int on)
- {
- int retval = -1;
- if (0 == on) {
- /*power off combo chip */
- retval = wmt_detect_chip_pwr_off();
- } else {
- wmt_detect_dump_pin_conf();
- /*power on combo chip */
- retval = wmt_detect_chip_pwr_on();
- }
- return retval;
- }
- int wmt_detect_sdio_pwr_ctrl(int on)
- {
- int retval = -1;
- #ifdef MTK_WCN_COMBO_CHIP_SUPPORT
- if (0 == on) {
- /*power off SDIO slot */
- retval = board_sdio_ctrl(1, 0);
- } else {
- /*power on SDIO slot */
- retval = board_sdio_ctrl(1, 1);
- }
- #else
- WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n");
- #endif
- return retval;
- }
|