ODROID-COMMON: hwmon: (pwm-fan) add fan pwm1_enable attribute

This patch adds to new attribute 'pwm1_enable' to change the fan speed
control method as documented in 'Documentation/hwmon/sysfs-interface'.

Signed-off-by: Dongjin Kim <tobetter@gmail.com>
Change-Id: I19094d60e928d6c3ce226d319e75a35ecbd3ae52
This commit is contained in:
Dongjin Kim
2020-11-25 05:01:49 +09:00
committed by vl
parent 9fd85caa8e
commit 84be19d25c

View File

@@ -48,6 +48,7 @@ struct pwm_fan_ctx {
struct notifier_block thermal_nb;
struct thermal_trips *thermal_trips;
bool thermal_notifier_is_ok;
int enable;
};
/* This handler assumes self resetting edge triggered interrupt. */
@@ -85,6 +86,10 @@ static int __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)
struct pwm_state state = { };
mutex_lock(&ctx->lock);
if (ctx->enable == 0)
pwm = MAX_PWM;
if (ctx->pwm_value == pwm)
goto exit_set_pwm_err;
@@ -194,9 +199,41 @@ static ssize_t cooll_show(struct device *dev,
static SENSOR_DEVICE_ATTR_RW(fan_speed, cooll, 0);
static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", ctx->enable);
}
static ssize_t enable_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
int err;
unsigned long val;
err = kstrtoul(buf, 10, &val);
if (err)
return err;
mutex_lock(&ctx->lock);
ctx->enable = val;
mutex_unlock(&ctx->lock);
err = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[ctx->pwm_fan_state]);
return err ? err : count;
}
static SENSOR_DEVICE_ATTR_RW(pwm1_enable, enable, 0);
static struct attribute *pwm_fan_attrs[] = {
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_fan_speed.dev_attr.attr,
NULL,
};
@@ -255,7 +292,7 @@ static int
pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct pwm_fan_ctx *ctx = cdev->devdata;
int ret;
int ret = 0;
if (!ctx || (state > ctx->pwm_fan_max_state))
return -EINVAL;
@@ -263,10 +300,12 @@ pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
if (state == ctx->pwm_fan_state)
return 0;
ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]);
if (ret) {
dev_err(&cdev->device, "Cannot set pwm!\n");
return ret;
if (ctx->enable >= 2) {
ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]);
if (ret) {
dev_err(&cdev->device, "Cannot set pwm!\n");
return ret;
}
}
ctx->pwm_fan_state = state;
@@ -443,6 +482,8 @@ static int pwm_fan_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);
ctx->enable = 2;
ctx->irq = platform_get_irq_optional(pdev, 0);
if (ctx->irq == -EPROBE_DEFER)
return ctx->irq;