lkml.org 
[lkml]   [2013]   [Nov]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6/7] extcon: arizona: Factor out different headphone detection IPs
    Date
    This patch factors out each headphone detection IP in a seperate
    function this makes the code a little more readable and prevents us
    getting to excessive levels of indentation.

    Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
    ---
    drivers/extcon/extcon-arizona.c | 213 +++++++++++++++++++++++---------------
    1 files changed, 129 insertions(+), 84 deletions(-)

    diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
    index d08e342..4441be4 100644
    --- a/drivers/extcon/extcon-arizona.c
    +++ b/drivers/extcon/extcon-arizona.c
    @@ -354,7 +354,31 @@ static struct {
    { 1000, 10000 },
    };

    -static int arizona_hpdet_read(struct arizona_extcon_info *info)
    +static int arizona_hpdet_read_ip0(struct arizona_extcon_info *info)
    +{
    + struct arizona *arizona = info->arizona;
    + unsigned int val;
    + int ret;
    +
    + ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
    + if (ret != 0) {
    + dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
    + ret);
    + return ret;
    + }
    +
    +
    + if (!(val & ARIZONA_HP_DONE)) {
    + dev_err(arizona->dev, "HPDET did not complete: %x\n", val);
    + return -EAGAIN;
    + }
    +
    + val &= ARIZONA_HP_LVL_MASK;
    +
    + return val;
    +}
    +
    +static int arizona_hpdet_read_ip1(struct arizona_extcon_info *info)
    {
    struct arizona *arizona = info->arizona;
    unsigned int val, range;
    @@ -367,105 +391,126 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
    return ret;
    }

    - switch (info->hpdet_ip) {
    - case 0:
    - if (!(val & ARIZONA_HP_DONE)) {
    - dev_err(arizona->dev, "HPDET did not complete: %x\n",
    - val);
    - return -EAGAIN;
    - }
    + if (!(val & ARIZONA_HP_DONE_B)) {
    + dev_err(arizona->dev, "HPDET did not complete: %x\n", val);
    + return -EAGAIN;
    + }

    - val &= ARIZONA_HP_LVL_MASK;
    - break;
    + ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
    + if (ret != 0) {
    + dev_err(arizona->dev, "Failed to read HP value: %d\n", ret);
    + return -EAGAIN;
    + }

    - case 1:
    - if (!(val & ARIZONA_HP_DONE_B)) {
    - dev_err(arizona->dev, "HPDET did not complete: %x\n",
    - val);
    - return -EAGAIN;
    - }
    + regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, &range);
    + range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
    + >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;

    - ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val);
    - if (ret != 0) {
    - dev_err(arizona->dev, "Failed to read HP value: %d\n",
    - ret);
    - return -EAGAIN;
    - }
    + if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
    + (val < 100 || val >= 0x3fb)) {
    + range++;
    + dev_dbg(arizona->dev, "Moving to HPDET range %d\n", range);
    + regmap_update_bits(arizona->regmap,
    + ARIZONA_HEADPHONE_DETECT_1,
    + ARIZONA_HP_IMPEDANCE_RANGE_MASK,
    + range <<
    + ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
    + return -EAGAIN;
    + }

    - regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
    - &range);
    - range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
    - >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
    + /* If we go out of range report top of range */
    + if (val < 100 || val >= 0x3fb) {
    + dev_dbg(arizona->dev, "Measurement out of range\n");
    + return ARIZONA_HPDET_MAX;
    + }

    - if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
    - (val < 100 || val >= 0x3fb)) {
    - range++;
    - dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
    - range);
    - regmap_update_bits(arizona->regmap,
    - ARIZONA_HEADPHONE_DETECT_1,
    - ARIZONA_HP_IMPEDANCE_RANGE_MASK,
    - range <<
    - ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
    - return -EAGAIN;
    - }
    + dev_dbg(arizona->dev, "HPDET read %d in range %d\n", val, range);

    - /* If we go out of range report top of range */
    - if (val < 100 || val >= 0x3fb) {
    - dev_dbg(arizona->dev, "Measurement out of range\n");
    - return ARIZONA_HPDET_MAX;
    - }
    + val = arizona_hpdet_b_ranges[range].factor_b
    + / ((val * 100) - arizona_hpdet_b_ranges[range].factor_a);
    +
    + return val;
    +}
    +
    +static int arizona_hpdet_read_ip2(struct arizona_extcon_info *info)
    +{
    + struct arizona *arizona = info->arizona;
    + unsigned int val, range;
    + int ret;

    - dev_dbg(arizona->dev, "HPDET read %d in range %d\n",
    - val, range);
    + ret = regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_2, &val);
    + if (ret != 0) {
    + dev_err(arizona->dev, "Failed to read HPDET status: %d\n",
    + ret);
    + return ret;
    + }

    - val = arizona_hpdet_b_ranges[range].factor_b
    - / ((val * 100) -
    - arizona_hpdet_b_ranges[range].factor_a);
    + if (!(val & ARIZONA_HP_DONE_B)) {
    + dev_err(arizona->dev, "HPDET did not complete: %x\n", val);
    + return -EAGAIN;
    + }
    +
    + val &= ARIZONA_HP_LVL_B_MASK;
    + val /= 2;
    +
    + regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, &range);
    + range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
    + >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
    +
    + /* Skip up a range, or report? */
    + if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
    + (val >= arizona_hpdet_c_ranges[range].max)) {
    + range++;
    + dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
    + arizona_hpdet_c_ranges[range].min,
    + arizona_hpdet_c_ranges[range].max);
    + regmap_update_bits(arizona->regmap,
    + ARIZONA_HEADPHONE_DETECT_1,
    + ARIZONA_HP_IMPEDANCE_RANGE_MASK,
    + range <<
    + ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
    + return -EAGAIN;
    + }
    +
    + if (range && (val < arizona_hpdet_c_ranges[range].min)) {
    + dev_dbg(arizona->dev, "Reporting range boundary %d\n",
    + arizona_hpdet_c_ranges[range].min);
    + val = arizona_hpdet_c_ranges[range].min;
    + }
    +
    + return val;
    +}
    +
    +static int arizona_hpdet_read(struct arizona_extcon_info *info)
    +{
    + struct arizona *arizona = info->arizona;
    + int ret = 0;
    +
    + switch (info->hpdet_ip) {
    + case 0:
    + ret = arizona_hpdet_read_ip0(info);
    + if (ret < 0)
    + return ret;
    + break;
    +
    + case 1:
    + ret = arizona_hpdet_read_ip1(info);
    + if (ret < 0)
    + return ret;
    break;

    default:
    dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
    info->hpdet_ip);
    case 2:
    - if (!(val & ARIZONA_HP_DONE_B)) {
    - dev_err(arizona->dev, "HPDET did not complete: %x\n",
    - val);
    - return -EAGAIN;
    - }
    -
    - val &= ARIZONA_HP_LVL_B_MASK;
    - val /= 2;
    -
    - regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
    - &range);
    - range = (range & ARIZONA_HP_IMPEDANCE_RANGE_MASK)
    - >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
    -
    - /* Skip up a range, or report? */
    - if (range < ARRAY_SIZE(arizona_hpdet_c_ranges) - 1 &&
    - (val >= arizona_hpdet_c_ranges[range].max)) {
    - range++;
    - dev_dbg(arizona->dev, "Moving to HPDET range %d-%d\n",
    - arizona_hpdet_c_ranges[range].min,
    - arizona_hpdet_c_ranges[range].max);
    - regmap_update_bits(arizona->regmap,
    - ARIZONA_HEADPHONE_DETECT_1,
    - ARIZONA_HP_IMPEDANCE_RANGE_MASK,
    - range <<
    - ARIZONA_HP_IMPEDANCE_RANGE_SHIFT);
    - return -EAGAIN;
    - }
    -
    - if (range && (val < arizona_hpdet_c_ranges[range].min)) {
    - dev_dbg(arizona->dev, "Reporting range boundary %d\n",
    - arizona_hpdet_c_ranges[range].min);
    - val = arizona_hpdet_c_ranges[range].min;
    - }
    + ret = arizona_hpdet_read_ip2(info);
    + if (ret < 0)
    + return ret;
    + break;
    }

    - dev_dbg(arizona->dev, "HP impedance %d ohms\n", val);
    - return val;
    + dev_dbg(arizona->dev, "HP impedance %d ohms\n", ret);
    + return ret;
    }

    static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
    --
    1.7.2.5


    \
     
     \ /
      Last update: 2013-11-13 19:41    [W:2.965 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site