[PATCH] NFC: Driver for SAMSUNG S3FHRN2 NFC Chip.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a driver for the S3FHRN2 NFC device. the driver is just a
proxy getting SHDLC/HCI frames from a userspace stack.

Signed-off-by: WoonKi Lee <woonki84.lee@xxxxxxxxxxx>
---
 drivers/nfc/Kconfig         |    8 +
 drivers/nfc/Makefile        |    1 +
 drivers/nfc/s3fhrn2_i2c.c   |  594 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/nfc/s3fhrn2.h |   52 ++++
 4 files changed, 655 insertions(+), 0 deletions(-)
 create mode 100644 drivers/nfc/s3fhrn2_i2c.c
 create mode 100644 include/linux/nfc/s3fhrn2.h

diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 3b20b73..08a90a9 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -51,4 +51,12 @@ config NFC_WILINK
 	  Say Y here to compile support for Texas Instrument's NFC WiLink driver
 	  into the kernel or say M to compile it as module.
 
+config S3FHRN2
+	bool "Samsung NFC S3FHRN2 I2C driver"
+	depends on I2C
+	help
+	  This driver provides support for NFC SAMSUNG S3FHRN2 devices.
+	  Say Y if you want S3FHRN2 NFC driver.
+
+	  This is for I2C connected version. If unsure, say N here.
 endmenu
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 473e44c..983ce4f 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_PN544_NFC)		+= pn544.o
 obj-$(CONFIG_PN544_HCI_NFC)	+= pn544_hci.o
 obj-$(CONFIG_NFC_PN533)		+= pn533.o
 obj-$(CONFIG_NFC_WILINK)	+= nfcwilink.o
+obj-$(CONFIG_S3FHRN2_I2C)	+= s3fhrn2_i2c.o
 
 ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff --git a/drivers/nfc/s3fhrn2_i2c.c b/drivers/nfc/s3fhrn2_i2c.c
