summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorTimo Alho <talho@nvidia.com>2014-04-07 14:19:41 +0300
committerTimo Alho <talho@nvidia.com>2014-04-09 03:47:28 -0700
commit017a1d491ccd08a6a49cdf4f5791654ba8f49c12 (patch)
tree588335eee53b393d25f7ab4a1c46fac18a7b60c1 /drivers/staging
parent266d7105717a991f52e4141edbe8ab402ceacad9 (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.c46
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;