All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: linux-arm-kernel@lists.infradead.org
Subject: Re: [lm-sensors] [PATCH 4/5] hwmon: DNS323 rev C1 fan support
Date: Sat, 22 May 2010 11:00:43 +0000	[thread overview]
Message-ID: <1274526043.1931.144.camel@pasglop> (raw)
In-Reply-To: <1274525694.1931.142.camel@pasglop>

On Sat, 2010-05-22 at 20:54 +1000, Benjamin Herrenschmidt wrote:
> The hardware only supports 3 settings: off, slow and fast.
> 
> In order to have a chance to work with existing fan control systems,
> we emulate a PWM device with the following mapping:
> 
>    0.. 15  off		0 RPM input
>   16..127  slow	      100 RPM input
                        ^^^

Little typo in the changeset comment, I actually fake 400 RPM, which
sounds more realistic from a gut feeling of how the fan is going but
I haven't actually measured.

Cheers,
Ben.

>  128..255  fast      2000 RPM input
> 
> This provides something more/less working with fancontrol, though
> it does have a tendency to work by doing short bursts of "slow"
> speed every half a minute as it settles around my min temp. Not
> a big deal a specialized script could probably do better, or even
> tweaks to fancontrol config. At leats it should be safe.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: lm-sensors@lm-sensors.org
> ---
>  drivers/hwmon/Kconfig       |   12 ++
>  drivers/hwmon/Makefile      |    1 +
>  drivers/hwmon/dns323c-fan.c |  271 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 284 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/hwmon/dns323c-fan.c
> 
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 9be8e17..5f55735 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1087,6 +1087,18 @@ config SENSORS_MC13783_ADC
>          help
>            Support for the A/D converter on MC13783 PMIC.
>  
> +config SENSORS_DNS323C_FAN
> +       tristate "D-Link DNS323 rev C1 Fan"
> +       depends on MACH_DNS323
> +       help
> +         Support for the GPIO based fan control on the D-Link DNS323
> +	 HW revision C1. This exposes a pseudo pwm device with the
> +	 following values supported:
> +
> +	 	    0..15	: Fan off
> +		   16..127	: Fan on low speed
> +		  128..255	: Fan on high speed
> +	 
>  if ACPI
>  
>  comment "ACPI drivers"
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 4aa1a3d..15bcdef 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -100,6 +100,7 @@ obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
>  obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
>  obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
>  obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
> +obj-$(CONFIG_SENSORS_DNS323C_FAN)+= dns323c-fan.o
>  
>  ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
>  EXTRA_CFLAGS += -DDEBUG
> diff --git a/drivers/hwmon/dns323c-fan.c b/drivers/hwmon/dns323c-fan.c
> new file mode 100644
> index 0000000..4ae18d0
> --- /dev/null
> +++ b/drivers/hwmon/dns323c-fan.c
> @@ -0,0 +1,271 @@
> +/*
> + *  dns323c_fan - Driver for the D-LINK DNS-323 rev C1 fan control
> + *
> + *  Copyright 2010 Benjamin Herrenschmidt
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/gpio.h>
> +#include <linux/hwmon.h>
> +
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/gfp.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/sysfs.h>
> +#include <linux/platform_device.h>
> +
> +enum fan_speed {
> +	FAN_OFF,
> +	FAN_LOW	,
> +	FAN_FAST,
> +	FAN_FAST_LOCK,
> +};
> +
> +#define DNS323C_GPIO_FAN_BIT1		18
> +#define DNS323C_GPIO_FAN_BIT0		19
> +
> +struct dns323c_fan {
> +	struct device	*hwmon;
> +	struct mutex	lock;
> +	enum fan_speed	speed;
> +};
> +
> +static void __set_fan_speed(struct dns323c_fan *fan, enum fan_speed speed)
> +{
> +	if (speed = fan->speed)
> +		return;
> +
> +	switch(speed) {
> +	case FAN_OFF:
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT1, 0);
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT0, 0);
> +		break;
> +	case FAN_LOW:
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT1, 0);
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT0, 1);
> +		break;
> +	default:
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT0, 0);
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT1, 1);
> +	};
> +	fan->speed = speed;
> +}
> +
> +static ssize_t show_name(struct device *dev, struct device_attribute *da,
> +			   char *buf)
> +{
> +	return sprintf(buf, "dns323c-fan\n");
> +}
> +
> +static ssize_t show_pwm(struct device *dev, struct device_attribute *da,
> +			char *buf)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	int pseudo_pwm;
> +
> +	switch(fan->speed) {
> +	case FAN_OFF:
> +		pseudo_pwm = 0;
> +		break;
> +	case FAN_LOW:
> +		pseudo_pwm = 63;
> +		break;
> +	default:
> +		pseudo_pwm = 255;
> +	}
> +	return sprintf(buf, "%d\n", pseudo_pwm);
> +}
> +
> +static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
> +		       const char *buf, size_t count)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	enum fan_speed speed;
> +	unsigned long val;
> +
> +	if (strict_strtoul(buf, 10, &val))
> +		return -EINVAL;
> +	if (fan->speed = FAN_FAST_LOCK)
> +		return count;
> +
> +	mutex_lock(&fan->lock);
> +	if (val < 16)
> +		speed = FAN_OFF;
> +	else if (val < 128)
> +		speed = FAN_LOW;
> +	else
> +		speed = FAN_FAST;
> +	__set_fan_speed(fan, speed);
> +	mutex_unlock(&fan->lock);
> +
> +	return count;
> +}
> +
> +static ssize_t show_pwm_en(struct device *dev, struct device_attribute *da,
> +			   char *buf)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +
> +	if (fan->speed = FAN_FAST_LOCK)
> +		return sprintf(buf, "0\n");
> +	else
> +		return sprintf(buf, "1\n");
> +}
> +
> +static ssize_t set_pwm_en(struct device *dev, struct device_attribute *da,
> +			  const char *buf, size_t count)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	enum fan_speed speed;
> +	unsigned long val;
> +
> +	if (strict_strtoul(buf, 10, &val))
> +		return -EINVAL;
> +	if (val != 0 && val != 1)
> +		return -EINVAL;
> +
> +	mutex_lock(&fan->lock);
> +	if (val = 0 && fan->speed != FAN_FAST_LOCK)
> +		speed = FAN_FAST_LOCK;
> +	else if (val != 0 && fan->speed = FAN_FAST_LOCK)
> +		speed = FAN_FAST;
> +	else
> +		speed = fan->speed;
> +	__set_fan_speed(fan, speed);
> +	mutex_unlock(&fan->lock);
> +
> +	return count;
> +}
> +
> +static ssize_t show_fake_rpm(struct device *dev, struct device_attribute *da,
> +			     char *buf)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	int pseudo_rpm;
> +
> +	switch(fan->speed) {
> +	case FAN_OFF:
> +		pseudo_rpm = 0;
> +		break;
> +	case FAN_LOW:
> +		pseudo_rpm = 400;
> +		break;
> +	default:
> +		pseudo_rpm = 2000;
> +	}
> +	return sprintf(buf, "%d\n", pseudo_rpm);
> +}
> +
> +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
> +static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm);
> +static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_en, set_pwm_en);
> +static DEVICE_ATTR(fan1_input, S_IRUGO, show_fake_rpm, NULL);
> +
> +static int dns323c_fan_probe(struct platform_device *pdev)
> +{
> +	struct dns323c_fan *fan = NULL;
> +	int ret = -ENXIO;
> +
> +	/* Get the GPIOs */
> +	if (gpio_request(DNS323C_GPIO_FAN_BIT0, "FAN0") != 0) {
> +		pr_err("dns323c_fan: Failed to request fan GPIO 0 !\n");
> +		return -ENXIO;
> +	}
> +	if (gpio_request(DNS323C_GPIO_FAN_BIT1, "FAN1") != 0) {
> +		pr_err("dns323c_fan: Failed to request fan GPIO 1 !\n");
> +		goto err_gpio;
> +	}
> +
> +	/* Set directions to output and medium speed. We write bit 1 first
> +	 * since it contains 0 to avoid having a transitory 11 state which
> +	 * isn't supported
> +	 */
> +	gpio_direction_output(DNS323C_GPIO_FAN_BIT1, 0);
> +	gpio_direction_output(DNS323C_GPIO_FAN_BIT0, 1);
> +
> +	/* Grab some memory for our state */
> +	fan = kzalloc(sizeof(struct dns323c_fan), GFP_KERNEL);
> +	if (!fan) {
> +		ret = -ENOMEM;
> +		goto err_alloc;
> +	}
> +	fan->speed = FAN_LOW;
> +	mutex_init(&fan->lock);
> +	platform_set_drvdata(pdev, fan);
> +
> +	ret = device_create_file(&pdev->dev, &dev_attr_name);
> +	ret |= device_create_file(&pdev->dev, &dev_attr_pwm1);
> +	ret |= device_create_file(&pdev->dev, &dev_attr_pwm1_enable);
> +	ret |= device_create_file(&pdev->dev, &dev_attr_fan1_input);
> +	if (ret)
> +		goto err_file;
> +
> +	fan->hwmon = hwmon_device_register(&pdev->dev);
> +	if (IS_ERR(fan->hwmon)) {
> +		ret = PTR_ERR(fan->hwmon);
> +		goto err_dev;
> +	}
> +	return 0;
> +
> + err_dev:
> +	device_remove_file(&pdev->dev, &dev_attr_name);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1_enable);
> +	device_remove_file(&pdev->dev, &dev_attr_fan1_input);
> + err_file:
> +	kfree(fan);
> + err_alloc:
> +	gpio_free(DNS323C_GPIO_FAN_BIT1);
> + err_gpio:
> +	gpio_free(DNS323C_GPIO_FAN_BIT0);
> +	return ret;
> +}
> +
> +static int __devexit dns323c_fan_remove(struct platform_device *pdev)
> +{
> +	struct dns323c_fan *fan = platform_get_drvdata(pdev);
> +
> +	hwmon_device_unregister(fan->hwmon);
> +	device_remove_file(&pdev->dev, &dev_attr_name);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1_enable);
> +	device_remove_file(&pdev->dev, &dev_attr_fan1_input);
> +	kfree(fan);
> +	gpio_free(DNS323C_GPIO_FAN_BIT1);
> +	gpio_free(DNS323C_GPIO_FAN_BIT0);
> +	return 0;
> +}
> +
> +static struct platform_driver dns323c_fan_driver = {
> +	.probe = dns323c_fan_probe,
> +	.remove = __devexit_p(dns323c_fan_remove),
> +	.driver = {
> +		.name = "dns323c-fan",
> +		.owner = THIS_MODULE,
> +	},
> +};
> +
> +static int __init dns323c_fan_init(void)
> +{
> +	return platform_driver_register(&dns323c_fan_driver);
> +}
> +
> +static void __exit dns323c_fan_exit(void)
> +{
> +	platform_driver_unregister(&dns323c_fan_driver);
> +}
> +
> +MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
> +MODULE_DESCRIPTION("DNS323 RevC1 Fan control");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:dns323c-fan");
> +
> +module_init(dns323c_fan_init);
> +module_exit(dns323c_fan_exit);
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