new file mode 100644
index 0000000..7d72b0c
--- /dev/null
+++ b/drivers/nfc/s3fhrn2_i2c.c
@@ -0,0 +1,594 @@
+/*
+ * SAMSUNG NFC S3FHRN2 Controller for I2C I/F
+ *
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Woonki Lee <woonki84.lee@xxxxxxxxxxx>
+ *
+ * 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.
+ *
+ * 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/wait.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/nfc/s3fhrn2.h>
+
+#define S3FHRN2_IS_LENGTH(val)	(val == S3FHRN2_LLC_LENGTH)
+
+enum s3fhrn2_irq {
+	S3FHRN2_NONE,
+	S3FHRN2_INT,
+};
+
+struct s3fhrn2_info {
+	struct miscdevice miscdev;
+	struct i2c_client *i2c_dev;
+	struct mutex read_mutex;
+	struct mutex mutex;
+	enum s3fhrn2_state state;	/* off, normal, firm download mode */
+	enum s3fhrn2_irq read_irq;
+	wait_queue_head_t read_wait;
+	size_t buflen;
+	u8 *buf;
+};
+
+static irqreturn_t s3fhrn2_irq_thread_fn(int irq, void *dev_id)
+{
+	struct s3fhrn2_info *info = dev_id;
+	struct i2c_client *client = info->i2c_dev;
+
+	dev_dbg(&client->dev, "IRQ\n");
+
+	mutex_lock(&info->read_mutex);
+	info->read_irq = S3FHRN2_INT;
+	mutex_unlock(&info->read_mutex);
+
+	wake_up_interruptible(&info->read_wait);
+
+	return IRQ_HANDLED;
+}
+
+static int s3fhrn2_set_state(struct s3fhrn2_info *info,
+					enum s3fhrn2_state state)
+{
+	struct i2c_client *client = info->i2c_dev;
+	struct s3fhrn2_platform_data *pdata = client->dev.platform_data;
+
+	/* intfo lock is aleady getten before calling this function */
+	info->read_irq = S3FHRN2_NONE;
+	info->state = state;
+
+	gpio_set_value(pdata->ven, 0);
+	gpio_set_value(pdata->firm, 0);
+	msleep(S3FHRN2_VEN_WAIT_TIME);
+
+	if (state == S3FHRN2_ST_FIRM) {
+		gpio_set_value(pdata->firm, 1);
+		msleep(S3FHRN2_VEN_WAIT_TIME);
+		gpio_set_value(pdata->ven, 0);
+		msleep(S3FHRN2_VEN_WAIT_TIME);
+	}
+
+	if (state != S3FHRN2_ST_OFF)
+		gpio_set_value(pdata->ven, 1);
+
+	msleep(S3FHRN2_VEN_WAIT_TIME*3);
+
+	return 0;
+}
+
+static int s3fhrn2_reset(struct s3fhrn2_info *info)
+{
+	struct i2c_client *client = info->i2c_dev;
+
+	dev_err(&client->dev, "i2c failed. return resatrt to M/W\n");
+
+	s3fhrn2_set_state(info, S3FHRN2_ST_NORM);
+
+	return -ERESTART;
+}
+
+static ssize_t s3fhrn2_read(struct file *file, char __user *buf,
+			  size_t count, loff_t *offset)
+{
+	struct s3fhrn2_info *info = container_of(file->private_data,
+						struct s3fhrn2_info, miscdev);
+	struct i2c_client *client = info->i2c_dev;
+	enum s3fhrn2_irq irq;
+	int min = S3FHRN2_MSG_MIN_SIZE;
+	int max = S3FHRN2_MSG_MAX_SIZE;
+	int ret = 0;
+
+	dev_dbg(&client->dev, "%s: info: %p, count: %zu\n", __func__,
+		info, count);
+
+	mutex_lock(&info->mutex);
+
+	if (info->state == S3FHRN2_ST_OFF) {
+		dev_err(&client->dev, "s3fhrn2 is not enabled\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	mutex_lock(&info->read_mutex);
+	irq = info->read_irq;
+	mutex_unlock(&info->read_mutex);
+	if (irq == S3FHRN2_NONE) {
+		if (file->f_flags & O_NONBLOCK) {
+			dev_err(&client->dev, "it is nonblock\n");
+			ret = -EAGAIN;
+			goto out;
+		}
+
+		if (wait_event_interruptible(info->read_wait,
+					(info->read_irq == S3FHRN2_INT))) {
+			ret = -ERESTARTSYS;
+			goto out;
+		}
+	}
+
+	/* i2c recv */
+	if (count > info->buflen)
+		count = info->buflen;
+
+	min = (info->state == S3FHRN2_ST_FIRM) ?
+				S3FHRN2_FIRM_MIN_SIZE : S3FHRN2_MSG_MIN_SIZE;
+	max = (info->state == S3FHRN2_ST_FIRM) ?
+				S3FHRN2_FIRM_MAX_SIZE : S3FHRN2_MSG_MAX_SIZE;
+
+	if (count < min || count > max) {
+		dev_dbg(&client->dev, "user required wrong size\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	mutex_lock(&info->read_mutex);
+	ret = i2c_master_recv(client, info->buf, count);
+	dev_dbg(&client->dev, "recv size : %d\n", ret);
+
+	if (ret == -EREMOTEIO) {
+		ret = s3fhrn2_reset(info);
+		goto read_error;
+	} else if (ret != count) {
+		dev_err(&client->dev, "read failed: return: %d count: %d\n",
+			ret, count);
+		ret = -EREMOTEIO;
+		goto read_error;
+	}
+
+	/* Only reading data can clear read_irq state. */
+	if (!S3FHRN2_IS_LENGTH(ret) || info->state == S3FHRN2_ST_FIRM)
+		info->read_irq = S3FHRN2_NONE;
+	/* check the length value,
+		It may be doing when reading length of frame. */
+	else if (info->buf[0] < min || info->buf[0] > max) {
+		dev_err(&client->dev, "reciev invaild length : %x\n",
+			info->buf[0]);
+
+		/* We need to check if i2c transmit is possible */
+		ret = i2c_master_send(client, "test", 1);
+		if (ret == -EREMOTEIO)
+			ret = s3fhrn2_reset(info);
+		else
+			ret = -EINVAL;
+
+		goto read_error;
+	}
+	mutex_unlock(&info->read_mutex);
+
+	*offset += ret;
+	if (copy_to_user(buf, info->buf, ret)) {
+		dev_err(&client->dev, "copy failed to user\n");
+		ret = -EFAULT;
+	}
+
+	goto out;
+
+read_error:
+	info->read_irq = S3FHRN2_NONE;
+	mutex_unlock(&info->read_mutex);
+out:
+	mutex_unlock(&info->mutex);
+
+	return ret;
+}
+
+static unsigned int s3fhrn2_poll(struct file *file, poll_table *wait)
+{
+	struct s3fhrn2_info *info = container_of(file->private_data,
+						struct s3fhrn2_info, miscdev);
+	struct i2c_client *client = info->i2c_dev;
+	int ret = 0;
+	enum s3fhrn2_irq irq;
+
+	dev_dbg(&client->dev, "%s: info: %p\n", __func__, info);
+
+	mutex_lock(&info->mutex);
+
+	if (info->state == S3FHRN2_ST_OFF) {
+		dev_err(&client->dev, "s3fhrn2 is not enabled\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	poll_wait(file, &info->read_wait, wait);
+
+	mutex_lock(&info->read_mutex);
+	irq = info->read_irq;
+	mutex_unlock(&info->read_mutex);
+	if (irq == S3FHRN2_INT)
+		ret = (POLLIN | POLLRDNORM);
+
+out:
+	mutex_unlock(&info->mutex);
+
+	return ret;
+}
+
+static ssize_t s3fhrn2_write(struct file *file, const char __user *buf,
+			   size_t count, loff_t *ppos)
+{
+	struct s3fhrn2_info *info = container_of(file->private_data,
+						struct s3fhrn2_info, miscdev);
+	struct i2c_client *client = info->i2c_dev;
+	int min, max;
+	int ret = 0;
+
+	dev_dbg(&client->dev, "%s: info: %p, count %zu\n", __func__,
+		info, count);
+
+	mutex_lock(&info->mutex);
+
+	if (info->state == S3FHRN2_ST_OFF) {
+		dev_err(&client->dev, "s3fhrn2 is not enabled\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (count > info->buflen)
+		count = info->buflen;
+
+	min = (info->state == S3FHRN2_ST_FIRM) ?
+				S3FHRN2_FIRM_MIN_SIZE : S3FHRN2_MSG_MIN_SIZE;
+	max = (info->state == S3FHRN2_ST_FIRM) ?
+				S3FHRN2_FIRM_MAX_SIZE : S3FHRN2_MSG_MAX_SIZE;
+
+	if (count < min || count > max) {
+		dev_dbg(&client->dev, "user required wrong size\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (copy_from_user(info->buf, buf, count)) {
+		dev_err(&client->dev, "copy failed from user\n");
+		ret = -EFAULT;
+		goto out;
+	}
+
+	usleep_range(6000, 10000);
+	ret = i2c_master_send(client, info->buf, count);
+	dev_dbg(&client->dev, "send: %d\n", ret);
+
+	if (ret == -EREMOTEIO) {
+		ret = s3fhrn2_reset(info);
+		goto out;
+	}
+
+	if (ret != count) {
+		dev_dbg(&client->dev, "send failed: return: %d count: %d\n",
+		ret, count);
+		ret = -EREMOTEIO;
+	}
+
+out:
+	mutex_unlock(&info->mutex);
+
+	return ret;
+}
+
+static long s3fhrn2_ioctl(struct file *file, unsigned int cmd,
+							unsigned long arg)
+{
+	struct s3fhrn2_info *info = container_of(file->private_data,
+						struct s3fhrn2_info, miscdev);
+	struct i2c_client *client = info->i2c_dev;
+	unsigned int mode = (unsigned int)arg;
+	int ret = 0;
+
+	dev_dbg(&client->dev, "%s: info: %p, cmd: 0x%x\n",
+			__func__, info, cmd);
+
+	mutex_lock(&info->mutex);
+
+	switch (cmd) {
+	case S3FHRN2_SET_MODE:
+		dev_dbg(&client->dev, "%s: s3fhrn2_SET_MODE\n", __func__);
+
+		if (info->state == mode)
+			break;
+
+		if (mode >= S3FHRN2_ST_COUNT) {
+			dev_err(&client->dev, "wrong state (%d)\n", mode);
+			ret = -EFAULT;
+			break;
+		}
+
+		ret = s3fhrn2_set_state(info, mode);
+		if (ret < 0) {
+			dev_err(&client->dev, "enable failed\n");
+			break;
+		}
+
+		break;
+	default:
+		dev_err(&client->dev, "Unknow ioctl 0x%x\n", cmd);
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	mutex_unlock(&info->mutex);
+
+	return ret;
+}
+
+static int s3fhrn2_open(struct inode *inode, struct file *file)
+{
+	struct s3fhrn2_info *info = container_of(file->private_data,
+						struct s3fhrn2_info, miscdev);
+	struct i2c_client *client = info->i2c_dev;
+	int ret = 0;
+
+	dev_dbg(&client->dev, "%s: info : %p, client %p\n", __func__,
+		info, info->i2c_dev);
+
+	mutex_lock(&info->mutex);
+	if (info->state != S3FHRN2_ST_OFF) {
+		dev_err(&client->dev, "s3fhrn2 is busy\n");
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = s3fhrn2_set_state(info, S3FHRN2_ST_NORM);
+out:
+	mutex_unlock(&info->mutex);
+	return ret;
+}
+
+static int s3fhrn2_close(struct inode *inode, struct file *file)
+{
+	struct s3fhrn2_info *info = container_of(file->private_data,
+						struct s3fhrn2_info, miscdev);
+	struct i2c_client *client = info->i2c_dev;
+
+	dev_dbg(&client->dev, "%s: info: %p, client %p\n",
+		__func__, info, info->i2c_dev);
+
+	mutex_lock(&info->mutex);
+	s3fhrn2_set_state(info, S3FHRN2_ST_OFF);
+	mutex_unlock(&info->mutex);
+
+	return 0;
+}
+
+static const struct file_operations s3fhrn2_fops = {
+	.owner		= THIS_MODULE,
+	.read		= s3fhrn2_read,
+	.write		= s3fhrn2_write,
+	.poll		= s3fhrn2_poll,
+	.open		= s3fhrn2_open,
+	.release	= s3fhrn2_close,
+	.unlocked_ioctl	= s3fhrn2_ioctl,
+};
+
+#ifdef CONFIG_PM
+static int s3fhrn2_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct s3fhrn2_info *info = i2c_get_clientdata(client);
+	int ret = 0;
+
+	mutex_lock(&info->mutex);
+
+	if (info->state == S3FHRN2_ST_FIRM)
+		ret = -EPERM;
+
+	/*
+		suspend sequence.
+	*/
+	mutex_unlock(&info->mutex);
+	return ret;
+}
+
+static int s3fhrn2_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct s3fhrn2_info *info = i2c_get_clientdata(client);
+
+	/*
+	mutex_lock(&info->mutex);
+
+		resume sequence here
+
+	mutex_unlock(&info->mutex);
+	*/
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(s3fhrn2_pm_ops, s3fhrn2_suspend, s3fhrn2_resume);
+#endif
+
+static int __devinit s3fhrn2_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct s3fhrn2_info *info;
+	struct s3fhrn2_platform_data *pdata;
+	int ret = 0;
+
+	info = kzalloc(sizeof(struct s3fhrn2_info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&client->dev,
+			"failed to allocate memory for s3fhrn2_info\n");
+		ret = -ENOMEM;
+		goto err_info_alloc;
+	}
+
+
+	info->buflen = S3FHRN2_MAX_BUFFER_SIZE;
+	info->buf = kzalloc(S3FHRN2_MAX_BUFFER_SIZE, GFP_KERNEL);
+	if (!info->buf) {
+		dev_err(&client->dev,
+			"failed to allocate memory for s3fhrn2_info->buf\n");
+		ret = -ENOMEM;
+		goto err_buf_alloc;
+	}
+
+	info->i2c_dev = client;
+	info->state = S3FHRN2_ST_OFF;
+	info->read_irq = S3FHRN2_NONE;
+	mutex_init(&info->read_mutex);
+	mutex_init(&info->mutex);
+	init_waitqueue_head(&info->read_wait);
+	i2c_set_clientdata(client, info);
+	pdata = client->dev.platform_data;
+	if (!pdata) {
+		dev_err(&client->dev, "No platform data\n");
+		ret = -ENOMEM;
+		goto err_buf_alloc;
+	}
+
+	ret = request_threaded_irq(client->irq, NULL, s3fhrn2_irq_thread_fn,
+				   IRQF_TRIGGER_RISING, S3FHRN2_DRIVER_NAME,
+				   info);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to register IRQ handler\n");
+		goto err_irq_req;
+	}
+
+	info->miscdev.minor = MISC_DYNAMIC_MINOR;
+	info->miscdev.name = S3FHRN2_DRIVER_NAME;
+	info->miscdev.fops = &s3fhrn2_fops;
+	info->miscdev.parent = &client->dev;
+	ret = misc_register(&info->miscdev);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to register Device\n");
+		goto err_dev_reg;
+	}
+
+	ret = gpio_request(pdata->ven, "nfc_ven");
+	if (ret) {
+		dev_err(&client->dev, "failed to get gpio ven\n");
+		goto err_gpio_ven;
+	}
+
+	ret = gpio_request(pdata->firm, "nfc_firm");
+	if (ret) {
+		dev_err(&client->dev, "failed to get gpio firm\n");
+		goto err_gpio_firm;
+	}
+
+	gpio_direction_output(pdata->ven, 0);
+	gpio_direction_output(pdata->firm, 0);
+
+	dev_dbg(&client->dev, "%s: info: %p, pdata %p, client %p\n",
+		__func__, info, pdata, client);
+
+	return 0;
+
+err_gpio_firm:
+	gpio_free(pdata->ven);
+err_gpio_ven:
+err_dev_reg:
+err_irq_req:
+	kfree(info->buf);
+err_buf_alloc:
+	kfree(info);
+err_info_alloc:
+	return ret;
+}
+
+static int __devexit s3fhrn2_remove(struct i2c_client *client)
+{
+	struct s3fhrn2_info *info = i2c_get_clientdata(client);
+	struct s3fhrn2_platform_data *pdata = client->dev.platform_data;
+
+	dev_dbg(&client->dev, "%s\n", __func__);
+
+	misc_deregister(&info->miscdev);
+
+	if (info->state != S3FHRN2_ST_OFF) {
+		gpio_set_value(pdata->firm, 0);
+		gpio_set_value(pdata->ven, 0);
+		info->read_irq = S3FHRN2_NONE;
+	}
+
+	gpio_free(pdata->firm);
+	gpio_free(pdata->ven);
+
+	free_irq(client->irq, info);
+
+	kfree(info->buf);
+	kfree(info);
+
+	return 0;
+}
+
+static struct i2c_device_id s3fhrn2_id_table[] = {
+	{ S3FHRN2_DRIVER_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, s3fhrn2_id_table);
+
+static struct i2c_driver s3fhrn2_driver = {
+	.driver = {
+		.name = S3FHRN2_DRIVER_NAME,
+#ifdef CONFIG_PM
+		.pm = &s3fhrn2_pm_ops,
+#endif
+	},
+	.probe = s3fhrn2_probe,
+	.id_table = s3fhrn2_id_table,
+	.remove = s3fhrn2_remove,
+};
+
+static int __init s3fhrn2_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&s3fhrn2_driver);
+
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void __exit s3fhrn2_exit(void)
+{
+	i2c_del_driver(&s3fhrn2_driver);
+}
+
+module_init(s3fhrn2_init);
+module_exit(s3fhrn2_exit);
+
+MODULE_DESCRIPTION("Samsung s3fhrn2 driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/nfc/s3fhrn2.h b/include/linux/nfc/s3fhrn2.h
new file mode 100644
index 0000000..2f8a619
--- /dev/null
+++ b/include/linux/nfc/s3fhrn2.h
@@ -0,0 +1,52 @@
+/*
+ * SAMSUNG NFC N2 Controller
+ *
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Woonki Lee <woonki84.lee@xxxxxxxxxxx>
+ *
+ * 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/platform_device.h>
+
+#define S3FHRN2_DRIVER_NAME		"snfc-n2"
+
+#define S3FHRN2_MAX_BUFFER_SIZE	512
+
+/* ioctl */
+#define S3FHRN2_MAGIC	'S'
+#define S3FHRN2_GET_MODE	_IOW(S3FHRN2_MAGIC, 0, unsigned int)
+#define S3FHRN2_SET_MODE	_IOW(S3FHRN2_MAGIC, 1, unsigned int)
+
+/* size */
+#define S3FHRN2_LLC_LENGTH		1
+#define S3FHRN2_MSG_MIN_SIZE	1 /* LLC length header is 1*/
+#define S3FHRN2_MSG_MAX_SIZE	0x21
+#define S3FHRN2_FIRM_MIN_SIZE	1
+#define S3FHRN2_FIRM_MAX_SIZE	129 /* length (1) + FW DATA (128) */
+
+/* check */
+#define S3FHRN2_IS_LENGTH(val)	(val == S3FHRN2_LLC_LENGTH)
+
+/* wait for device stable */
+#define S3FHRN2_VEN_WAIT_TIME	(200)
+
+/* gpio pin configuration */
+struct s3fhrn2_platform_data {
+	unsigned int irq;
+	unsigned int ven;
+	unsigned int firm;
+	void	(*cfg_gpio)(struct platform_device *dev);
+};
+
+enum s3fhrn2_state {
+	S3FHRN2_ST_OFF = 0,
+	S3FHRN2_ST_NORM,
+	S3FHRN2_ST_FIRM,
+	S3FHRN2_ST_COUNT,
+};
+
-- 
1.7.1


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


[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux