Skip to content

Commit 7e14fc4

Browse files
charleskeepaxchanwoochoi
authored andcommitted
extcon: arizona: Factor out microphone impedance into a function
The microphone detection handler is very long, start breaking it up by factoring out the actual reading of the impedance value into a separate functions. Additionally, this also fixes a minor bug and ensures that the microphone timeout will be rescheduled in all error cases. Signed-off-by: Charles Keepax <[email protected]> Signed-off-by: Chanwoo Choi <[email protected]>
1 parent 3dfa743 commit 7e14fc4

File tree

1 file changed

+73
-52
lines changed

1 file changed

+73
-52
lines changed

drivers/extcon/extcon-arizona.c

Lines changed: 73 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -804,88 +804,109 @@ static void arizona_micd_timeout_work(struct work_struct *work)
804804
mutex_unlock(&info->lock);
805805
}
806806

807-
static void arizona_micd_detect(struct work_struct *work)
807+
static int arizona_micd_adc_read(struct arizona_extcon_info *info)
808808
{
809-
struct arizona_extcon_info *info = container_of(work,
810-
struct arizona_extcon_info,
811-
micd_detect_work.work);
812809
struct arizona *arizona = info->arizona;
813-
unsigned int val = 0, lvl;
814-
int ret, i, key;
815-
816-
cancel_delayed_work_sync(&info->micd_timeout_work);
810+
unsigned int val;
811+
int ret;
817812

818-
mutex_lock(&info->lock);
813+
/* Must disable MICD before we read the ADCVAL */
814+
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
815+
ARIZONA_MICD_ENA, 0);
819816

820-
/* If the cable was removed while measuring ignore the result */
821-
ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
822-
if (ret < 0) {
823-
dev_err(arizona->dev, "Failed to check cable state: %d\n",
824-
ret);
825-
mutex_unlock(&info->lock);
826-
return;
827-
} else if (!ret) {
828-
dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
829-
mutex_unlock(&info->lock);
830-
return;
817+
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
818+
if (ret != 0) {
819+
dev_err(arizona->dev,
820+
"Failed to read MICDET_ADCVAL: %d\n", ret);
821+
return ret;
831822
}
832823

833-
if (info->detecting && arizona->pdata.micd_software_compare) {
834-
/* Must disable MICD before we read the ADCVAL */
835-
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
836-
ARIZONA_MICD_ENA, 0);
837-
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
838-
if (ret != 0) {
839-
dev_err(arizona->dev,
840-
"Failed to read MICDET_ADCVAL: %d\n",
841-
ret);
842-
mutex_unlock(&info->lock);
843-
return;
844-
}
824+
dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
845825

846-
dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
826+
val &= ARIZONA_MICDET_ADCVAL_MASK;
827+
if (val < ARRAY_SIZE(arizona_micd_levels))
828+
val = arizona_micd_levels[val];
829+
else
830+
val = INT_MAX;
831+
832+
if (val <= QUICK_HEADPHONE_MAX_OHM)
833+
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
834+
else if (val <= MICROPHONE_MIN_OHM)
835+
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
836+
else if (val <= MICROPHONE_MAX_OHM)
837+
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
838+
else
839+
val = ARIZONA_MICD_LVL_8;
847840

848-
val &= ARIZONA_MICDET_ADCVAL_MASK;
849-
if (val < ARRAY_SIZE(arizona_micd_levels))
850-
val = arizona_micd_levels[val];
851-
else
852-
val = INT_MAX;
853-
854-
if (val <= QUICK_HEADPHONE_MAX_OHM)
855-
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
856-
else if (val <= MICROPHONE_MIN_OHM)
857-
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
858-
else if (val <= MICROPHONE_MAX_OHM)
859-
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
860-
else
861-
val = ARIZONA_MICD_LVL_8;
862-
}
841+
return val;
842+
}
843+
844+
static int arizona_micd_read(struct arizona_extcon_info *info)
845+
{
846+
struct arizona *arizona = info->arizona;
847+
unsigned int val = 0;
848+
int ret, i;
863849

864850
for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
865851
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
866852
if (ret != 0) {
867853
dev_err(arizona->dev,
868854
"Failed to read MICDET: %d\n", ret);
869-
mutex_unlock(&info->lock);
870-
return;
855+
return ret;
871856
}
872857

873858
dev_dbg(arizona->dev, "MICDET: %x\n", val);
874859

875860
if (!(val & ARIZONA_MICD_VALID)) {
876861
dev_warn(arizona->dev,
877862
"Microphone detection state invalid\n");
878-
mutex_unlock(&info->lock);
879-
return;
863+
return -EINVAL;
880864
}
881865
}
882866

883867
if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
884868
dev_err(arizona->dev, "Failed to get valid MICDET value\n");
869+
return -EINVAL;
870+
}
871+
872+
return val;
873+
}
874+
875+
static void arizona_micd_detect(struct work_struct *work)
876+
{
877+
struct arizona_extcon_info *info = container_of(work,
878+
struct arizona_extcon_info,
879+
micd_detect_work.work);
880+
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");
885897
mutex_unlock(&info->lock);
886898
return;
887899
}
888900

901+
if (info->detecting && arizona->pdata.micd_software_compare)
902+
ret = arizona_micd_adc_read(info);
903+
else
904+
ret = arizona_micd_read(info);
905+
if (ret < 0)
906+
goto handled;
907+
908+
val = ret;
909+
889910
/* Due to jack detect this should never happen */
890911
if (!(val & ARIZONA_MICD_STS)) {
891912
dev_warn(arizona->dev, "Detected open circuit\n");

0 commit comments

Comments
 (0)