diff mbox

[V5,1/2] introduce ALS sysfs class

Message ID 1251706028.3483.160.camel@rzhang-dt (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Zhang, Rui Aug. 31, 2009, 8:07 a.m. UTC
Introduce ALS sysfs class.

ALS sysfs class provides a standard sysfs interface for
Ambient Light Sensor devices.

please read Documentation/ABI/testing/sysfs-class-als for
detailed sysfs designs.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 Documentation/ABI/testing/sysfs-class-als |   32 ++++
 MAINTAINERS                               |    6 
 drivers/Kconfig                           |    2 
 drivers/Makefile                          |    1 
 drivers/als/Kconfig                       |   10 +
 drivers/als/Makefile                      |    5 
 drivers/als/als_sys.c                     |  220 ++++++++++++++++++++++++++++++
 include/linux/als_sys.h                   |   55 +++++++
 8 files changed, 331 insertions(+)



--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Pavel Machek Aug. 31, 2009, 8:34 a.m. UTC | #1
Hi!

> @@ -0,0 +1,32 @@
> +What:		/sys/class/als/als[0-N]/desc
> +Date:		Aug. 2009
> +KernelVersion:	2.6.32
> +Contact:	Zhang Rui <rui.zhang@intel.com>
> +Description:	Strings which descibes the current Ambient Light Sensor
> +		device. This is given by native ALS driver as part of
> +		registration. e.g: "acpi_als" for ACPI ALS devices.
> +		RO

Normal way to do that (backlight class does it, for example) is to
have acpi_als instead of als0, and get rid of desc field.
									Pavel
Zhang, Rui Aug. 31, 2009, 8:48 a.m. UTC | #2
On Mon, 2009-08-31 at 16:34 +0800, Pavel Machek wrote:
> Hi!
> 
> > @@ -0,0 +1,32 @@
> > +What:		/sys/class/als/als[0-N]/desc
> > +Date:		Aug. 2009
> > +KernelVersion:	2.6.32
> > +Contact:	Zhang Rui <rui.zhang@intel.com>
> > +Description:	Strings which descibes the current Ambient Light Sensor
> > +		device. This is given by native ALS driver as part of
> > +		registration. e.g: "acpi_als" for ACPI ALS devices.
> > +		RO
> 
> Normal way to do that (backlight class does it, for example) is to
> have acpi_als instead of als0, and get rid of desc field.

IMO, both are okay, hard to say which is preferred.
Other sysfs classes like scsi_host, hwmon, input use this as well.
and you don't have a really strong objection to this, right? :)

thanks,
rui

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek Aug. 31, 2009, 9:02 a.m. UTC | #3
On Mon 2009-08-31 16:48:57, Zhang Rui wrote:
> On Mon, 2009-08-31 at 16:34 +0800, Pavel Machek wrote:
> > Hi!
> > 
> > > @@ -0,0 +1,32 @@
> > > +What:		/sys/class/als/als[0-N]/desc
> > > +Date:		Aug. 2009
> > > +KernelVersion:	2.6.32
> > > +Contact:	Zhang Rui <rui.zhang@intel.com>
> > > +Description:	Strings which descibes the current Ambient Light Sensor
> > > +		device. This is given by native ALS driver as part of
> > > +		registration. e.g: "acpi_als" for ACPI ALS devices.
> > > +		RO
> > 
> > Normal way to do that (backlight class does it, for example) is to
> > have acpi_als instead of als0, and get rid of desc field.
> 
> IMO, both are okay, hard to say which is preferred.
> Other sysfs classes like scsi_host, hwmon, input use this as well.
> and you don't have a really strong objection to this, right? :)

Actually I do. Inventing nonsensical als17 name, then having helpful
desc explaining it is acpi_als is pretty ugly...
									Pavel
diff mbox

Patch

Index: linux-2.6/drivers/Kconfig
===================================================================
--- linux-2.6.orig/drivers/Kconfig
+++ linux-2.6/drivers/Kconfig
@@ -62,6 +62,8 @@  source "drivers/power/Kconfig"
 
 source "drivers/hwmon/Kconfig"
 
+source "drivers/als/Kconfig"
+
 source "drivers/thermal/Kconfig"
 
 source "drivers/watchdog/Kconfig"
Index: linux-2.6/drivers/Makefile
===================================================================
--- linux-2.6.orig/drivers/Makefile
+++ linux-2.6/drivers/Makefile
@@ -76,6 +76,7 @@  obj-$(CONFIG_PPS)		+= pps/
 obj-$(CONFIG_W1)		+= w1/
 obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
+obj-$(CONFIG_ALS)		+= als/
 obj-$(CONFIG_THERMAL)		+= thermal/
 obj-$(CONFIG_WATCHDOG)		+= watchdog/
 obj-$(CONFIG_PHONE)		+= telephony/
Index: linux-2.6/drivers/als/Kconfig
===================================================================
--- /dev/null
+++ linux-2.6/drivers/als/Kconfig
@@ -0,0 +1,10 @@ 
+#
+# Ambient Light Sensor sysfs device configuration
+#
+
+menuconfig ALS
+	tristate "Ambient Light Sensor sysfs device"
+	help
+	  This framework provides a generic sysfs interface for
+	  Ambient Light Sensor devices.
+	  If you want this support, you should say Y or M here.
Index: linux-2.6/drivers/als/Makefile
===================================================================
--- /dev/null
+++ linux-2.6/drivers/als/Makefile
@@ -0,0 +1,5 @@ 
+#
+# Makefile for Ambient Light Sensor device drivers.
+#
+
+obj-$(CONFIG_ALS)		+= als_sys.o
Index: linux-2.6/drivers/als/als_sys.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/als/als_sys.c
@@ -0,0 +1,220 @@ 
+/*
+ *  als_sys.c - Ambient Light Sensor Sysfs support.
+ *
+ *  Copyright (C) 2009 Intel Corp
+ *  Copyright (C) 2009 Zhang Rui <rui.zhang@intel.com>
+ *
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/als_sys.h>
+
+MODULE_AUTHOR("Zhang Rui");
+MODULE_DESCRIPTION("Ambient Light Sensor sysfs support");
+MODULE_LICENSE("GPL");
+
+static int als_get_adjustment(struct als_device *, int, int *);
+
+/* sys I/F for Ambient Light Sensor */
+
+#define to_als_device(dev) container_of(dev, struct als_device, device)
+
+static ssize_t
+desc_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct als_device *als = to_als_device(dev);
+
+	return sprintf(buf, "%s\n", als->desc ? als->desc : "N/A");
+}
+
+static ssize_t
+illuminance_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct als_device *als = to_als_device(dev);
+	int illuminance;
+	int result;
+
+	result = als->ops->get_illuminance(als, &illuminance);
+	if (result)
+		return result;
+
+	if (!illuminance)
+		return sprintf(buf, "Illuminance below the supported range\n");
+	else if (illuminance == -1)
+		return sprintf(buf, "Illuminance above the supported range\n");
+	else if (illuminance < -1)
+		return -ERANGE;
+	else
+		return sprintf(buf, "%d\n", illuminance);
+}
+
+static ssize_t
+adjustment_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct als_device *als = to_als_device(dev);
+	int illuminance, adjustment;
+	int result;
+
+	result = als->ops->get_illuminance(als, &illuminance);
+	if (result)
+		return result;
+
+	if (illuminance < 0 && illuminance != -1)
+		return sprintf(buf, "Current illuminance invalid\n");
+
+	result = als_get_adjustment(als, illuminance, &adjustment);
+	if (result)
+		return result;
+
+	return sprintf(buf, "%d%%\n", adjustment);
+}
+
+static struct device_attribute als_attrs[] = {
+	__ATTR(desc, 0444, desc_show, NULL),
+	__ATTR(illuminance, 0444, illuminance_show, NULL),
+	__ATTR(display_adjustment, 0444, adjustment_show, NULL),
+	__ATTR_NULL,
+};
+
+static void als_release(struct device *dev)
+{
+	struct als_device *als = to_als_device(dev);
+
+	kfree(als->desc);
+	kfree(als);
+}
+
+static struct class als_class = {
+	.name = "als",
+	.dev_release = als_release,
+	.dev_attrs = als_attrs,
+};
+
+static int als_get_adjustment(struct als_device *als, int illuminance,
+			      int *adjustment)
+{
+	int lux_high, lux_low, adj_high, adj_low;
+	int i;
+
+	if (!als->mappings)
+		return -EINVAL;
+
+	if (illuminance == -1
+	    || illuminance > als->mappings[als->count].illuminance)
+		illuminance = als->mappings[als->count].illuminance;
+	else if (illuminance < als->mappings[0].illuminance)
+		illuminance = als->mappings[0].illuminance;
+
+	for (i = 0; i < als->count; i++) {
+		if (illuminance == als->mappings[i].illuminance) {
+			*adjustment = als->mappings[i].adjustment;
+			return 0;
+		}
+
+		if (illuminance > als->mappings[i].illuminance)
+			continue;
+
+		lux_high = als->mappings[i].illuminance;
+		lux_low = als->mappings[i - 1].illuminance;
+		adj_high = als->mappings[i].adjustment;
+		adj_low = als->mappings[i - 1].adjustment;
+
+		*adjustment =
+		    ((adj_high - adj_low) / (lux_high -
+					     lux_low)) * (illuminance -
+							  lux_low) + adj_low;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+/**
+ * als_device_register - register a new Ambient Light Sensor class device
+ * @ops:	standard ALS devices callbacks.
+ * @devdata:	device private data.
+ */
+struct als_device *als_device_register(struct als_device_ops *ops,
+				       char *desc, void *devdata)
+{
+	struct als_device *als;
+	static int als_id;
+	int result = -ENOMEM;
+
+	if (!ops || !ops->get_illuminance)
+		return ERR_PTR(-EINVAL);
+
+	als = kzalloc(sizeof(struct als_device), GFP_KERNEL);
+	if (!als)
+		return ERR_PTR(-ENOMEM);
+
+	als->ops = ops;
+	als->device.class = &als_class;
+	als->devdata = devdata;
+	als->id = als_id++;
+	if (desc) {
+		als->desc = kzalloc(strlen(desc), GFP_KERNEL);
+		if (!als->desc)
+			goto err;
+		strcpy(als->desc, desc);
+	}
+	dev_set_name(&als->device, "als%d", als->id);
+	result = device_register(&als->device);
+	if (result)
+		goto err;
+
+	if (ops->update_mappings) {
+		result = ops->update_mappings(als);
+		if (result) {
+			device_unregister(&als->device);
+			goto err;
+		}
+	}
+	return als;
+
+err:
+	kfree(als->desc);
+	kfree(als);
+	return ERR_PTR(result);
+}
+EXPORT_SYMBOL(als_device_register);
+
+/**
+ * als_device_unregister - removes the registered ALS device
+ * @als:	the ALS device to remove.
+ */
+void als_device_unregister(struct als_device *als)
+{
+	device_unregister(&als->device);
+}
+EXPORT_SYMBOL(als_device_unregister);
+
+static int __init als_init(void)
+{
+	return class_register(&als_class);
+}
+
+static void __exit als_exit(void)
+{
+	class_unregister(&als_class);
+}
+
+subsys_initcall(als_init);
+module_exit(als_exit);
Index: linux-2.6/include/linux/als_sys.h
===================================================================
--- /dev/null
+++ linux-2.6/include/linux/als_sys.h
@@ -0,0 +1,55 @@ 
+/*
+ *  als.h
+ *
+ *  Copyright (C) 2009  Intel Corp
+ *  Copyright (C) 2009  Zhang Rui <rui.zhang@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef __ALS_SYS_H__
+#define __ALS_SYS_H__
+
+#include <linux/device.h>
+
+struct als_device;
+
+struct als_device_ops {
+	int (*get_illuminance) (struct als_device *, int *);
+	int (*update_mappings) (struct als_device *);
+};
+
+struct als_mapping {
+	int illuminance;
+	int adjustment;
+};
+
+struct als_device {
+	int id;
+	int illuminance;
+	struct device device;
+	struct als_device_ops *ops;
+	void *devdata;
+	char *desc;
+	int count;
+	struct als_mapping *mappings;
+};
+
+struct als_device *als_device_register(struct als_device_ops *, char *, void *);
+void als_device_unregister(struct als_device *);
+
+#endif /* __ALS_SYS_H__ */
Index: linux-2.6/Documentation/ABI/testing/sysfs-class-als
===================================================================
--- /dev/null
+++ linux-2.6/Documentation/ABI/testing/sysfs-class-als
@@ -0,0 +1,32 @@ 
+What:		/sys/class/als/als[0-N]/desc
+Date:		Aug. 2009
+KernelVersion:	2.6.32
+Contact:	Zhang Rui <rui.zhang@intel.com>
+Description:	Strings which descibes the current Ambient Light Sensor
+		device. This is given by native ALS driver as part of
+		registration. e.g: "acpi_als" for ACPI ALS devices.
+		RO
+
+What:		/sys/class/als/als[0-N]/illuminance
+Date:		Aug. 2009
+KernelVersion:	2.6.32
+Contact:	Zhang Rui <rui.zhang@intel.com>
+Description:	Current Ambient Light Illuminance reported by
+		native ALS driver
+		Unit: lux (lumens per square meter)
+		RO
+
+What:		/sys/class/als/als[0-N]/display_adjustment
+Date:		Aug. 2009
+KernelVersion:	2.6.32
+Contact:	Zhang Rui <rui.zhang@intel.com>
+Description:	a relative percentages in order simplify the means
+		by which these adjustments are applied in lieu of
+		changes to the user’s display brightness preference.
+		A value of 100% is used to indicate no display
+		brightness adjustment.
+		Values less than 100% indicate a negative adjustment
+		(dimming); values greater than 100% indicate a positive
+		adjustment (brightening).
+		RO
+
Index: linux-2.6/MAINTAINERS
===================================================================
--- linux-2.6.orig/MAINTAINERS
+++ linux-2.6/MAINTAINERS
@@ -399,6 +399,12 @@  S:	Maintained for 2.4; PCI support for 2
 L:	linux-alpha@vger.kernel.org
 F:	arch/alpha/
 
+AMBIENT LIGHT SENSOR
+M:	Zhang Rui <rui.zhang@intel.com>
+S:	Supported
+F:	include/linux/als_sys.h
+F:	drivers/als/
+
 AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
 M:	Thomas Dahlmann <dahlmann.thomas@arcor.de>
 L:	linux-geode@lists.infradead.org (moderated for non-subscribers)