diff options
author | Timo Alho <talho@nvidia.com> | 2014-04-07 14:19:41 +0300 |
---|---|---|
committer | Timo Alho <talho@nvidia.com> | 2014-04-09 03:47:28 -0700 |
commit | 017a1d491ccd08a6a49cdf4f5791654ba8f49c12 (patch) | |
tree | 588335eee53b393d25f7ab4a1c46fac18a7b60c1 /drivers/staging | |
parent | 266d7105717a991f52e4141edbe8ab402ceacad9 (diff) |
iio: meter: ina3221: add FORCED_TRIGGERED mode
This patchs adds an explicit triggered mode into ina3221 driver. There
are now four modes of operation for ina3221 in the device driver
(1) FORCED_TRIGGERED
(2) FORCED_CONTINUOUS
(3) TRIGGERED
(4) CONTINUOUS
First two (1, 2) are selectable from user space. If mode is not forced
from user space, and critical or warning current limit has been
configured, driver automatically picks the mode from latter two (3, 4)
depending on the system activity.
Operation mode of ina3221 can be selected by writing into running_mode
sysfs entry.
* Writing >0 enables FORCED_CONTINUOUS mode
* Writing 0 enables FORCED_TRIGGERED mode
* Writing <0 enables automatic mode selection of the driver
Change-Id: I935e9be3280b46b5ee3dd83f50e4845ae2eafe0b
Signed-off-by: Timo Alho <talho@nvidia.com>
Reviewed-on: http://git-master/r/392886
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/iio/meter/ina3221.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/staging/iio/meter/ina3221.c b/drivers/staging/iio/meter/ina3221.c index 895cf0776a88..89421962cfb7 100644 --- a/drivers/staging/iio/meter/ina3221.c +++ b/drivers/staging/iio/meter/ina3221.c @@ -93,10 +93,14 @@ enum { enum mode { TRIGGERED = 0, - CONTINUOUS, - FORCED_CONTINUOUS, + FORCED_TRIGGERED = 1, + CONTINUOUS = 2, + FORCED_CONTINUOUS = 3, }; +#define IS_TRIGGERED(x) (!((x) & 2)) +#define IS_CONTINUOUS(x) ((x) & 2) + struct ina3221_chan_pdata { const char *rail_name; u32 warn_conf_limits; @@ -196,7 +200,7 @@ static int __locked_start_conversion(struct ina3221_chip *chip) { int ret, cvrf, trials = 0; - if (chip->mode == TRIGGERED) { + if (IS_TRIGGERED(chip->mode)) { ret = __locked_power_up_ina3221(chip, chip->pdata->trig_conf_data); @@ -227,7 +231,7 @@ static int __locked_end_conversion(struct ina3221_chip *chip) { int ret = 0; - if (chip->mode == TRIGGERED) + if (IS_TRIGGERED(chip->mode)) ret = __locked_power_down_ina3221(chip); return ret; @@ -265,7 +269,7 @@ static int ina3221_get_mode(struct ina3221_chip *chip, char *buf) int v; mutex_lock(&chip->mutex); - v = (chip->mode == TRIGGERED) ? 0 : 1; + v = (IS_TRIGGERED(chip->mode)) ? 0 : 1; mutex_unlock(&chip->mutex); return sprintf(buf, "%d\n", v); } @@ -282,14 +286,21 @@ static int ina3221_set_mode(struct ina3221_chip *chip, return -EINVAL; mutex_lock(&chip->mutex); - if (val != TRIGGERED) { + if (val > 0) { ret = __locked_power_up_ina3221(chip, chip->pdata->cont_conf_data); if (!ret) chip->mode = FORCED_CONTINUOUS; - } else if (chip->mode == FORCED_CONTINUOUS) { + } else if (val == 0) { + chip->mode = FORCED_TRIGGERED; + ret = __locked_power_down_ina3221(chip); + } else { if (chip->alert_enabled) { - chip->mode = CONTINUOUS; + if (IS_TRIGGERED(chip->mode)) + chip->mode = TRIGGERED; + else + chip->mode = CONTINUOUS; + /* evaluate the state */ cpufreq = cpufreq_quick_get(0); cpus = num_online_cpus(); ret = __locked_ina3221_switch_mode(chip, cpus, cpufreq); @@ -331,7 +342,7 @@ static int ina3221_get_channel_current(struct ina3221_chip *chip, mutex_lock(&chip->mutex); /* return 0 if INA is off */ - if (trigger && (chip->mode == TRIGGERED)) { + if (trigger && (IS_TRIGGERED(chip->mode))) { *current_ma = 0; goto exit; } @@ -358,7 +369,7 @@ static int ina3221_get_channel_power(struct ina3221_chip *chip, mutex_lock(&chip->mutex); - if (trigger && (chip->mode == TRIGGERED)) { + if (trigger && (IS_TRIGGERED(chip->mode))) { *power_mw = 0; goto exit; } @@ -539,6 +550,7 @@ static int __locked_ina3221_switch_mode(struct ina3221_chip *chip, } break; case FORCED_CONTINUOUS: + case FORCED_TRIGGERED: default: break; } @@ -991,7 +1003,8 @@ static int ina3221_suspend(struct device *dev) dev_err(dev, "INA can't be turned off: 0x%x\n", ret); goto error; } - chip->mode = TRIGGERED; + if (chip->mode == CONTINUOUS) + chip->mode = TRIGGERED; chip->is_suspended = 1; error: mutex_unlock(&chip->mutex); @@ -1005,9 +1018,14 @@ static int ina3221_resume(struct device *dev) int ret = 0; mutex_lock(&chip->mutex); - cpufreq = cpufreq_quick_get(0); - cpus = num_online_cpus(); - ret = __locked_ina3221_switch_mode(chip, cpus, cpufreq); + if (chip->mode == FORCED_CONTINUOUS) { + ret = __locked_power_up_ina3221(chip, + chip->pdata->cont_conf_data); + } else { + cpufreq = cpufreq_quick_get(0); + cpus = num_online_cpus(); + ret = __locked_ina3221_switch_mode(chip, cpus, cpufreq); + } if (ret < 0) dev_err(dev, "INA can't be turned off/on: 0x%x\n", ret); chip->is_suspended = 0; |