Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

extcon: arizona: Factor out microphone and button detection

Continue refactoring the microphone detect handling by factoring
out the handling for microphone detection and button detection
into separate functions. This both makes the code a little clearer
and prepares for some planned future refactoring to make the state
handling in the driver more explicit.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

authored by

Charles Keepax and committed by
Chanwoo Choi
4b28b25c 7e14fc43

+71 -44
+71 -44
drivers/extcon/extcon-arizona.c
··· 872 872 return val; 873 873 } 874 874 875 - static void arizona_micd_detect(struct work_struct *work) 875 + static int arizona_micdet_reading(void *priv) 876 876 { 877 - struct arizona_extcon_info *info = container_of(work, 878 - struct arizona_extcon_info, 879 - micd_detect_work.work); 877 + struct arizona_extcon_info *info = priv; 880 878 struct arizona *arizona = info->arizona; 881 - unsigned int val = 0, lvl; 882 - int ret, i, key; 883 - 884 - cancel_delayed_work_sync(&info->micd_timeout_work); 885 - 886 - mutex_lock(&info->lock); 887 - 888 - /* If the cable was removed while measuring ignore the result */ 889 - ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); 890 - if (ret < 0) { 891 - dev_err(arizona->dev, "Failed to check cable state: %d\n", 892 - ret); 893 - mutex_unlock(&info->lock); 894 - return; 895 - } else if (!ret) { 896 - dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n"); 897 - mutex_unlock(&info->lock); 898 - return; 899 - } 879 + int ret, val; 900 880 901 881 if (info->detecting && arizona->pdata.micd_software_compare) 902 882 ret = arizona_micd_adc_read(info); 903 883 else 904 884 ret = arizona_micd_read(info); 905 885 if (ret < 0) 906 - goto handled; 886 + return ret; 907 887 908 888 val = ret; 909 889 ··· 893 913 info->mic = false; 894 914 info->detecting = false; 895 915 arizona_identify_headphone(info); 896 - goto handled; 916 + return 0; 897 917 } 898 918 899 919 /* If we got a high impedence we should have a headset, report it. */ 900 - if (info->detecting && (val & ARIZONA_MICD_LVL_8)) { 920 + if (val & ARIZONA_MICD_LVL_8) { 901 921 info->mic = true; 902 922 info->detecting = false; 903 923 ··· 916 936 ret); 917 937 } 918 938 919 - goto handled; 939 + return 0; 920 940 } 921 941 922 942 /* If we detected a lower impedence during initial startup ··· 925 945 * plain headphones. If both polarities report a low 926 946 * impedence then give up and report headphones. 927 947 */ 928 - if (info->detecting && (val & MICD_LVL_1_TO_7)) { 948 + if (val & MICD_LVL_1_TO_7) { 929 949 if (info->jack_flips >= info->micd_num_modes * 10) { 930 950 dev_dbg(arizona->dev, "Detected HP/line\n"); 931 951 ··· 939 959 arizona_extcon_set_mode(info, info->micd_mode); 940 960 941 961 info->jack_flips++; 962 + 963 + if (arizona->pdata.micd_software_compare) 964 + regmap_update_bits(arizona->regmap, 965 + ARIZONA_MIC_DETECT_1, 966 + ARIZONA_MICD_ENA, 967 + ARIZONA_MICD_ENA); 968 + 969 + queue_delayed_work(system_power_efficient_wq, 970 + &info->micd_timeout_work, 971 + msecs_to_jiffies(arizona->pdata.micd_timeout)); 942 972 } 943 973 944 - goto handled; 974 + return 0; 945 975 } 976 + 977 + /* 978 + * If we're still detecting and we detect a short then we've 979 + * got a headphone. 980 + */ 981 + dev_dbg(arizona->dev, "Headphone detected\n"); 982 + info->detecting = false; 983 + 984 + arizona_identify_headphone(info); 985 + 986 + return 0; 987 + } 988 + 989 + static int arizona_button_reading(void *priv) 990 + { 991 + struct arizona_extcon_info *info = priv; 992 + struct arizona *arizona = info->arizona; 993 + int val, key, lvl, i; 994 + 995 + val = arizona_micd_read(info); 996 + if (val < 0) 997 + return val; 946 998 947 999 /* 948 1000 * If we're still detecting and we detect a short then we've ··· 998 986 } else { 999 987 dev_err(arizona->dev, "Button out of range\n"); 1000 988 } 1001 - } else if (info->detecting) { 1002 - dev_dbg(arizona->dev, "Headphone detected\n"); 1003 - info->detecting = false; 1004 - 1005 - arizona_identify_headphone(info); 1006 989 } else { 1007 990 dev_warn(arizona->dev, "Button with no mic: %x\n", 1008 991 val); ··· 1011 1004 arizona_extcon_pulse_micbias(info); 1012 1005 } 1013 1006 1014 - handled: 1015 - if (info->detecting) { 1016 - if (arizona->pdata.micd_software_compare) 1017 - regmap_update_bits(arizona->regmap, 1018 - ARIZONA_MIC_DETECT_1, 1019 - ARIZONA_MICD_ENA, 1020 - ARIZONA_MICD_ENA); 1007 + return 0; 1008 + } 1021 1009 1022 - queue_delayed_work(system_power_efficient_wq, 1023 - &info->micd_timeout_work, 1024 - msecs_to_jiffies(arizona->pdata.micd_timeout)); 1010 + static void arizona_micd_detect(struct work_struct *work) 1011 + { 1012 + struct arizona_extcon_info *info = container_of(work, 1013 + struct arizona_extcon_info, 1014 + micd_detect_work.work); 1015 + struct arizona *arizona = info->arizona; 1016 + int ret; 1017 + 1018 + cancel_delayed_work_sync(&info->micd_timeout_work); 1019 + 1020 + mutex_lock(&info->lock); 1021 + 1022 + /* If the cable was removed while measuring ignore the result */ 1023 + ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); 1024 + if (ret < 0) { 1025 + dev_err(arizona->dev, "Failed to check cable state: %d\n", 1026 + ret); 1027 + mutex_unlock(&info->lock); 1028 + return; 1029 + } else if (!ret) { 1030 + dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n"); 1031 + mutex_unlock(&info->lock); 1032 + return; 1025 1033 } 1034 + 1035 + if (info->detecting) 1036 + arizona_micdet_reading(info); 1037 + else 1038 + arizona_button_reading(info); 1026 1039 1027 1040 pm_runtime_mark_last_busy(info->dev); 1028 1041 mutex_unlock(&info->lock);