lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 09 Sep 2011 17:22:26 +0900
From:	Donggeun Kim <dg77.kim@...sung.com>
To:	linux-kernel@...r.kernel.org
Cc:	linux-doc@...r.kernel.org, akpm@...ux-foundation.org,
	gregkh@...e.de, jic23@....ac.kr, kyungmin.park@...sung.com,
	dg77.kim@...sung.com
Subject: [PATCH v2] misc: Add driver for GP2AP002 proximity/ambient light sensor

SHARP GP2AP002 is proximity and ambient light sensor.
This patch supports it.

Signed-off-by: Donggeun Kim <dg77.kim@...sung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@...sung.com>
---
Changes for v2
  - changed to expose lux
  - changed request_irq to request_threaded_irq function
  - added sysfs_notify function call
  - cleaned up code

 Documentation/misc-devices/gp2ap002    |   44 +++
 drivers/misc/Kconfig                   |   10 +
 drivers/misc/Makefile                  |    1 +
 drivers/misc/gp2ap002.c                |  488 ++++++++++++++++++++++++++++++++
 include/linux/platform_data/gp2ap002.h |   69 +++++
 5 files changed, 612 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/misc-devices/gp2ap002
 create mode 100644 drivers/misc/gp2ap002.c
 create mode 100644 include/linux/platform_data/gp2ap002.h

diff --git a/Documentation/misc-devices/gp2ap002 b/Documentation/misc-devices/gp2ap002
new file mode 100644
index 0000000..3187740
--- /dev/null
+++ b/Documentation/misc-devices/gp2ap002
@@ -0,0 +1,44 @@
+Kernel driver gp2ap002
+=================
+
+Supported chips:
+* SHARP GP2AP002A00F proximity and ambient light sensor
+  Datasheet: Not publicly available
+
+Authors: Donggeun Kim <dg77.kim@...sung.com>
+	 Minkyu Kang <mk7.kang@...sung.com>
+
+Description
+-----------
+GP2AP002A00F is a proximity and ambient light sensor.
+The proximity sensor operates in a normal or interrupt mode.
+1. Normal mode: read the register regarding proximity register
+2. Interrupt mode: the chip generates interrupts
+	whenever object is detected or not detected
+The proximity state can be obtained from VO field of PROX register
+	1 = object is detected (value of VO field)
+	0 = object is not detected (value of VO field)
+
+This chip only exports current as the result of ambient light sensor.
+To get illuminance, CPU measures the current exported
+from the sensor through ADC.
+The relationship between current and illuminance is as follows:
+	illuminance = 10^(current/10)  - (1)
+This driver exposes illuminance
+by looking up the current-illuminance mapping table.
+
+Sysfs Interface
+---------------
+prox0_input	proximity sensor result
+		0: object is not detected
+		1: object is detected
+		RO
+
+lux0_input	ambient light sensor result
+		unit: lux
+		RO
+
+power_state	enable/disable the sensor
+		1: enable
+		0: disable
+		RW
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 2d6423c..576e386 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -499,6 +499,16 @@ config USB_SWITCH_FSA9480
 	  stereo and mono audio, video, microphone and UART data to use
 	  a common connector port.
 
+config GP2AP002
+	tristate "SHARP GP2AP002 proximity/ambient light sensor"
+	depends on I2C
+	help
+	 Say Y here if you want to support Sharp GP2AP002
+	 proximity/ambient light sensor.
+
+	 To compile this driver as a module, choose M here: the
+	 module will be called GP2AP002.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 8f3efb6..7929c26 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_AB8500_PWM)	+= ab8500-pwm.o
 obj-y				+= lis3lv02d/
 obj-y				+= carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
