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 <ckeepax@opensource.cirrus.com> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
This commit is contained in:
parent
3dfa743dcd
commit
7e14fc437c
@ -804,6 +804,74 @@ static void arizona_micd_timeout_work(struct work_struct *work)
|
||||
mutex_unlock(&info->lock);
|
||||
}
|
||||
|
||||
static int arizona_micd_adc_read(struct arizona_extcon_info *info)
|
||||
{
|
||||
struct arizona *arizona = info->arizona;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
/* Must disable MICD before we read the ADCVAL */
|
||||
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
|
||||
ARIZONA_MICD_ENA, 0);
|
||||
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev,
|
||||
"Failed to read MICDET_ADCVAL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
|
||||
|
||||
val &= ARIZONA_MICDET_ADCVAL_MASK;
|
||||
if (val < ARRAY_SIZE(arizona_micd_levels))
|
||||
val = arizona_micd_levels[val];
|
||||
else
|
||||
val = INT_MAX;
|
||||
|
||||
if (val <= QUICK_HEADPHONE_MAX_OHM)
|
||||
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
|
||||
else if (val <= MICROPHONE_MIN_OHM)
|
||||
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
|
||||
else if (val <= MICROPHONE_MAX_OHM)
|
||||
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
|
||||
else
|
||||
val = ARIZONA_MICD_LVL_8;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int arizona_micd_read(struct arizona_extcon_info *info)
|
||||
{
|
||||
struct arizona *arizona = info->arizona;
|
||||
unsigned int val = 0;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev,
|
||||
"Failed to read MICDET: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(arizona->dev, "MICDET: %x\n", val);
|
||||
|
||||
if (!(val & ARIZONA_MICD_VALID)) {
|
||||
dev_warn(arizona->dev,
|
||||
"Microphone detection state invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
|
||||
dev_err(arizona->dev, "Failed to get valid MICDET value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void arizona_micd_detect(struct work_struct *work)
|
||||
{
|
||||
struct arizona_extcon_info *info = container_of(work,
|
||||
@ -830,61 +898,14 @@ static void arizona_micd_detect(struct work_struct *work)
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->detecting && arizona->pdata.micd_software_compare) {
|
||||
/* Must disable MICD before we read the ADCVAL */
|
||||
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
|
||||
ARIZONA_MICD_ENA, 0);
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev,
|
||||
"Failed to read MICDET_ADCVAL: %d\n",
|
||||
ret);
|
||||
mutex_unlock(&info->lock);
|
||||
return;
|
||||
}
|
||||
if (info->detecting && arizona->pdata.micd_software_compare)
|
||||
ret = arizona_micd_adc_read(info);
|
||||
else
|
||||
ret = arizona_micd_read(info);
|
||||
if (ret < 0)
|
||||
goto handled;
|
||||
|
||||
dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
|
||||
|
||||
val &= ARIZONA_MICDET_ADCVAL_MASK;
|
||||
if (val < ARRAY_SIZE(arizona_micd_levels))
|
||||
val = arizona_micd_levels[val];
|
||||
else
|
||||
val = INT_MAX;
|
||||
|
||||
if (val <= QUICK_HEADPHONE_MAX_OHM)
|
||||
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
|
||||
else if (val <= MICROPHONE_MIN_OHM)
|
||||
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
|
||||
else if (val <= MICROPHONE_MAX_OHM)
|
||||
val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
|
||||
else
|
||||
val = ARIZONA_MICD_LVL_8;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
|
||||
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
|
||||
if (ret != 0) {
|
||||
dev_err(arizona->dev,
|
||||
"Failed to read MICDET: %d\n", ret);
|
||||
mutex_unlock(&info->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_dbg(arizona->dev, "MICDET: %x\n", val);
|
||||
|
||||
if (!(val & ARIZONA_MICD_VALID)) {
|
||||
dev_warn(arizona->dev,
|
||||
"Microphone detection state invalid\n");
|
||||
mutex_unlock(&info->lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
|
||||
dev_err(arizona->dev, "Failed to get valid MICDET value\n");
|
||||
mutex_unlock(&info->lock);
|
||||
return;
|
||||
}
|
||||
val = ret;
|
||||
|
||||
/* Due to jack detect this should never happen */
|
||||
if (!(val & ARIZONA_MICD_STS)) {
|
||||
|
Loading…
Reference in New Issue
Block a user