/*clear ACCDET IRQ in accdet register*/
814 static inline void clear_accdet_interrupt(void)
815 {
816 /*it is safe by using polling to adjust when to clear IRQ_CLR_BIT*/
817 pmic_pwrap_write(ACCDET_IRQ_STS, ((pmic_pwrap_read(ACCDET_IRQ_STS)) & 0x8000) | (IRQ_CLR_BIT));
818 ACCDET_DEBUG("[Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
819 }
820
821 static inline void clear_accdet_eint_interrupt(void)
822 {
823 pmic_pwrap_write(ACCDET_IRQ_STS, (((pmic_pwrap_read(ACCDET_IRQ_STS)) & 0x8000) | IRQ_EINT_CLR_BIT));
824 ACCDET_DEBUG("[Accdet]clear_accdet_eint_interrupt: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
825 }
826
827 static inline void check_cable_type(void)
828 {
829 int current_status = 0;
830 int irq_temp = 0; /*for clear IRQ_bit*/
831 int wait_clear_irq_times = 0;
832 #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
833 int pin_adc_value = 0;
834 #define PIN_ADC_CHANNEL 5
835 #endif
836
837 current_status = ((pmic_pwrap_read(ACCDET_STATE_RG) & 0xc0) >> 6); /*A=bit1; B=bit0*/
838 ACCDET_DEBUG("[Accdet]accdet interrupt happen:[%s]current AB = %d\n",
839 accdet_status_string[accdet_status], current_status);
840
841 button_status = 0;
842 pre_status = accdet_status;
843
844 /*ACCDET_DEBUG("[Accdet]check_cable_type: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));*/
845 IRQ_CLR_FLAG = false;
846 switch (accdet_status) {
847 case PLUG_OUT:
848 #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
849 pmic_pwrap_write(ACCDET_DEBOUNCE1, cust_headset_settings->debounce1);
850 #endif
851 if (current_status == 0) {
852 #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
853 /*micbias always on during detected PIN recognition*/
854 pmic_pwrap_write(ACCDET_PWM_WIDTH, cust_headset_settings->pwm_width);
855 pmic_pwrap_write(ACCDET_PWM_THRESH, cust_headset_settings->pwm_width);
856 ACCDET_DEBUG("[Accdet]PIN recognition micbias always on!\n");
857 ACCDET_DEBUG("[Accdet]before adc read, pin_adc_value = %d mv!\n", pin_adc_value);
858 msleep(500);
859 current_status = ((pmic_pwrap_read(ACCDET_STATE_RG) & 0xc0) >> 6); /*A=bit1; B=bit0*/
860 if (current_status == 0 && show_icon_delay != 0) {
861 /*accdet_auxadc_switch(1);switch on when need to use auxadc read voltage*/
862 pin_adc_value = Accdet_PMIC_IMM_GetOneChannelValue(1);
863 ACCDET_DEBUG("[Accdet]pin_adc_value = %d mv!\n", pin_adc_value);
864 /*accdet_auxadc_switch(0);*/
865 if (180 > pin_adc_value && pin_adc_value > 90) { /*90mv ilegal headset*/
866 /*mt_set_gpio_out(GPIO_CAMERA_2_CMRST_PIN, GPIO_OUT_ONE);*/
867 /*ACCDET_DEBUG("[Accdet]PIN recognition change GPIO_OUT!\n");*/
868 mutex_lock(&accdet_eint_irq_sync_mutex);
869 if (1 == eint_accdet_sync_flag) {
870 cable_type = HEADSET_NO_MIC;
871 accdet_status = HOOK_SWITCH;
872 cable_pin_recognition = 1;
873 ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n",
874 cable_pin_recognition);
875 } else {
876 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
877 }
878 mutex_unlock(&accdet_eint_irq_sync_mutex);
879 } else {
880 mutex_lock(&accdet_eint_irq_sync_mutex);
881 if (1 == eint_accdet_sync_flag) {
882 cable_type = HEADSET_NO_MIC;
883 accdet_status = HOOK_SWITCH;
884 } else {
885 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
886 }
887 mutex_unlock(&accdet_eint_irq_sync_mutex);
888 }
889 }
890 #else
891 mutex_lock(&accdet_eint_irq_sync_mutex);
892 if (1 == eint_accdet_sync_flag) {
893 cable_type = HEADSET_NO_MIC;
894 accdet_status = HOOK_SWITCH;
895 } else {
896 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
897 }
898 mutex_unlock(&accdet_eint_irq_sync_mutex);
899 #endif
900 } else if (current_status == 1) {
901 mutex_lock(&accdet_eint_irq_sync_mutex);
902 if (1 == eint_accdet_sync_flag) {
903 accdet_status = MIC_BIAS;
904 cable_type = HEADSET_MIC;
905 /*AB=11 debounce=30ms*/
906 pmic_pwrap_write(ACCDET_DEBOUNCE3, cust_headset_settings->debounce3 * 30);
907 } else {
908 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
909 }
910 mutex_unlock(&accdet_eint_irq_sync_mutex);
911 pmic_pwrap_write(ACCDET_DEBOUNCE0, button_press_debounce);
912 /*recover polling set AB 00-01*/
913 #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
914 pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
915 pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
916 #endif
917 } else if (current_status == 3) {
918 ACCDET_DEBUG("[Accdet]PLUG_OUT state not change!\n");
919 #ifdef CONFIG_ACCDET_EINT
920 ACCDET_DEBUG("[Accdet] do not send plug out event in plug out\n");
921 #else
922 mutex_lock(&accdet_eint_irq_sync_mutex);
923 if (1 == eint_accdet_sync_flag) {
924 accdet_status = PLUG_OUT;
925 cable_type = NO_DEVICE;
926 } else {
927 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
928 }
929 mutex_unlock(&accdet_eint_irq_sync_mutex);
930 #endif
931 } else {
932 ACCDET_DEBUG("[Accdet]PLUG_OUT can't change to this state!\n");
933 }
934 break;
935
936 case MIC_BIAS:
937 /*solution: resume hook switch debounce time*/
938 pmic_pwrap_write(ACCDET_DEBOUNCE0, cust_headset_settings->debounce0);
939
940 if (current_status == 0) {
941 mutex_lock(&accdet_eint_irq_sync_mutex);
942 if (1 == eint_accdet_sync_flag) {
943 while ((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT)
944 && (wait_clear_irq_times < 3)) {
945 ACCDET_DEBUG("[Accdet]check_cable_type: MIC BIAS clear IRQ on-going1....\n");
946 wait_clear_irq_times++;
947 msleep(20);
948 }
949 irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS);
950 irq_temp = irq_temp & (~IRQ_CLR_BIT);
951 pmic_pwrap_write(ACCDET_IRQ_STS, irq_temp);
952 IRQ_CLR_FLAG = true;
953 accdet_status = HOOK_SWITCH;
954 } else {
955 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
956 }
957 mutex_unlock(&accdet_eint_irq_sync_mutex);
958 button_status = 1;
959 if (button_status) {
960 mutex_lock(&accdet_eint_irq_sync_mutex);
961 if (1 == eint_accdet_sync_flag)
962 multi_key_detection(current_status);
963 else
964 ACCDET_DEBUG("[Accdet] multi_key_detection: Headset has plugged out\n");
965 mutex_unlock(&accdet_eint_irq_sync_mutex);
966 /*accdet_auxadc_switch(0);*/
967 /*recover pwm frequency and duty*/
968 pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
969 pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
970 }
971 } else if (current_status == 1) {
972 mutex_lock(&accdet_eint_irq_sync_mutex);
973 if (1 == eint_accdet_sync_flag) {
974 accdet_status = MIC_BIAS;
975 cable_type = HEADSET_MIC;
976 ACCDET_DEBUG("[Accdet]MIC_BIAS state not change!\n");
977 } else {
978 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
979 }
980 mutex_unlock(&accdet_eint_irq_sync_mutex);
981 } else if (current_status == 3) {
982 #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
983 ACCDET_DEBUG("[Accdet]do not send plug ou in micbiast\n");
984 mutex_lock(&accdet_eint_irq_sync_mutex);
985 if (1 == eint_accdet_sync_flag)
986 accdet_status = PLUG_OUT;
987 else
988 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
989 mutex_unlock(&accdet_eint_irq_sync_mutex);
990 #else
991 mutex_lock(&accdet_eint_irq_sync_mutex);
992 if (1 == eint_accdet_sync_flag) {
993 accdet_status = PLUG_OUT;
994 cable_type = NO_DEVICE;
995 } else {
996 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
997 }
998 mutex_unlock(&accdet_eint_irq_sync_mutex);
999 #endif
1000 } else {
1001 ACCDET_DEBUG("[Accdet]MIC_BIAS can't change to this state!\n");
1002 }
1003 break;
1004
1005 case HOOK_SWITCH:
1006 if (current_status == 0) {
1007 mutex_lock(&accdet_eint_irq_sync_mutex);
1008 if (1 == eint_accdet_sync_flag) {
1009 /*for avoid 01->00 framework of Headset will report press key info for Audio*/
1010 /*cable_type = HEADSET_NO_MIC;*/
1011 /*accdet_status = HOOK_SWITCH;*/
1012 ACCDET_DEBUG("[Accdet]HOOK_SWITCH state not change!\n");
1013 } else {
1014 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
1015 }
1016 mutex_unlock(&accdet_eint_irq_sync_mutex);
1017 } else if (current_status == 1) {
1018 mutex_lock(&accdet_eint_irq_sync_mutex);
1019 if (1 == eint_accdet_sync_flag) {
1020 multi_key_detection(current_status);
1021 accdet_status = MIC_BIAS;
1022 cable_type = HEADSET_MIC;
1023 } else {
1024 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
1025 }
1026 mutex_unlock(&accdet_eint_irq_sync_mutex);
1027 /*accdet_auxadc_switch(0);*/
1028 #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
1029 cable_pin_recognition = 0;
1030 ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n", cable_pin_recognition);
1031 pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
1032 pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
1033 #endif
1034 /*solution: reduce hook switch debounce time to 0x400*/
1035 pmic_pwrap_write(ACCDET_DEBOUNCE0, button_press_debounce);
1036 } else if (current_status == 3) {
1037
1038 #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
1039 cable_pin_recognition = 0;
1040 ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n", cable_pin_recognition);
1041 mutex_lock(&accdet_eint_irq_sync_mutex);
1042 if (1 == eint_accdet_sync_flag)
1043 accdet_status = PLUG_OUT;
1044 else
1045 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
1046 mutex_unlock(&accdet_eint_irq_sync_mutex);
1047 #endif
1048 #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
1049 ACCDET_DEBUG("[Accdet] do not send plug out event in hook switch\n");
1050 mutex_lock(&accdet_eint_irq_sync_mutex);
1051 if (1 == eint_accdet_sync_flag)
1052 accdet_status = PLUG_OUT;
1053 else
1054 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
1055 mutex_unlock(&accdet_eint_irq_sync_mutex);
1056 #else
1057 mutex_lock(&accdet_eint_irq_sync_mutex);
1058 if (1 == eint_accdet_sync_flag) {
1059 accdet_status = PLUG_OUT;
1060 cable_type = NO_DEVICE;
1061 } else {
1062 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
1063 }
1064 mutex_unlock(&accdet_eint_irq_sync_mutex);
1065 #endif
1066 } else {
1067 ACCDET_DEBUG("[Accdet]HOOK_SWITCH can't change to this state!\n");
1068 }
1069 break;
1070 case STAND_BY:
1071 if (current_status == 3) {
1072 #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
1073 ACCDET_DEBUG("[Accdet]accdet do not send plug out event in stand by!\n");
1074 #else
1075 mutex_lock(&accdet_eint_irq_sync_mutex);
1076 if (1 == eint_accdet_sync_flag) {
1077 accdet_status = PLUG_OUT;
1078 cable_type = NO_DEVICE;
1079 } else {
1080 ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
1081 }
1082 mutex_unlock(&accdet_eint_irq_sync_mutex);
1083 #endif
1084 } else {
1085 ACCDET_DEBUG("[Accdet]STAND_BY can't change to this state!\n");
1086 }
1087 break;
1088
1089 default:
1090 ACCDET_DEBUG("[Accdet]check_cable_type: accdet current status error!\n");
1091 break;
1092
1093 }
1094
1095 if (!IRQ_CLR_FLAG) {
1096 mutex_lock(&accdet_eint_irq_sync_mutex);
1097 if (1 == eint_accdet_sync_flag) {
1098 while ((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT) && (wait_clear_irq_times < 3)) {
1099 ACCDET_DEBUG("[Accdet]check_cable_type: Clear interrupt on-going2....\n");
1100 wait_clear_irq_times++;
1101 msleep(20);
1102 }
1103 }
1104 irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS);
1105 irq_temp = irq_temp & (~IRQ_CLR_BIT);
1106 pmic_pwrap_write(ACCDET_IRQ_STS, irq_temp);
1107 mutex_unlock(&accdet_eint_irq_sync_mutex);
1108 IRQ_CLR_FLAG = true;
1109 ACCDET_DEBUG("[Accdet]check_cable_type:Clear interrupt:Done[0x%x]!\n", pmic_pwrap_read(ACCDET_IRQ_STS));
1110
1111 } else {
1112 IRQ_CLR_FLAG = false;
1113 }
1114
1115 ACCDET_DEBUG("[Accdet]cable type:[%s], status switch:[%s]->[%s]\n",
1116 accdet_report_string[cable_type], accdet_status_string[pre_status],
1117 accdet_status_string[accdet_status]);
1118 }