+obj-$(CONFIG_GP2AP002)		+= gp2ap002.o
diff --git a/drivers/misc/gp2ap002.c b/drivers/misc/gp2ap002.c
new file mode 100644
index 0000000..7ce5b37
--- /dev/null
+++ b/drivers/misc/gp2ap002.c
@@ -0,0 +1,488 @@
+/*
+ *  gp2ap002.c - SHARP GP2AP002 proximity/ambient light sensor
+ *
+ *  Copyright (C) 2010 Samsung Electronics
+ *  Minkyu Kang <mk7.kang@...sung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+#include <linux/platform_data/gp2ap002.h>
+
+#define GP2AP002_PROX		0x00
+#define GP2AP002_GAIN		0x01
+#define GP2AP002_HYS		0x02
+#define GP2AP002_CYCLE		0x03
+#define GP2AP002_OPMOD		0x04
+#define GP2AP002_CON		0x06
+
+#define PROX_VO_NO_DETECT	(0 << 0)
+#define PROX_VO_DETECT		(1 << 0)
+
+#define GAIN_LED_SHIFT		(3)
+#define GAIN_LED_MASK		(0x1 << GAIN_LED_SHIFT)
+
+#define HYS_HYSD_SHIFT		(7)
+#define HYS_HYSD_MASK		(0x1 << HYS_HYSD_SHIFT)
+#define HYS_HYSC_SHIFT		(5)
+#define HYS_HYSC_MASK		(0x3 << HYS_HYSC_SHIFT)
+#define HYS_HYSF_SHIFT		(0)
+#define HYS_HYSF_MASK		(0xf << HYS_HYSF_SHIFT)
+
+#define CYCLE_CYCL_SHIFT	(3)
+#define CYCLE_CYCL_MASK		(0x7 << CYCLE_CYCL_SHIFT)
+#define CYCLE_OSC_SHIFT		(2)
+#define CYCLE_OSC_MASK		(0x1 << CYCLE_OSC_SHIFT)
+
+#define OPMOD_ASD_SHIFT		(4)
+#define OPMOD_ASD_MASK		(0x1 << OPMOD_ASD_SHIFT)
+#define OPMOD_SSD_SHUTDOWN	(0)
+#define OPMOD_SSD_OPERATING	(1)
+#define OPMOD_VCON_SHIFT	(1)
+#define OPMOD_VCON_MASK		(0x1 << OPMOD_VCON_SHIFT)
+#define OPMOD_VCON_NORMAL	(0 << 1)
+#define OPMOD_VCON_IRQ		(1 << 1)
+
+#define CON_OCON_SHIFT		(3)
+#define CON_OCON_MASK		(0x3 << CON_OCON_SHIFT)
+
+struct illuminance {
+	unsigned int	curr;
+	unsigned int	lux;
+};
+
+/*
+ * This array maps current and lux.
+ * Ambient light sensing range is 3 to 55000.
+ * This mapping is based on the following formula.
+ * illuminance = 10 ^ (current / 10)
+ */
+const struct illuminance illuminance_table[] = {
+	{ .curr		= 5, .lux	= 3 },
+	{ .curr		= 6, .lux	= 4 },
+	{ .curr		= 7, .lux	= 5 },
+	{ .curr		= 8, .lux	= 6 },
+	{ .curr		= 9, .lux	= 8 },
+	{ .curr		= 10, .lux	= 10 },
+	{ .curr		= 11, .lux	= 12 },
+	{ .curr		= 12, .lux	= 16 },
+	{ .curr		= 13, .lux	= 20 },
+	{ .curr		= 14, .lux	= 25 },
+	{ .curr		= 15, .lux	= 32 },
+	{ .curr		= 16, .lux	= 40 },
+	{ .curr		= 17, .lux	= 50 },
+	{ .curr		= 18, .lux	= 63 },
+	{ .curr		= 19, .lux	= 79 },
+	{ .curr		= 20, .lux	= 100 },
+	{ .curr		= 21, .lux	= 126 },
+	{ .curr		= 22, .lux	= 158 },
+	{ .curr		= 23, .lux	= 200 },
+	{ .curr		= 24, .lux	= 251 },
+	{ .curr		= 25, .lux	= 316 },
+	{ .curr		= 26, .lux	= 398 },
+	{ .curr		= 27, .lux	= 501 },
+	{ .curr		= 28, .lux	= 631 },
+	{ .curr		= 29, .lux	= 794 },
+	{ .curr		= 30, .lux	= 1000 },
+	{ .curr		= 31, .lux	= 1259 },
+	{ .curr		= 32, .lux	= 1585 },
+	{ .curr		= 33, .lux	= 1995 },
+	{ .curr		= 34, .lux	= 2512 },
+	{ .curr		= 35, .lux	= 3162 },
+	{ .curr		= 36, .lux	= 3981 },
+	{ .curr		= 37, .lux	= 5012 },
+	{ .curr		= 38, .lux	= 6310 },
+	{ .curr		= 39, .lux	= 7943 },
+	{ .curr		= 40, .lux	= 10000 },
+	{ .curr		= 41, .lux	= 12589 },
+	{ .curr		= 42, .lux	= 15849 },
+	{ .curr		= 43, .lux	= 19953 },
+	{ .curr		= 44, .lux	= 25119 },
+	{ .curr		= 45, .lux	= 31623 },
+	{ .curr		= 46, .lux	= 39811 },
+	{ .curr		= 47, .lux	= 50119 },
+};
+
+struct gp2ap002_chip {
+	struct i2c_client	*client;
+	struct work_struct	work;
+	struct mutex		lock;
+
+	struct gp2ap002_platform_data *pdata;
+
+	bool enabled;
+
+	/* Proximity */
+	int proximity;
+
+	/* Ambient Light */
+	int adc;
+	int lux;
+};
+
+static void gp2ap002_get_proximity(struct gp2ap002_chip *chip)
+{
+	/* Determine whether the object is detected
+	   by reading GP2AP002_PROX register */
+	chip->proximity = i2c_smbus_read_byte_data(chip->client,
+				GP2AP002_PROX) & PROX_VO_DETECT;
+}
+
+static int gp2ap002_chip_enable(struct gp2ap002_chip *chip, bool enable)
+{
+	struct gp2ap002_platform_data *pdata = chip->pdata;
+	int ret;
+	u8 value;
+
+	if (enable == chip->enabled)
+		return 0;
+
+	value = (pdata->analog_sleep << OPMOD_ASD_SHIFT) |
+		(pdata->prox_mode << OPMOD_VCON_SHIFT);
+	/* software shutdown mode */
+	if (enable)
+		value |= OPMOD_SSD_OPERATING;
+	else /* operating mode */
+		value |= OPMOD_SSD_SHUTDOWN;
+
+	ret = i2c_smbus_write_byte_data(chip->client, GP2AP002_OPMOD, value);
+	if (ret < 0)
+		goto out;
+
+	chip->enabled = enable;
+out:
+	return ret;
+}
+
+static void gp2ap002_work(struct work_struct *work)
+{
+	struct gp2ap002_chip *chip = container_of(work,
+			struct gp2ap002_chip, work);
+
+	mutex_lock(&chip->lock);
+	gp2ap002_get_proximity(chip);
+
+	kobject_uevent(&chip->client->dev.kobj, KOBJ_CHANGE);
+	sysfs_notify(&chip->client->dev.kobj, NULL, "prox0_input");
+	mutex_unlock(&chip->lock);
+
+	enable_irq(chip->client->irq);
+}
+
+static irqreturn_t gp2ap002_irq(int irq, void *data)
+{
+	struct gp2ap002_chip *chip = data;
+
+	disable_irq_nosync(irq);
+	schedule_work(&chip->work);
+
+	return IRQ_HANDLED;
+}
+
+static int lookup_lux(int curr)
+{
+	int start, end, mid = -1;
+	int table_size = ARRAY_SIZE(illuminance_table);
+
+	/* Do a binary search on illuminance table */
+	start = 0;
+	end = table_size;
+
+	while (end > start) {
+		mid = start + (end - start) / 2;
+		if (illuminance_table[mid].curr < curr)
+			end = mid;
+		else if (illuminance_table[mid].curr > curr)
+			start = mid + 1;
+		else
+			return mid;
+	}
+
+	return -ENODATA;
+}
+
+static ssize_t gp2ap002_show_proximity(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct gp2ap002_chip *chip = dev_get_drvdata(dev);
+
+	mutex_lock(&chip->lock);
+	gp2ap002_get_proximity(chip);
+	mutex_unlock(&chip->lock);
+
+	if (chip->proximity < 0)
+		return chip->proximity;
+	return sprintf(buf, "%d\n", chip->proximity);
+}
+static DEVICE_ATTR(prox0_input, S_IRUGO, gp2ap002_show_proximity, NULL);
+
+static ssize_t gp2ap002_show_lux(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct gp2ap002_chip *chip = dev_get_drvdata(dev);
+	struct gp2ap002_platform_data *pdata = chip->pdata;
+	int ret;
+
+	if (pdata->get_adc) {
+		mutex_lock(&chip->lock);
+		chip->adc = pdata->get_adc();
+		ret = lookup_lux(chip->adc);
+		if (ret < 0) {
+			mutex_unlock(&chip->lock);
+			return ret;
+		}
+		chip->lux = illuminance_table[ret].lux;
+		mutex_unlock(&chip->lock);
+	}
+	return sprintf(buf, "%d\n", chip->lux);
+}
+static DEVICE_ATTR(lux0_input, S_IRUGO, gp2ap002_show_lux, NULL);
+
+static ssize_t gp2ap002_store_enable(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct gp2ap002_chip *chip = dev_get_drvdata(dev);
+	unsigned long value;
+	int ret;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	ret = gp2ap002_chip_enable(chip, !!value);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+static ssize_t gp2ap002_show_enable(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct gp2ap002_chip *chip = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", chip->enabled);
+}
+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
+		gp2ap002_show_enable, gp2ap002_store_enable);
+
+static struct attribute *gp2ap002_attributes[] = {
+	&dev_attr_prox0_input.attr,
+	&dev_attr_lux0_input.attr,
+	&dev_attr_power_state.attr,
+	NULL
+};
+
+static const struct attribute_group gp2ap002_attribute_group = {
+	.attrs = gp2ap002_attributes,
+};
+
+static int gp2ap002_initialize(struct gp2ap002_chip *chip)
+{
+	struct gp2ap002_platform_data *pdata = chip->pdata;
+	int ret;
+	u8 value;
+
+	/* GAIN register */
+	value = (pdata->led_mode << GAIN_LED_SHIFT) & GAIN_LED_MASK;
+	ret = i2c_smbus_write_byte_data(chip->client, GP2AP002_GAIN, value);
+	if (ret < 0)
+		goto out;
+
+	/* HYS register */
+	value = (pdata->hysd << HYS_HYSD_SHIFT) & HYS_HYSD_MASK;
+	value |= (pdata->hysc << HYS_HYSC_SHIFT) & HYS_HYSC_MASK;
+	value |= (pdata->hysf << HYS_HYSF_SHIFT) & HYS_HYSF_MASK;
+	ret = i2c_smbus_write_byte_data(chip->client, GP2AP002_HYS, value);
+	if (ret < 0)
+		goto out;
+
+	/* CYCLE register */
+	value = (pdata->cycle << CYCLE_CYCL_SHIFT) & CYCLE_CYCL_MASK;
+	value |= (pdata->oscillator << CYCLE_OSC_SHIFT) & CYCLE_OSC_MASK;
+	ret = i2c_smbus_write_byte_data(chip->client, GP2AP002_CYCLE, value);
+	if (ret < 0)
+		goto out;
+
+	/* CON register */
+	value = (pdata->vout_control << CON_OCON_SHIFT) & CON_OCON_MASK;
+	ret = i2c_smbus_write_byte_data(chip->client, GP2AP002_CYCLE, value);
+out:
+	return ret;
+}
+
+static int __devinit gp2ap002_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	struct gp2ap002_chip *chip;
+	struct gp2ap002_platform_data *pdata;
+	int ret;
+
+	pdata = client->dev.platform_data;
+	if (!pdata) {
+		dev_err(&client->dev, "No platform init data supplied\n");
+		return -ENODEV;
+	}
+
+	chip = kzalloc(sizeof(struct gp2ap002_chip), GFP_KERNEL);
+	if (!chip) {
+		dev_err(&client->dev, "Failed to allocate driver structure\n");
+		return -ENOMEM;
+	}
+
+	if (client->irq > 0) {
+		ret = request_threaded_irq(client->irq, NULL, gp2ap002_irq,
+			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			"GP2AP002 sensor", chip);
+		if (ret) {
+			dev_err(&client->dev, "Failed to request irq: %d\n",
+				client->irq);
+			goto error_irq;
+		}
+	}
+
+	chip->client = client;
+	i2c_set_clientdata(client, chip);
+	INIT_WORK(&chip->work, gp2ap002_work);
+	mutex_init(&chip->lock);
+	chip->pdata = pdata;
+
+	ret = sysfs_create_group(&client->dev.kobj, &gp2ap002_attribute_group);
+	if (ret) {
+		dev_err(&client->dev,
+			"Failed to create attribute group\n");
+		goto error_sysfs_group;
+	}
+
+	if (pdata->power_enable)
+		pdata->power_enable(true);
+
+	ret = gp2ap002_initialize(chip);
+	if (ret) {
+		dev_err(&client->dev, "Failed to initialize chip\n");
+		goto error_chip_initialize;
+	}
+
+	ret = gp2ap002_chip_enable(chip, pdata->chip_enable);
+	if (ret) {
+		dev_err(&client->dev, "Failed to enable chip\n");
+		goto error_chip_enable;
+	}
+
+	dev_info(&client->dev, "%s registered\n", id->name);
+	return 0;
+
+error_chip_enable:
+error_chip_initialize:
+	sysfs_remove_group(&client->dev.kobj, &gp2ap002_attribute_group);
+error_sysfs_group:
+	if (client->irq > 0)
+		free_irq(client->irq, chip);
+error_irq:
+	kfree(chip);
+	return ret;
+}
+
+static int __devexit gp2ap002_remove(struct i2c_client *client)
+{
+	struct gp2ap002_chip *chip = i2c_get_clientdata(client);
+
+	disable_irq_nosync(client->irq);
+	cancel_work_sync(&chip->work);
+
+	if (client->irq > 0)
+		free_irq(client->irq, chip);
+
+	sysfs_remove_group(&client->dev.kobj, &gp2ap002_attribute_group);
+
+	gp2ap002_chip_enable(chip, false);
+
+	if (chip->pdata->power_enable)
+		chip->pdata->power_enable(false);
+
+	kfree(chip);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int gp2ap002_suspend(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct gp2ap002_chip *chip = i2c_get_clientdata(client);
+
+	cancel_work_sync(&chip->work);
+	gp2ap002_chip_enable(chip, false);
+
+	if (chip->pdata->power_enable)
+		chip->pdata->power_enable(false);
+
+	return 0;
+}
+
+static int gp2ap002_resume(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct gp2ap002_chip *chip = i2c_get_clientdata(client);
+
+	if (chip->pdata->power_enable)
+		chip->pdata->power_enable(true);
+
+	gp2ap002_chip_enable(chip, true);
+
+	return 0;
+}
+#else
+#define gp2ap002_suspend NULL
+#define gp2ap002_resume NULL
+#endif
+
+static const struct i2c_device_id gp2ap002_id[] = {
+	{ "GP2AP002", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, gp2ap002_id);
+
+static const struct dev_pm_ops gp2ap002_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(gp2ap002_suspend, gp2ap002_resume)
+};
+
+static struct i2c_driver gp2ap002_i2c_driver = {
+	.driver = {
+		.name	= "GP2AP002",
+		.owner	= THIS_MODULE,
+		.pm	= &gp2ap002_pm_ops,
+	},
+	.probe		= gp2ap002_probe,
+	.remove		= __devexit_p(gp2ap002_remove),
+	.id_table	= gp2ap002_id,
+};
+
+static int __init gp2ap002_init(void)
+{
+	return i2c_add_driver(&gp2ap002_i2c_driver);
+}
+module_init(gp2ap002_init);
+
+static void __exit gp2ap002_exit(void)
+{
+	i2c_del_driver(&gp2ap002_i2c_driver);
+}
+module_exit(gp2ap002_exit);
+
+MODULE_AUTHOR("Minkyu Kang <mk7.kang@...sung.com>");
+MODULE_DESCRIPTION("GP2AP002 Proximity/Ambient Light Sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/platform_data/gp2ap002.h b/include/linux/platform_data/gp2ap002.h
new file mode 100644
index 0000000..39e6a1b
--- /dev/null
+++ b/include/linux/platform_data/gp2ap002.h
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (C) 2010 Samsung Electronics
+ *  Minkyu Kang <mk7.kang@...sung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __GP2AP002_H_
+#define __GP2AP002_H_
+
+/**
+ * struct gp2ap002_platform_data
+ * @get_adc: call back function to get adc value for ambient light sensor
+ * @power_enable: call back function to control voltage supply for chip
+ * @led_mode: select switch for LED's resistance
+ *	0: 2x higher setting,
+ *	1: normal setting
+ * @hysd, hysc, hysf: a set of these bits adjusts the sensitivity,
+ *	determining characteristics of the detection distance and
+ *	its hysteresis
+ *	0 <= hysd <= 1
+ *	0 <= hysc <= 3
+ *	0 <= hysf <= 15
+ * @cycle: determine the detection cycle
+ *	0: 8ms (response time)
+ *	1: 16ms (response time)
+ *	2: 32ms (response time)
+ *	3: 64ms (response time)
+ *	4: 128ms (response time)
+ *	5: 256ms (response time)
+ *	6: 512ms (response time)
+ *	7: 1024ms (response time)
+ * @oscillator: select switch for internal clock frequency hopping
+ *	0: effective,
+ *	1: ineffective
+ * @analog_sleep: select switch for analog sleep function
+ *	0: ineffective
+ *	1: effective
+ * @prox_mode: determine output method control for Vout pin
+ *	0: normal mode
+ *	1: interrupt_mode
+ * @vout_control: select switch for enabling/disabling Vout pin
+ *	0: enable
+ *	2: force to go Low
+ *	3: force to go High
+ * @chip_enable: determine enabling/disabling software shutdown function
+ *	0: shutdown mode
+ *	1: operating mode
+ */
+struct gp2ap002_platform_data {
+	int (*get_adc)(void);
+	void (*power_enable)(bool);
+
+	u8 led_mode;
+	u8 hysd;
+	u8 hysc;
+	u8 hysf;
+	u8 cycle;
+	u8 oscillator;
+	u8 analog_sleep;
+	u8 prox_mode;
+	u8 vout_control;
+
+	bool chip_enable;
+};
+
+#endif
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