WARNING: multiple messages have this Message-ID (diff)
From: benh@kernel.crashing.org (Benjamin Herrenschmidt)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 4/5] hwmon: DNS323 rev C1 fan support
Date: Sat, 22 May 2010 21:00:43 +1000	[thread overview]
Message-ID: <1274526043.1931.144.camel@pasglop> (raw)
In-Reply-To: <1274525694.1931.142.camel@pasglop>

On Sat, 2010-05-22 at 20:54 +1000, Benjamin Herrenschmidt wrote:
> The hardware only supports 3 settings: off, slow and fast.
> 
> In order to have a chance to work with existing fan control systems,
> we emulate a PWM device with the following mapping:
> 
>    0.. 15  off		0 RPM input
>   16..127  slow	      100 RPM input
                        ^^^

Little typo in the changeset comment, I actually fake 400 RPM, which
sounds more realistic from a gut feeling of how the fan is going but
I haven't actually measured.

Cheers,
Ben.

>  128..255  fast      2000 RPM input
> 
> This provides something more/less working with fancontrol, though
> it does have a tendency to work by doing short bursts of "slow"
> speed every half a minute as it settles around my min temp. Not
> a big deal a specialized script could probably do better, or even
> tweaks to fancontrol config. At leats it should be safe.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> CC: lm-sensors at lm-sensors.org
> ---
>  drivers/hwmon/Kconfig       |   12 ++
>  drivers/hwmon/Makefile      |    1 +
>  drivers/hwmon/dns323c-fan.c |  271 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 284 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/hwmon/dns323c-fan.c
> 
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 9be8e17..5f55735 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1087,6 +1087,18 @@ config SENSORS_MC13783_ADC
>          help
>            Support for the A/D converter on MC13783 PMIC.
>  
> +config SENSORS_DNS323C_FAN
> +       tristate "D-Link DNS323 rev C1 Fan"
> +       depends on MACH_DNS323
> +       help
> +         Support for the GPIO based fan control on the D-Link DNS323
> +	 HW revision C1. This exposes a pseudo pwm device with the
> +	 following values supported:
> +
> +	 	    0..15	: Fan off
> +		   16..127	: Fan on low speed
> +		  128..255	: Fan on high speed
> +	 
>  if ACPI
>  
>  comment "ACPI drivers"
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index 4aa1a3d..15bcdef 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -100,6 +100,7 @@ obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
>  obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
>  obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
>  obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
> +obj-$(CONFIG_SENSORS_DNS323C_FAN)+= dns323c-fan.o
>  
>  ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
>  EXTRA_CFLAGS += -DDEBUG
> diff --git a/drivers/hwmon/dns323c-fan.c b/drivers/hwmon/dns323c-fan.c
> new file mode 100644
> index 0000000..4ae18d0
> --- /dev/null
> +++ b/drivers/hwmon/dns323c-fan.c
> @@ -0,0 +1,271 @@
> +/*
> + *  dns323c_fan - Driver for the D-LINK DNS-323 rev C1 fan control
> + *
> + *  Copyright 2010 Benjamin Herrenschmidt
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/gpio.h>
> +#include <linux/hwmon.h>
> +
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/gfp.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/sysfs.h>
> +#include <linux/platform_device.h>
> +
> +enum fan_speed {
> +	FAN_OFF,
> +	FAN_LOW	,
> +	FAN_FAST,
> +	FAN_FAST_LOCK,
> +};
> +
> +#define DNS323C_GPIO_FAN_BIT1		18
> +#define DNS323C_GPIO_FAN_BIT0		19
> +
> +struct dns323c_fan {
> +	struct device	*hwmon;
> +	struct mutex	lock;
> +	enum fan_speed	speed;
> +};
> +
> +static void __set_fan_speed(struct dns323c_fan *fan, enum fan_speed speed)
> +{
> +	if (speed == fan->speed)
> +		return;
> +
> +	switch(speed) {
> +	case FAN_OFF:
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT1, 0);
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT0, 0);
> +		break;
> +	case FAN_LOW:
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT1, 0);
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT0, 1);
> +		break;
> +	default:
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT0, 0);
> +		gpio_set_value(DNS323C_GPIO_FAN_BIT1, 1);
> +	};
> +	fan->speed = speed;
> +}
> +
> +static ssize_t show_name(struct device *dev, struct device_attribute *da,
> +			   char *buf)
> +{
> +	return sprintf(buf, "dns323c-fan\n");
> +}
> +
> +static ssize_t show_pwm(struct device *dev, struct device_attribute *da,
> +			char *buf)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	int pseudo_pwm;
> +
> +	switch(fan->speed) {
> +	case FAN_OFF:
> +		pseudo_pwm = 0;
> +		break;
> +	case FAN_LOW:
> +		pseudo_pwm = 63;
> +		break;
> +	default:
> +		pseudo_pwm = 255;
> +	}
> +	return sprintf(buf, "%d\n", pseudo_pwm);
> +}
> +
> +static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
> +		       const char *buf, size_t count)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	enum fan_speed speed;
> +	unsigned long val;
> +
> +	if (strict_strtoul(buf, 10, &val))
> +		return -EINVAL;
> +	if (fan->speed == FAN_FAST_LOCK)
> +		return count;
> +
> +	mutex_lock(&fan->lock);
> +	if (val < 16)
> +		speed = FAN_OFF;
> +	else if (val < 128)
> +		speed = FAN_LOW;
> +	else
> +		speed = FAN_FAST;
> +	__set_fan_speed(fan, speed);
> +	mutex_unlock(&fan->lock);
> +
> +	return count;
> +}
> +
> +static ssize_t show_pwm_en(struct device *dev, struct device_attribute *da,
> +			   char *buf)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +
> +	if (fan->speed == FAN_FAST_LOCK)
> +		return sprintf(buf, "0\n");
> +	else
> +		return sprintf(buf, "1\n");
> +}
> +
> +static ssize_t set_pwm_en(struct device *dev, struct device_attribute *da,
> +			  const char *buf, size_t count)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	enum fan_speed speed;
> +	unsigned long val;
> +
> +	if (strict_strtoul(buf, 10, &val))
> +		return -EINVAL;
> +	if (val != 0 && val != 1)
> +		return -EINVAL;
> +
> +	mutex_lock(&fan->lock);
> +	if (val == 0 && fan->speed != FAN_FAST_LOCK)
> +		speed = FAN_FAST_LOCK;
> +	else if (val != 0 && fan->speed == FAN_FAST_LOCK)
> +		speed = FAN_FAST;
> +	else
> +		speed = fan->speed;
> +	__set_fan_speed(fan, speed);
> +	mutex_unlock(&fan->lock);
> +
> +	return count;
> +}
> +
> +static ssize_t show_fake_rpm(struct device *dev, struct device_attribute *da,
> +			     char *buf)
> +{
> +	struct dns323c_fan *fan = dev_get_drvdata(dev);
> +	int pseudo_rpm;
> +
> +	switch(fan->speed) {
> +	case FAN_OFF:
> +		pseudo_rpm = 0;
> +		break;
> +	case FAN_LOW:
> +		pseudo_rpm = 400;
> +		break;
> +	default:
> +		pseudo_rpm = 2000;
> +	}
> +	return sprintf(buf, "%d\n", pseudo_rpm);
> +}
> +
> +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
> +static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm);
> +static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_en, set_pwm_en);
> +static DEVICE_ATTR(fan1_input, S_IRUGO, show_fake_rpm, NULL);
> +
> +static int dns323c_fan_probe(struct platform_device *pdev)
> +{
> +	struct dns323c_fan *fan = NULL;
> +	int ret = -ENXIO;
> +
> +	/* Get the GPIOs */
> +	if (gpio_request(DNS323C_GPIO_FAN_BIT0, "FAN0") != 0) {
> +		pr_err("dns323c_fan: Failed to request fan GPIO 0 !\n");
> +		return -ENXIO;
> +	}
> +	if (gpio_request(DNS323C_GPIO_FAN_BIT1, "FAN1") != 0) {
> +		pr_err("dns323c_fan: Failed to request fan GPIO 1 !\n");
> +		goto err_gpio;
> +	}
> +
> +	/* Set directions to output and medium speed. We write bit 1 first
> +	 * since it contains 0 to avoid having a transitory 11 state which
> +	 * isn't supported
> +	 */
> +	gpio_direction_output(DNS323C_GPIO_FAN_BIT1, 0);
> +	gpio_direction_output(DNS323C_GPIO_FAN_BIT0, 1);
> +
> +	/* Grab some memory for our state */
> +	fan = kzalloc(sizeof(struct dns323c_fan), GFP_KERNEL);
> +	if (!fan) {
> +		ret = -ENOMEM;
> +		goto err_alloc;
> +	}
> +	fan->speed = FAN_LOW;
> +	mutex_init(&fan->lock);
> +	platform_set_drvdata(pdev, fan);
> +
> +	ret = device_create_file(&pdev->dev, &dev_attr_name);
> +	ret |= device_create_file(&pdev->dev, &dev_attr_pwm1);
> +	ret |= device_create_file(&pdev->dev, &dev_attr_pwm1_enable);
> +	ret |= device_create_file(&pdev->dev, &dev_attr_fan1_input);
> +	if (ret)
> +		goto err_file;
> +
> +	fan->hwmon = hwmon_device_register(&pdev->dev);
> +	if (IS_ERR(fan->hwmon)) {
> +		ret = PTR_ERR(fan->hwmon);
> +		goto err_dev;
> +	}
> +	return 0;
> +
> + err_dev:
> +	device_remove_file(&pdev->dev, &dev_attr_name);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1_enable);
> +	device_remove_file(&pdev->dev, &dev_attr_fan1_input);
> + err_file:
> +	kfree(fan);
> + err_alloc:
> +	gpio_free(DNS323C_GPIO_FAN_BIT1);
> + err_gpio:
> +	gpio_free(DNS323C_GPIO_FAN_BIT0);
> +	return ret;
> +}
> +
> +static int __devexit dns323c_fan_remove(struct platform_device *pdev)
> +{
> +	struct dns323c_fan *fan = platform_get_drvdata(pdev);
> +
> +	hwmon_device_unregister(fan->hwmon);
> +	device_remove_file(&pdev->dev, &dev_attr_name);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1);
> +	device_remove_file(&pdev->dev, &dev_attr_pwm1_enable);
> +	device_remove_file(&pdev->dev, &dev_attr_fan1_input);
> +	kfree(fan);
> +	gpio_free(DNS323C_GPIO_FAN_BIT1);
> +	gpio_free(DNS323C_GPIO_FAN_BIT0);
> +	return 0;
> +}
> +
> +static struct platform_driver dns323c_fan_driver = {
> +	.probe = dns323c_fan_probe,
> +	.remove = __devexit_p(dns323c_fan_remove),
> +	.driver = {
> +		.name = "dns323c-fan",
> +		.owner = THIS_MODULE,
> +	},
> +};
> +
> +static int __init dns323c_fan_init(void)
> +{
> +	return platform_driver_register(&dns323c_fan_driver);
> +}
> +
> +static void __exit dns323c_fan_exit(void)
> +{
> +	platform_driver_unregister(&dns323c_fan_driver);
> +}
> +
> +MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
> +MODULE_DESCRIPTION("DNS323 RevC1 Fan control");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:dns323c-fan");
> +
> +module_init(dns323c_fan_init);
> +module_exit(dns323c_fan_exit);
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2010-05-22 11:00 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-22 10:54 [lm-sensors] [PATCH 4/5] hwmon: DNS323 rev C1 fan support Benjamin Herrenschmidt
2010-05-22 10:54 ` Benjamin Herrenschmidt
2010-05-22 11:00 ` Benjamin Herrenschmidt [this message]
2010-05-22 11:00   ` Benjamin Herrenschmidt
2010-10-13 11:59 ` [lm-sensors] " Simon Guinot
2010-10-13 11:59   ` Simon Guinot
2010-10-13 16:34   ` [lm-sensors] " Guenter Roeck
2010-10-13 16:34     ` Guenter Roeck
2010-10-17 15:40     ` Simon Guinot
2010-10-17 15:40       ` Simon Guinot
2010-10-17 15:50       ` [lm-sensors] [PATCH 1/2] hwmon: add generic GPIO fan driver Simon Guinot
2010-10-17 15:50         ` Simon Guinot
2010-10-17 15:50         ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Simon Guinot
2010-10-17 15:50           ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Simon Guinot
2010-10-22  1:53           ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Guenter Roeck
2010-10-22  1:53             ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Guenter Roeck
2010-10-22  2:08             ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Nicolas Pitre
2010-10-22  2:08               ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Nicolas Pitre
2010-10-22  4:30               ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Guenter Roeck
2010-10-22  4:30                 ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Guenter Roeck
2010-10-22  9:29                 ` [lm-sensors] [PATCH] [ARM] Kirkwood: add fan support for Network Simon Guinot
2010-10-22  9:29                   ` [PATCH] [ARM] Kirkwood: add fan support for Network Space Max v2 Simon Guinot
2010-10-22  9:59                   ` [lm-sensors] [PATCH] [ARM] Kirkwood: add fan support for Guenter Roeck
2010-10-22  9:59                     ` [PATCH] [ARM] Kirkwood: add fan support for Network Space Max v2 Guenter Roeck
2010-10-22  8:27               ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Simon Guinot
2010-10-22  8:27                 ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Simon Guinot
2010-10-22  9:58                 ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Guenter Roeck
2010-10-22  9:58                   ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Guenter Roeck
2010-10-22 18:39                 ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Guenter Roeck
2010-10-22 18:39                   ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Guenter Roeck
2010-10-22 18:50                   ` [lm-sensors] [PATCH 2/2] [ARM] Kirkwood: add fan support for Nicolas Pitre
2010-10-22 18:50                     ` [PATCH 2/2] [ARM] Kirkwood: add fan support for Network Space Max v2 Nicolas Pitre
2010-10-18 16:08         ` [lm-sensors] [PATCH 1/2] hwmon: add generic GPIO fan driver Guenter Roeck
2010-10-18 16:08           ` Guenter Roeck
2010-10-18 18:00           ` [lm-sensors] " Chris Moore
2010-10-18 18:00             ` Chris Moore
2010-10-18 18:35             ` [lm-sensors] " Guenter Roeck
2010-10-18 18:35               ` Guenter Roeck
2010-10-18 20:36           ` [lm-sensors] " Simon Guinot
2010-10-18 20:36             ` Simon Guinot
2010-10-18 20:50             ` [lm-sensors] " Guenter Roeck
2010-10-18 20:50               ` Guenter Roeck
2010-10-19 11:46               ` [lm-sensors] " Simon Guinot
2010-10-19 11:46                 ` Simon Guinot
2010-10-19 14:52                 ` [lm-sensors] " Guenter Roeck
2010-10-19 14:52                   ` Guenter Roeck
2010-10-19  6:52             ` [lm-sensors] " Guenter Roeck
2010-10-19  6:52               ` Guenter Roeck
2010-10-19  8:36               ` [lm-sensors] " Simon Guinot
2010-10-19  8:36                 ` Simon Guinot
2010-10-19 15:15                 ` [lm-sensors] " Guenter Roeck
2010-10-19 15:15                   ` Guenter Roeck
2010-10-19 19:30                   ` [lm-sensors] " Simon Guinot
2010-10-19 19:30                     ` Simon Guinot
2010-10-21 20:07           ` [lm-sensors] " Simon Guinot
2010-10-21 20:07             ` Simon Guinot
2010-10-21 20:26             ` [lm-sensors] " Guenter Roeck
2010-10-21 20:26               ` Guenter Roeck
2010-10-19 22:03         ` [lm-sensors] " Guenter Roeck
2010-10-19 22:03           ` Guenter Roeck
2010-10-20  0:19           ` [lm-sensors] " Simon Guinot
2010-10-20  0:19             ` Simon Guinot
2010-10-20  0:50             ` [lm-sensors] " Guenter Roeck
2010-10-20  0:50               ` Guenter Roeck
2010-10-20  7:59               ` [lm-sensors] " Simon Guinot
2010-10-20  7:59                 ` Simon Guinot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1274526043.1931.144.camel@pasglop \
    --to=benh@kernel.crashing.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.