All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] digital compass hmc5843
@ 2010-07-06 11:08 Shubhrajyoti D
  2010-07-06 11:09 ` Datta, Shubhrajyoti
  0 siblings, 1 reply; 5+ messages in thread
From: Shubhrajyoti D @ 2010-07-06 11:08 UTC (permalink / raw)
  To: linux-iio; +Cc: sfking, Shubhrajyoti D

Adding support for the Honeywell HMC5843. The interface to the device is i2c.

- Changing the interface to suit the standards

TODO
- Documentation for the interface provided
- Gauss is reported in millig

Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/Kconfig                |    1 +
 drivers/staging/iio/Makefile               |    1 +
 drivers/staging/iio/magnetometer/Kconfig   |   15 +
 drivers/staging/iio/magnetometer/Makefile  |    5 +
 drivers/staging/iio/magnetometer/hmc5843.c |  622 ++++++++++++++++++++++++++++
 5 files changed, 644 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/iio/magnetometer/Kconfig
 create mode 100644 drivers/staging/iio/magnetometer/Makefile
 create mode 100644 drivers/staging/iio/magnetometer/hmc5843.c

diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index b0e6244..569b938 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -44,6 +44,7 @@ source "drivers/staging/iio/adc/Kconfig"
 source "drivers/staging/iio/gyro/Kconfig"
 source "drivers/staging/iio/imu/Kconfig"
 source "drivers/staging/iio/light/Kconfig"
+source "drivers/staging/iio/magnetometer/Kconfig"
 
 source "drivers/staging/iio/trigger/Kconfig"
 
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
index 3502b39..10d1f6b 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -14,5 +14,6 @@ obj-y += adc/
 obj-y += gyro/
 obj-y += imu/
 obj-y += light/
+obj-y += magnetometer/
 
 obj-y += trigger/
\ No newline at end of file
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
new file mode 100644
index 0000000..d014450
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -0,0 +1,15 @@
+#
+# Magnetometer sensors
+#
+comment "Magnetometer sensors"
+
+config SENSORS_HMC5843
+	tristate "Honeywell HMC5843 3-Axis Magnetometer"
+	depends on I2C
+	help
+	  Say Y here to add support for the Honeywell HMC 5843 3-Axis
+	  Magnetometer (digital compass).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called hmc5843
+
diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile
new file mode 100644
index 0000000..f9bfb2e
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for industrial I/O Magnetometer sensors
+#
+
+obj-$(CONFIG_SENSORS_HMC5843)	+= hmc5843.o
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
new file mode 100644
index 0000000..58d275a
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -0,0 +1,622 @@
+/*  Copyright (C) 2010 Texas Instruments
+    Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
+    Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include "../iio.h"
+#include "../sysfs.h"
+#include "magnet.h"
+
+#define HMC5843_I2C_ADDRESS			0x1E
+
+#define HMC5843_CONFIG_REG_A			0x00
+#define HMC5843_CONFIG_REG_B			0x01
+#define HMC5843_MODE_REG			0x02
+#define HMC5843_DATA_OUT_X_MSB_REG		0x03
+#define HMC5843_DATA_OUT_X_LSB_REG		0x04
+#define HMC5843_DATA_OUT_Y_MSB_REG		0x05
+#define HMC5843_DATA_OUT_Y_LSB_REG		0x06
+#define HMC5843_DATA_OUT_Z_MSB_REG		0x07
+#define HMC5843_DATA_OUT_Z_LSB_REG		0x08
+#define HMC5843_STATUS_REG			0x09
+#define HMC5843_ID_REG_A			0x0A
+#define HMC5843_ID_REG_B			0x0B
+#define HMC5843_ID_REG_C			0x0C
+
+#define HMC5843_ID_REG_LENGTH			0x03
+#define HMC5843_ID_STRING			"H43"
+
+/*
+ * Range settings in  (+-)Ga
+ * */
+#define RANGE_GAIN_OFFSET			0x05
+
+#define	RANGE_0_7				0x00
+#define	RANGE_1_0				0x01 /* default */
+#define	RANGE_1_5				0x02
+#define	RANGE_2_0				0x03
+#define	RANGE_3_2				0x04
+#define	RANGE_3_8				0x05
+#define	RANGE_4_5				0x06
+#define	RANGE_6_5				0x07 /* Not recommended */
+
+/*
+ * Device status
+ */
+#define	DATA_READY  				0x01
+#define	DATA_OUTPUT_LOCK  			0x02
+#define	VOLTAGE_REGULATOR_ENABLED  		0x04
+
+/*
+ * Mode register configuration
+ */
+#define	MODE_CONVERSION_CONTINUOUS		0x00
+#define	MODE_CONVERSION_SINGLE			0x01
+#define	MODE_IDLE				0x02
+#define	MODE_SLEEP				0x03
+
+/* Minimum Data Output Rate in 1/10 Hz  */
+#define RATE_OFFSET				0x02
+#define RATE_BITMASK				0x1C
+#define	RATE_5					0x00
+#define	RATE_10					0x01
+#define	RATE_20					0x02
+#define	RATE_50					0x03
+#define	RATE_100				0x04
+#define	RATE_200				0x05
+#define	RATE_500				0x06
+#define	RATE_NOT_USED				0x07
+
+/*
+ * Device Configutration
+ */
+#define	CONF_NORMAL  				0x00
+#define	CONF_POSITIVE_BIAS			0x01
+#define	CONF_NEGATIVE_BIAS			0x02
+#define	CONF_NOT_USED				0x03
+#define	MEAS_CONF_MASK				0x03
+
+static const int regval_to_counts_per_mg[] = {
+	1620,
+	1300,
+	970,
+	780,
+	530,
+	460,
+	390,
+	280
+};
+static const int regval_to_input_field_mg[] = {
+	700,
+	1000,
+	1500,
+	2000,
+	3200,
+	3800,
+	4500,
+	6500
+};
+static const char *regval_to_samp_freq[] = {
+	"0.5",
+	"1",
+	"2",
+	"5",
+	"10",
+	"20",
+	"50",
+};
+
+/* Addresses to scan: 0x1E */
+static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
+							I2C_CLIENT_END };
+
+/* Each client has this additional data */
+struct hmc5843_data {
+	struct iio_dev	*indio_dev;
+	struct mutex lock;
+	u8		rate;
+	u8		meas_conf;
+	u8		operating_mode;
+	u8		range;
+};
+
+static void hmc5843_init_client(struct i2c_client *client);
+
+static s32 hmc5843_configure(struct i2c_client *client,
+				       u8 operating_mode)
+{
+	/* The lower two bits contain the current conversion mode */
+	return i2c_smbus_write_byte_data(client,
+					HMC5843_MODE_REG,
+					(operating_mode & 0x03));
+}
+
+/* Return the measurement value from the  specified channel */
+static ssize_t hmc5843_read_measurement(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+	s16 coordinate_val;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	s32 result;
+
+	mutex_lock(&data->lock);
+
+	result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
+	while (!(result & DATA_READY))
+		result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
+
+	result = i2c_smbus_read_word_data(client, this_attr->address);
+	mutex_unlock(&data->lock);
+	if (result < 0)
+		return -EINVAL;
+
+	coordinate_val	= (s16)swab16((u16)result);
+	return sprintf(buf, "%d\n", coordinate_val);
+}
+static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
+		HMC5843_DATA_OUT_X_MSB_REG);
+static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
+		HMC5843_DATA_OUT_Y_MSB_REG);
+static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
+		HMC5843_DATA_OUT_Z_MSB_REG);
+
+/*
+ * From the datasheet
+ * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
+ * device continuously performs conversions an places the result in the
+ * data register.
+ *
+ * 1 - Single-Conversion Mode : device performs a single measurement,
+ *  sets RDY high and returned to sleep mode
+ *
+ * 2 - Idle Mode :  Device is placed in idle mode.
+ *
+ * 3 - Sleep Mode. Device is placed in sleep mode.
+ *
+ */
+static ssize_t hmc5843_show_operating_mode(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	return sprintf(buf, "%d\n", data->operating_mode);
+}
+
+static ssize_t hmc5843_set_operating_mode(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t count)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long operating_mode = 0;
+	s32 status;
+	int error;
+	mutex_lock(&data->lock);
+	error = strict_strtoul(buf, 10, &operating_mode);
+	if (error)
+		return error;
+	dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
+	if (operating_mode > MODE_SLEEP)
+			return -EINVAL;
+
+	status = i2c_smbus_write_byte_data(client, this_attr->address,
+					operating_mode);
+	if (status) {
+		count = -EINVAL;
+		goto exit;
+	}
+	data->operating_mode = operating_mode;
+
+exit:
+	mutex_unlock(&data->lock);
+	return count;
+}
+static IIO_DEVICE_ATTR(operating_mode,
+			S_IWUSR | S_IRUGO,
+			hmc5843_show_operating_mode,
+			hmc5843_set_operating_mode,
+			HMC5843_MODE_REG);
+
+/*
+ * API for setting the measurement configuration to
+ * Normal, Positive bias and Negative bias
+ * From the datasheet
+ *
+ * Normal measurement configuration (default): In normal measurement
+ * configuration the device follows normal measurement flow. Pins BP and BN
+ * are left floating and high impedance.
+ *
+ * Positive bias configuration: In positive bias configuration, a positive
+ * current is forced across the resistive load on pins BP and BN.
+ *
+ * Negative bias configuration. In negative bias configuration, a negative
+ * current is forced across the resistive load on pins BP and BN.
+ *
+ */
+static s32 hmc5843_set_meas_conf(struct i2c_client *client,
+				      u8 meas_conf)
+{
+	struct hmc5843_data *data = i2c_get_clientdata(client);
+	u8 reg_val;
+	reg_val = (meas_conf & MEAS_CONF_MASK) |  (data->rate << RATE_OFFSET);
+	return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+}
+
+static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
+						struct device_attribute *attr,
+						char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	return sprintf(buf, "%d\n", data->meas_conf);
+}
+
+static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t count)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+	struct hmc5843_data *data = i2c_get_clientdata(client);
+	unsigned long meas_conf = 0;
+	int error = strict_strtoul(buf, 10, &meas_conf);
+	if (error)
+		return error;
+	mutex_lock(&data->lock);
+
+	dev_dbg(dev, "set mode to %lu\n", meas_conf);
+	if (hmc5843_set_meas_conf(client, meas_conf)) {
+		count = -EINVAL;
+		goto exit;
+	}
+	data->meas_conf = meas_conf;
+
+exit:
+	mutex_unlock(&data->lock);
+	return count;
+}
+static IIO_DEVICE_ATTR(meas_conf,
+			S_IWUSR | S_IRUGO,
+			hmc5843_show_measurement_configuration,
+			hmc5843_set_measurement_configuration,
+			0);
+
+/*
+ * From Datasheet
+ * The table shows the minimum data output
+ * Value	| Minimum data output rate(Hz)
+ * 0		| 0.5
+ * 1		| 1
+ * 2		| 2
+ * 3		| 5
+ * 4		| 10 (default)
+ * 5		| 20
+ * 6		| 50
+ * 7		| Not used
+ */
+static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
+
+static s32 hmc5843_set_rate(struct i2c_client *client,
+				u8 rate)
+{
+	struct hmc5843_data *data = i2c_get_clientdata(client);
+	u8 reg_val;
+
+	reg_val = (data->meas_conf) |  (rate << RATE_OFFSET);
+	if (rate >= RATE_NOT_USED) {
+		dev_err(&client->dev,
+			"This data output rate is not supported \n");
+		return -EINVAL;
+	}
+	return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+}
+
+static ssize_t set_sampling_frequency(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	unsigned long rate = 0;
+
+	if (strncmp(buf, "0.5" , 3) == 0)
+		rate = RATE_5;
+	else if (strncmp(buf, "1" , 1) == 0)
+		rate = RATE_10;
+	else if (strncmp(buf, "2", 1) == 0)
+		rate = RATE_20;
+	else if (strncmp(buf, "5", 1) == 0)
+		rate = RATE_50;
+	else if (strncmp(buf, "10", 2) == 0)
+		rate = RATE_100;
+	else if (strncmp(buf, "20" , 2) == 0)
+		rate = RATE_200;
+	else if (strncmp(buf, "50" , 2) == 0)
+		rate = RATE_500;
+	else
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+	dev_dbg(dev, "set rate to %lu\n", rate);
+	if (hmc5843_set_rate(client, rate)) {
+		count = -EINVAL;
+		goto exit;
+	}
+	data->rate = rate;
+
+exit:
+	mutex_unlock(&data->lock);
+	return count;
+}
+
+static ssize_t show_sampling_frequency(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	u32 rate;
+
+	rate = i2c_smbus_read_byte_data(client,  this_attr->address);
+	if (rate < 0)
+		return -EINVAL;
+	rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
+	return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
+}
+static IIO_DEVICE_ATTR(sampling_frequency,
+			S_IWUSR | S_IRUGO,
+			show_sampling_frequency,
+			set_sampling_frequency,
+			HMC5843_CONFIG_REG_A);
+
+/*
+ * From Datasheet
+ *	Nominal gain settings
+ * Value	| Sensor Input Field Range(Ga)	| Gain(counts/ milli-gauss)
+ *0		|(+-)0.7			|1620
+ *1		|(+-)1.0			|1300
+ *2		|(+-)1.5			|970
+ *3		|(+-)2.0			|780
+ *4		|(+-)3.2			|530
+ *5		|(+-)3.8			|460
+ *6		|(+-)4.5			|390
+ *7		|(+-)6.5			|280
+ */
+static ssize_t show_range(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	u8 range;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct hmc5843_data *data = indio_dev->dev_data;
+
+	range = data->range;
+	return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
+}
+
+static ssize_t set_range(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf,
+			size_t count)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	unsigned long range = 0;
+	int error;
+	mutex_lock(&data->lock);
+	error = strict_strtoul(buf, 10, &range);
+	if (error)
+		return error;
+	dev_dbg(dev, "set range to %lu\n", range);
+
+	if (range > RANGE_6_5)
+		return -EINVAL;
+
+	data->range = range;
+	range = range << RANGE_GAIN_OFFSET;
+	if (i2c_smbus_write_byte_data(client, this_attr->address, range))
+		count = -EINVAL;
+
+	mutex_unlock(&data->lock);
+	return count;
+
+}
+static IIO_DEVICE_ATTR(magn_range,
+			S_IWUSR | S_IRUGO,
+			show_range,
+			set_range,
+			HMC5843_CONFIG_REG_B);
+
+static ssize_t show_gain(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct hmc5843_data *data = indio_dev->dev_data;
+	return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
+}
+static IIO_DEVICE_ATTR(magn_gain,
+			S_IRUGO,
+			show_gain,
+			NULL , 0);
+
+static struct attribute *hmc5843_attributes[] = {
+	&iio_dev_attr_meas_conf.dev_attr.attr,
+	&iio_dev_attr_operating_mode.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_magn_range.dev_attr.attr,
+	&iio_dev_attr_magn_gain.dev_attr.attr,
+	&iio_dev_attr_magn_x_raw.dev_attr.attr,
+	&iio_dev_attr_magn_y_raw.dev_attr.attr,
+	&iio_dev_attr_magn_z_raw.dev_attr.attr,
+	&iio_const_attr_available_sampling_frequency.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group hmc5843_group = {
+	.attrs = hmc5843_attributes,
+};
+
+static int hmc5843_detect(struct i2c_client *client,
+			  struct i2c_board_info *info)
+{
+	unsigned char id_str[HMC5843_ID_REG_LENGTH];
+
+	if (client->addr != HMC5843_I2C_ADDRESS)
+		return -ENODEV;
+
+	if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
+				HMC5843_ID_REG_LENGTH, id_str)
+			!= HMC5843_ID_REG_LENGTH)
+		return -ENODEV;
+
+	if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
+		return -ENODEV;
+
+	return 0;
+}
+
+/* Called when we have found a new HMC5843. */
+static void hmc5843_init_client(struct i2c_client *client)
+{
+	struct hmc5843_data *data = i2c_get_clientdata(client);
+	hmc5843_set_meas_conf(client, data->meas_conf);
+	hmc5843_set_rate(client, data->rate);
+	hmc5843_configure(client, data->operating_mode);
+	i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
+	mutex_init(&data->lock);
+	pr_info("HMC5843 initialized\n");
+}
+
+static int hmc5843_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct hmc5843_data *data;
+	int err = 0;
+
+	data = kzalloc(sizeof(struct hmc5843_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	/* default settings at probe */
+
+	data->meas_conf = CONF_NORMAL;
+	data->range = RANGE_1_0;
+	data->operating_mode = MODE_CONVERSION_CONTINUOUS;
+
+	i2c_set_clientdata(client, data);
+
+	/* Initialize the HMC5843 chip */
+	hmc5843_init_client(client);
+
+	data->indio_dev = iio_allocate_device();
+	if (!data->indio_dev) {
+		err = -ENOMEM;
+		goto exit_free;
+	}
+	data->indio_dev->attrs = &hmc5843_group;
+	data->indio_dev->dev.parent = &client->dev;
+	data->indio_dev->dev_data = (void *)(data);
+	data->indio_dev->driver_module = THIS_MODULE;
+	data->indio_dev->modes = INDIO_DIRECT_MODE;
+	err = iio_device_register(data->indio_dev);
+	if (err)
+		goto exit_free;
+	return 0;
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int hmc5843_remove(struct i2c_client *client)
+{
+	struct hmc5843_data *data = i2c_get_clientdata(client);
+	 /*  sleep mode to save power */
+	hmc5843_configure(client, MODE_SLEEP);
+	iio_device_unregister(data->indio_dev);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	hmc5843_configure(client, MODE_SLEEP);
+	return 0;
+}
+
+static int hmc5843_resume(struct i2c_client *client)
+{
+	struct hmc5843_data *data = i2c_get_clientdata(client);
+	hmc5843_configure(client, data->operating_mode);
+	return 0;
+}
+
+static const struct i2c_device_id hmc5843_id[] = {
+	{ "hmc5843", 0 },
+	{ }
+};
+
+static struct i2c_driver hmc5843_driver = {
+	.driver = {
+		.name	= "hmc5843",
+	},
+	.id_table	= hmc5843_id,
+	.probe		= hmc5843_probe,
+	.remove		= hmc5843_remove,
+	.detect		= hmc5843_detect,
+	.address_list	= normal_i2c,
+	.suspend	= hmc5843_suspend,
+	.resume		= hmc5843_resume,
+};
+
+static int __init hmc5843_init(void)
+{
+	return i2c_add_driver(&hmc5843_driver);
+}
+
+static void __exit hmc5843_exit(void)
+{
+	i2c_del_driver(&hmc5843_driver);
+}
+
+MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
+MODULE_DESCRIPTION("HMC5843 driver");
+MODULE_LICENSE("GPL");
+
+module_init(hmc5843_init);
+module_exit(hmc5843_exit);
-- 
1.5.4.7


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* RE: [PATCH] digital compass hmc5843
  2010-07-06 11:08 Shubhrajyoti D
@ 2010-07-06 11:09 ` Datta, Shubhrajyoti
  0 siblings, 0 replies; 5+ messages in thread
From: Datta, Shubhrajyoti @ 2010-07-06 11:09 UTC (permalink / raw)
  To: Datta, Shubhrajyoti, linux-iio@vger.kernel.org; +Cc: sfking@fdwdc.com



> -----Original Message-----
> From: Datta, Shubhrajyoti
> Sent: Tuesday, July 06, 2010 4:38 PM
> To: linux-iio@vger.kernel.org
> Cc: sfking@fdwdc.com; Datta, Shubhrajyoti
> Subject: [PATCH] digital compass hmc5843
>
> Adding support for the Honeywell HMC5843. The interface to the device is
> i2c.
>
> - Changing the interface to suit the standards
>
> TODO
> - Documentation for the interface provided
> - Gauss is reported in millig
>
Adds some lock protection for the cached cases
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/staging/iio/Kconfig                |    1 +
>  drivers/staging/iio/Makefile               |    1 +
>  drivers/staging/iio/magnetometer/Kconfig   |   15 +
>  drivers/staging/iio/magnetometer/Makefile  |    5 +
>  drivers/staging/iio/magnetometer/hmc5843.c |  622
> ++++++++++++++++++++++++++++
>  5 files changed, 644 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/staging/iio/magnetometer/Kconfig
>  create mode 100644 drivers/staging/iio/magnetometer/Makefile
>  create mode 100644 drivers/staging/iio/magnetometer/hmc5843.c
>
> diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
> index b0e6244..569b938 100644
> --- a/drivers/staging/iio/Kconfig
> +++ b/drivers/staging/iio/Kconfig
> @@ -44,6 +44,7 @@ source "drivers/staging/iio/adc/Kconfig"
>  source "drivers/staging/iio/gyro/Kconfig"
>  source "drivers/staging/iio/imu/Kconfig"
>  source "drivers/staging/iio/light/Kconfig"
> +source "drivers/staging/iio/magnetometer/Kconfig"
>
>  source "drivers/staging/iio/trigger/Kconfig"
>
> diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
> index 3502b39..10d1f6b 100644
> --- a/drivers/staging/iio/Makefile
> +++ b/drivers/staging/iio/Makefile
> @@ -14,5 +14,6 @@ obj-y += adc/
>  obj-y += gyro/
>  obj-y += imu/
>  obj-y += light/
> +obj-y += magnetometer/
>
>  obj-y += trigger/
> \ No newline at end of file
> diff --git a/drivers/staging/iio/magnetometer/Kconfig
> b/drivers/staging/iio/magnetometer/Kconfig
> new file mode 100644
> index 0000000..d014450
> --- /dev/null
> +++ b/drivers/staging/iio/magnetometer/Kconfig
> @@ -0,0 +1,15 @@
> +#
> +# Magnetometer sensors
> +#
> +comment "Magnetometer sensors"
> +
> +config SENSORS_HMC5843
> +     tristate "Honeywell HMC5843 3-Axis Magnetometer"
> +     depends on I2C
> +     help
> +       Say Y here to add support for the Honeywell HMC 5843 3-Axis
> +       Magnetometer (digital compass).
> +
> +       To compile this driver as a module, choose M here: the module
> +       will be called hmc5843
> +
> diff --git a/drivers/staging/iio/magnetometer/Makefile
> b/drivers/staging/iio/magnetometer/Makefile
> new file mode 100644
> index 0000000..f9bfb2e
> --- /dev/null
> +++ b/drivers/staging/iio/magnetometer/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Makefile for industrial I/O Magnetometer sensors
> +#
> +
> +obj-$(CONFIG_SENSORS_HMC5843)        += hmc5843.o
> diff --git a/drivers/staging/iio/magnetometer/hmc5843.c
> b/drivers/staging/iio/magnetometer/hmc5843.c
> new file mode 100644
> index 0000000..58d275a
> --- /dev/null
> +++ b/drivers/staging/iio/magnetometer/hmc5843.c
> @@ -0,0 +1,622 @@
> +/*  Copyright (C) 2010 Texas Instruments
> +    Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
> +    Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable
> inputs.
> +
> +    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., 675 Mass Ave, Cambridge, MA 02139, USA.
> +*/
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/i2c.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +#include "../iio.h"
> +#include "../sysfs.h"
> +#include "magnet.h"
> +
> +#define HMC5843_I2C_ADDRESS                  0x1E
> +
> +#define HMC5843_CONFIG_REG_A                 0x00
> +#define HMC5843_CONFIG_REG_B                 0x01
> +#define HMC5843_MODE_REG                     0x02
> +#define HMC5843_DATA_OUT_X_MSB_REG           0x03
> +#define HMC5843_DATA_OUT_X_LSB_REG           0x04
> +#define HMC5843_DATA_OUT_Y_MSB_REG           0x05
> +#define HMC5843_DATA_OUT_Y_LSB_REG           0x06
> +#define HMC5843_DATA_OUT_Z_MSB_REG           0x07
> +#define HMC5843_DATA_OUT_Z_LSB_REG           0x08
> +#define HMC5843_STATUS_REG                   0x09
> +#define HMC5843_ID_REG_A                     0x0A
> +#define HMC5843_ID_REG_B                     0x0B
> +#define HMC5843_ID_REG_C                     0x0C
> +
> +#define HMC5843_ID_REG_LENGTH                        0x03
> +#define HMC5843_ID_STRING                    "H43"
> +
> +/*
> + * Range settings in  (+-)Ga
> + * */
> +#define RANGE_GAIN_OFFSET                    0x05
> +
> +#define      RANGE_0_7                               0x00
> +#define      RANGE_1_0                               0x01 /* default */
> +#define      RANGE_1_5                               0x02
> +#define      RANGE_2_0                               0x03
> +#define      RANGE_3_2                               0x04
> +#define      RANGE_3_8                               0x05
> +#define      RANGE_4_5                               0x06
> +#define      RANGE_6_5                               0x07 /* Not recommended */
> +
> +/*
> + * Device status
> + */
> +#define      DATA_READY                              0x01
> +#define      DATA_OUTPUT_LOCK                        0x02
> +#define      VOLTAGE_REGULATOR_ENABLED               0x04
> +
> +/*
> + * Mode register configuration
> + */
> +#define      MODE_CONVERSION_CONTINUOUS              0x00
> +#define      MODE_CONVERSION_SINGLE                  0x01
> +#define      MODE_IDLE                               0x02
> +#define      MODE_SLEEP                              0x03
> +
> +/* Minimum Data Output Rate in 1/10 Hz  */
> +#define RATE_OFFSET                          0x02
> +#define RATE_BITMASK                         0x1C
> +#define      RATE_5                                  0x00
> +#define      RATE_10                                 0x01
> +#define      RATE_20                                 0x02
> +#define      RATE_50                                 0x03
> +#define      RATE_100                                0x04
> +#define      RATE_200                                0x05
> +#define      RATE_500                                0x06
> +#define      RATE_NOT_USED                           0x07
> +
> +/*
> + * Device Configutration
> + */
> +#define      CONF_NORMAL                             0x00
> +#define      CONF_POSITIVE_BIAS                      0x01
> +#define      CONF_NEGATIVE_BIAS                      0x02
> +#define      CONF_NOT_USED                           0x03
> +#define      MEAS_CONF_MASK                          0x03
> +
> +static const int regval_to_counts_per_mg[] = {
> +     1620,
> +     1300,
> +     970,
> +     780,
> +     530,
> +     460,
> +     390,
> +     280
> +};
> +static const int regval_to_input_field_mg[] = {
> +     700,
> +     1000,
> +     1500,
> +     2000,
> +     3200,
> +     3800,
> +     4500,
> +     6500
> +};
> +static const char *regval_to_samp_freq[] = {
> +     "0.5",
> +     "1",
> +     "2",
> +     "5",
> +     "10",
> +     "20",
> +     "50",
> +};
> +
> +/* Addresses to scan: 0x1E */
> +static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
> +                                                     I2C_CLIENT_END };
> +
> +/* Each client has this additional data */
> +struct hmc5843_data {
> +     struct iio_dev  *indio_dev;
> +     struct mutex lock;
> +     u8              rate;
> +     u8              meas_conf;
> +     u8              operating_mode;
> +     u8              range;
> +};
> +
> +static void hmc5843_init_client(struct i2c_client *client);
> +
> +static s32 hmc5843_configure(struct i2c_client *client,
> +                                    u8 operating_mode)
> +{
> +     /* The lower two bits contain the current conversion mode */
> +     return i2c_smbus_write_byte_data(client,
> +                                     HMC5843_MODE_REG,
> +                                     (operating_mode & 0x03));
> +}
> +
> +/* Return the measurement value from the  specified channel */
> +static ssize_t hmc5843_read_measurement(struct device *dev,
> +             struct device_attribute *attr,
> +             char *buf)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
> +     s16 coordinate_val;
> +     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     s32 result;
> +
> +     mutex_lock(&data->lock);
> +
> +     result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
> +     while (!(result & DATA_READY))
> +             result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
> +
> +     result = i2c_smbus_read_word_data(client, this_attr->address);
> +     mutex_unlock(&data->lock);
> +     if (result < 0)
> +             return -EINVAL;
> +
> +     coordinate_val  = (s16)swab16((u16)result);
> +     return sprintf(buf, "%d\n", coordinate_val);
> +}
> +static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
> +             HMC5843_DATA_OUT_X_MSB_REG);
> +static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
> +             HMC5843_DATA_OUT_Y_MSB_REG);
> +static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
> +             HMC5843_DATA_OUT_Z_MSB_REG);
> +
> +/*
> + * From the datasheet
> + * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
> + * device continuously performs conversions an places the result in the
> + * data register.
> + *
> + * 1 - Single-Conversion Mode : device performs a single measurement,
> + *  sets RDY high and returned to sleep mode
> + *
> + * 2 - Idle Mode :  Device is placed in idle mode.
> + *
> + * 3 - Sleep Mode. Device is placed in sleep mode.
> + *
> + */
> +static ssize_t hmc5843_show_operating_mode(struct device *dev,
> +                                     struct device_attribute *attr,
> +                                     char *buf)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     return sprintf(buf, "%d\n", data->operating_mode);
> +}
> +
> +static ssize_t hmc5843_set_operating_mode(struct device *dev,
> +                             struct device_attribute *attr,
> +                             const char *buf,
> +                             size_t count)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> +     unsigned long operating_mode = 0;
> +     s32 status;
> +     int error;
> +     mutex_lock(&data->lock);
> +     error = strict_strtoul(buf, 10, &operating_mode);
> +     if (error)
> +             return error;
> +     dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
> +     if (operating_mode > MODE_SLEEP)
> +                     return -EINVAL;
> +
> +     status = i2c_smbus_write_byte_data(client, this_attr->address,
> +                                     operating_mode);
> +     if (status) {
> +             count = -EINVAL;
> +             goto exit;
> +     }
> +     data->operating_mode = operating_mode;
> +
> +exit:
> +     mutex_unlock(&data->lock);
> +     return count;
> +}
> +static IIO_DEVICE_ATTR(operating_mode,
> +                     S_IWUSR | S_IRUGO,
> +                     hmc5843_show_operating_mode,
> +                     hmc5843_set_operating_mode,
> +                     HMC5843_MODE_REG);
> +
> +/*
> + * API for setting the measurement configuration to
> + * Normal, Positive bias and Negative bias
> + * From the datasheet
> + *
> + * Normal measurement configuration (default): In normal measurement
> + * configuration the device follows normal measurement flow. Pins BP and
> BN
> + * are left floating and high impedance.
> + *
> + * Positive bias configuration: In positive bias configuration, a
> positive
> + * current is forced across the resistive load on pins BP and BN.
> + *
> + * Negative bias configuration. In negative bias configuration, a
> negative
> + * current is forced across the resistive load on pins BP and BN.
> + *
> + */
> +static s32 hmc5843_set_meas_conf(struct i2c_client *client,
> +                                   u8 meas_conf)
> +{
> +     struct hmc5843_data *data = i2c_get_clientdata(client);
> +     u8 reg_val;
> +     reg_val = (meas_conf & MEAS_CONF_MASK) |  (data->rate <<
> RATE_OFFSET);
> +     return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A,
> reg_val);
> +}
> +
> +static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
> +                                             struct device_attribute *attr,
> +                                             char *buf)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     return sprintf(buf, "%d\n", data->meas_conf);
> +}
> +
> +static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
> +                                             struct device_attribute *attr,
> +                                             const char *buf,
> +                                             size_t count)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
> +     struct hmc5843_data *data = i2c_get_clientdata(client);
> +     unsigned long meas_conf = 0;
> +     int error = strict_strtoul(buf, 10, &meas_conf);
> +     if (error)
> +             return error;
> +     mutex_lock(&data->lock);
> +
> +     dev_dbg(dev, "set mode to %lu\n", meas_conf);
> +     if (hmc5843_set_meas_conf(client, meas_conf)) {
> +             count = -EINVAL;
> +             goto exit;
> +     }
> +     data->meas_conf = meas_conf;
> +
> +exit:
> +     mutex_unlock(&data->lock);
> +     return count;
> +}
> +static IIO_DEVICE_ATTR(meas_conf,
> +                     S_IWUSR | S_IRUGO,
> +                     hmc5843_show_measurement_configuration,
> +                     hmc5843_set_measurement_configuration,
> +                     0);
> +
> +/*
> + * From Datasheet
> + * The table shows the minimum data output
> + * Value     | Minimum data output rate(Hz)
> + * 0         | 0.5
> + * 1         | 1
> + * 2         | 2
> + * 3         | 5
> + * 4         | 10 (default)
> + * 5         | 20
> + * 6         | 50
> + * 7         | Not used
> + */
> +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
> +
> +static s32 hmc5843_set_rate(struct i2c_client *client,
> +                             u8 rate)
> +{
> +     struct hmc5843_data *data = i2c_get_clientdata(client);
> +     u8 reg_val;
> +
> +     reg_val = (data->meas_conf) |  (rate << RATE_OFFSET);
> +     if (rate >= RATE_NOT_USED) {
> +             dev_err(&client->dev,
> +                     "This data output rate is not supported \n");
> +             return -EINVAL;
> +     }
> +     return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A,
> reg_val);
> +}
> +
> +static ssize_t set_sampling_frequency(struct device *dev,
> +                                     struct device_attribute *attr,
> +                                     const char *buf, size_t count)
> +{
> +
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     unsigned long rate = 0;
> +
> +     if (strncmp(buf, "0.5" , 3) == 0)
> +             rate = RATE_5;
> +     else if (strncmp(buf, "1" , 1) == 0)
> +             rate = RATE_10;
> +     else if (strncmp(buf, "2", 1) == 0)
> +             rate = RATE_20;
> +     else if (strncmp(buf, "5", 1) == 0)
> +             rate = RATE_50;
> +     else if (strncmp(buf, "10", 2) == 0)
> +             rate = RATE_100;
> +     else if (strncmp(buf, "20" , 2) == 0)
> +             rate = RATE_200;
> +     else if (strncmp(buf, "50" , 2) == 0)
> +             rate = RATE_500;
> +     else
> +             return -EINVAL;
> +
> +     mutex_lock(&data->lock);
> +     dev_dbg(dev, "set rate to %lu\n", rate);
> +     if (hmc5843_set_rate(client, rate)) {
> +             count = -EINVAL;
> +             goto exit;
> +     }
> +     data->rate = rate;
> +
> +exit:
> +     mutex_unlock(&data->lock);
> +     return count;
> +}
> +
> +static ssize_t show_sampling_frequency(struct device *dev,
> +                     struct device_attribute *attr, char *buf)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
> +     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> +     u32 rate;
> +
> +     rate = i2c_smbus_read_byte_data(client,  this_attr->address);
> +     if (rate < 0)
> +             return -EINVAL;
> +     rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
> +     return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
> +}
> +static IIO_DEVICE_ATTR(sampling_frequency,
> +                     S_IWUSR | S_IRUGO,
> +                     show_sampling_frequency,
> +                     set_sampling_frequency,
> +                     HMC5843_CONFIG_REG_A);
> +
> +/*
> + * From Datasheet
> + *   Nominal gain settings
> + * Value     | Sensor Input Field Range(Ga)  | Gain(counts/ milli-
> gauss)
> + *0          |(+-)0.7                        |1620
> + *1          |(+-)1.0                        |1300
> + *2          |(+-)1.5                        |970
> + *3          |(+-)2.0                        |780
> + *4          |(+-)3.2                        |530
> + *5          |(+-)3.8                        |460
> + *6          |(+-)4.5                        |390
> + *7          |(+-)6.5                        |280
> + */
> +static ssize_t show_range(struct device *dev,
> +                             struct device_attribute *attr,
> +                             char *buf)
> +{
> +     u8 range;
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +
> +     range = data->range;
> +     return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
> +}
> +
> +static ssize_t set_range(struct device *dev,
> +                     struct device_attribute *attr,
> +                     const char *buf,
> +                     size_t count)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
> +     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     unsigned long range = 0;
> +     int error;
> +     mutex_lock(&data->lock);
> +     error = strict_strtoul(buf, 10, &range);
> +     if (error)
> +             return error;
> +     dev_dbg(dev, "set range to %lu\n", range);
> +
> +     if (range > RANGE_6_5)
> +             return -EINVAL;
> +
> +     data->range = range;
> +     range = range << RANGE_GAIN_OFFSET;
> +     if (i2c_smbus_write_byte_data(client, this_attr->address, range))
> +             count = -EINVAL;
> +
> +     mutex_unlock(&data->lock);
> +     return count;
> +
> +}
> +static IIO_DEVICE_ATTR(magn_range,
> +                     S_IWUSR | S_IRUGO,
> +                     show_range,
> +                     set_range,
> +                     HMC5843_CONFIG_REG_B);
> +
> +static ssize_t show_gain(struct device *dev,
> +                     struct device_attribute *attr,
> +                     char *buf)
> +{
> +     struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +     struct hmc5843_data *data = indio_dev->dev_data;
> +     return sprintf(buf, "%d\n", regval_to_counts_per_mg[data->range]);
> +}
> +static IIO_DEVICE_ATTR(magn_gain,
> +                     S_IRUGO,
> +                     show_gain,
> +                     NULL , 0);
> +
> +static struct attribute *hmc5843_attributes[] = {
> +     &iio_dev_attr_meas_conf.dev_attr.attr,
> +     &iio_dev_attr_operating_mode.dev_attr.attr,
> +     &iio_dev_attr_sampling_frequency.dev_attr.attr,
> +     &iio_dev_attr_magn_range.dev_attr.attr,
> +     &iio_dev_attr_magn_gain.dev_attr.attr,
> +     &iio_dev_attr_magn_x_raw.dev_attr.attr,
> +     &iio_dev_attr_magn_y_raw.dev_attr.attr,
> +     &iio_dev_attr_magn_z_raw.dev_attr.attr,
> +     &iio_const_attr_available_sampling_frequency.dev_attr.attr,
> +     NULL
> +};
> +
> +static const struct attribute_group hmc5843_group = {
> +     .attrs = hmc5843_attributes,
> +};
> +
> +static int hmc5843_detect(struct i2c_client *client,
> +                       struct i2c_board_info *info)
> +{
> +     unsigned char id_str[HMC5843_ID_REG_LENGTH];
> +
> +     if (client->addr != HMC5843_I2C_ADDRESS)
> +             return -ENODEV;
> +
> +     if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
> +                             HMC5843_ID_REG_LENGTH, id_str)
> +                     != HMC5843_ID_REG_LENGTH)
> +             return -ENODEV;
> +
> +     if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
> +             return -ENODEV;
> +
> +     return 0;
> +}
> +
> +/* Called when we have found a new HMC5843. */
> +static void hmc5843_init_client(struct i2c_client *client)
> +{
> +     struct hmc5843_data *data = i2c_get_clientdata(client);
> +     hmc5843_set_meas_conf(client, data->meas_conf);
> +     hmc5843_set_rate(client, data->rate);
> +     hmc5843_configure(client, data->operating_mode);
> +     i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data-
> >range);
> +     mutex_init(&data->lock);
> +     pr_info("HMC5843 initialized\n");
> +}
> +
> +static int hmc5843_probe(struct i2c_client *client,
> +                      const struct i2c_device_id *id)
> +{
> +     struct hmc5843_data *data;
> +     int err = 0;
> +
> +     data = kzalloc(sizeof(struct hmc5843_data), GFP_KERNEL);
> +     if (!data) {
> +             err = -ENOMEM;
> +             goto exit;
> +     }
> +
> +     /* default settings at probe */
> +
> +     data->meas_conf = CONF_NORMAL;
> +     data->range = RANGE_1_0;
> +     data->operating_mode = MODE_CONVERSION_CONTINUOUS;
> +
> +     i2c_set_clientdata(client, data);
> +
> +     /* Initialize the HMC5843 chip */
> +     hmc5843_init_client(client);
> +
> +     data->indio_dev = iio_allocate_device();
> +     if (!data->indio_dev) {
> +             err = -ENOMEM;
> +             goto exit_free;
> +     }
> +     data->indio_dev->attrs = &hmc5843_group;
> +     data->indio_dev->dev.parent = &client->dev;
> +     data->indio_dev->dev_data = (void *)(data);
> +     data->indio_dev->driver_module = THIS_MODULE;
> +     data->indio_dev->modes = INDIO_DIRECT_MODE;
> +     err = iio_device_register(data->indio_dev);
> +     if (err)
> +             goto exit_free;
> +     return 0;
> +exit_free:
> +     kfree(data);
> +exit:
> +     return err;
> +}
> +
> +static int hmc5843_remove(struct i2c_client *client)
> +{
> +     struct hmc5843_data *data = i2c_get_clientdata(client);
> +      /*  sleep mode to save power */
> +     hmc5843_configure(client, MODE_SLEEP);
> +     iio_device_unregister(data->indio_dev);
> +     kfree(i2c_get_clientdata(client));
> +     return 0;
> +}
> +
> +static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
> +{
> +     hmc5843_configure(client, MODE_SLEEP);
> +     return 0;
> +}
> +
> +static int hmc5843_resume(struct i2c_client *client)
> +{
> +     struct hmc5843_data *data = i2c_get_clientdata(client);
> +     hmc5843_configure(client, data->operating_mode);
> +     return 0;
> +}
> +
> +static const struct i2c_device_id hmc5843_id[] = {
> +     { "hmc5843", 0 },
> +     { }
> +};
> +
> +static struct i2c_driver hmc5843_driver = {
> +     .driver = {
> +             .name   = "hmc5843",
> +     },
> +     .id_table       = hmc5843_id,
> +     .probe          = hmc5843_probe,
> +     .remove         = hmc5843_remove,
> +     .detect         = hmc5843_detect,
> +     .address_list   = normal_i2c,
> +     .suspend        = hmc5843_suspend,
> +     .resume         = hmc5843_resume,
> +};
> +
> +static int __init hmc5843_init(void)
> +{
> +     return i2c_add_driver(&hmc5843_driver);
> +}
> +
> +static void __exit hmc5843_exit(void)
> +{
> +     i2c_del_driver(&hmc5843_driver);
> +}
> +
> +MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
> +MODULE_DESCRIPTION("HMC5843 driver");
> +MODULE_LICENSE("GPL");
> +
> +module_init(hmc5843_init);
> +module_exit(hmc5843_exit);
> --
> 1.5.4.7


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] digital compass hmc5843
       [not found] ` <AANLkTinsbpx2HVNlkSIHXY_huwllBDHObk_WAEFz0TQh@mail.gmail.com>
@ 2010-07-21 13:57   ` Datta, Shubhrajyoti
  2010-07-22 18:40   ` Greg KH
  1 sibling, 0 replies; 5+ messages in thread
From: Datta, Shubhrajyoti @ 2010-07-21 13:57 UTC (permalink / raw)
  To: Barry Song; +Cc: linux-iio@vger.kernel.org, gregkh@suse.de, Jonathan Cameron

PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBCYXJyeSBTb25nIFttYWlsdG86
MjFjbmJhb0BnbWFpbC5jb21dDQo+IFNlbnQ6IFdlZG5lc2RheSwgSnVseSAyMSwgMjAxMCAxOjE5
IFBNDQo+IFRvOiBEYXR0YSwgU2h1YmhyYWp5b3RpDQo+IENjOiBsaW51eC1paW9Admdlci5rZXJu
ZWwub3JnOyBncmVna2hAc3VzZS5kZQ0KPiBTdWJqZWN0OiBSZTogW1BBVENIXSBkaWdpdGFsIGNv
bXBhc3MgaG1jNTg0Mw0KPg0KPiBUaGUgcGF0Y2ggc2hvdWxkIGJlIHNlbnQgdG8gSm9uYXRoYW4g
Q2FtZXJvbiA8amljMjNAY2FtLmFjLnVrPi4NCj4gLWJhcnJ5DQpTdXJlDQo+DQo+IE9uIFNhdCwg
SnVsIDE3LCAyMDEwIGF0IDk6MDIgUE0sIFNodWJocmFqeW90aSBEIDxzaHViaHJhanlvdGlAdGku
Y29tPg0KPiB3cm90ZToNCj4gPiBBZGRpbmcgc3VwcG9ydCBmb3IgdGhlIEhvbmV5d2VsbCBITUM1
ODQzLiBUaGUgaW50ZXJmYWNlIHRvIHRoZSBkZXZpY2UgaXMNCj4gPiBpMmMNCj4gPg0KPiA+IFRP
RE86DQo+ID4gQWRkaW5nIHRoZSBkb2N1bWVudGF0aW9uDQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5
OiBTaHViaHJhanlvdGkgRCA8c2h1YmhyYWp5b3RpQHRpLmNvbT4NCj4gPiBBY2tlZC1ieTogSm9u
YXRoYW4gQ2FtZXJvbiA8amljMjNAY2FtLmFjLnVrPg0KPiA+IC0tLQ0KPiA+ICBkcml2ZXJzL3N0
YWdpbmcvaWlvL0tjb25maWcgICAgICAgICAgICAgICAgfCAgICAxICsNCj4gPiAgZHJpdmVycy9z
dGFnaW5nL2lpby9NYWtlZmlsZSAgICAgICAgICAgICAgIHwgICAgMSArDQo+ID4gIGRyaXZlcnMv
c3RhZ2luZy9paW8vbWFnbmV0b21ldGVyL0tjb25maWcgICB8ICAgMTUgKw0KPiA+ICBkcml2ZXJz
L3N0YWdpbmcvaWlvL21hZ25ldG9tZXRlci9NYWtlZmlsZSAgfCAgICA1ICsNCj4gPiAgZHJpdmVy
cy9zdGFnaW5nL2lpby9tYWduZXRvbWV0ZXIvaG1jNTg0My5jIHwgIDYyNA0KPiArKysrKysrKysr
KysrKysrKysrKysrKysrKysrDQo+ID4gIDUgZmlsZXMgY2hhbmdlZCwgNjQ2IGluc2VydGlvbnMo
KyksIDAgZGVsZXRpb25zKC0pDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3N0YWdp
bmcvaWlvL21hZ25ldG9tZXRlci9LY29uZmlnDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2
ZXJzL3N0YWdpbmcvaWlvL21hZ25ldG9tZXRlci9NYWtlZmlsZQ0KPiA+ICBjcmVhdGUgbW9kZSAx
MDA2NDQgZHJpdmVycy9zdGFnaW5nL2lpby9tYWduZXRvbWV0ZXIvaG1jNTg0My5jDQo+ID4NCj4g
PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9zdGFnaW5nL2lpby9LY29uZmlnIGIvZHJpdmVycy9zdGFn
aW5nL2lpby9LY29uZmlnDQo+ID4gaW5kZXggYjBlNjI0NC4uNTY5YjkzOCAxMDA2NDQNCj4gPiAt
LS0gYS9kcml2ZXJzL3N0YWdpbmcvaWlvL0tjb25maWcNCj4gPiArKysgYi9kcml2ZXJzL3N0YWdp
bmcvaWlvL0tjb25maWcNCj4gPiBAQCAtNDQsNiArNDQsNyBAQCBzb3VyY2UgImRyaXZlcnMvc3Rh
Z2luZy9paW8vYWRjL0tjb25maWciDQo+ID4gIHNvdXJjZSAiZHJpdmVycy9zdGFnaW5nL2lpby9n
eXJvL0tjb25maWciDQo+ID4gIHNvdXJjZSAiZHJpdmVycy9zdGFnaW5nL2lpby9pbXUvS2NvbmZp
ZyINCj4gPiAgc291cmNlICJkcml2ZXJzL3N0YWdpbmcvaWlvL2xpZ2h0L0tjb25maWciDQo+ID4g
K3NvdXJjZSAiZHJpdmVycy9zdGFnaW5nL2lpby9tYWduZXRvbWV0ZXIvS2NvbmZpZyINCj4gPg0K
PiA+ICBzb3VyY2UgImRyaXZlcnMvc3RhZ2luZy9paW8vdHJpZ2dlci9LY29uZmlnIg0KPiA+DQo+
ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvc3RhZ2luZy9paW8vTWFrZWZpbGUgYi9kcml2ZXJzL3N0
YWdpbmcvaWlvL01ha2VmaWxlDQo+ID4gaW5kZXggMzUwMmIzOS4uMTBkMWY2YiAxMDA2NDQNCj4g
PiAtLS0gYS9kcml2ZXJzL3N0YWdpbmcvaWlvL01ha2VmaWxlDQo+ID4gKysrIGIvZHJpdmVycy9z
dGFnaW5nL2lpby9NYWtlZmlsZQ0KPiA+IEBAIC0xNCw1ICsxNCw2IEBAIG9iai15ICs9IGFkYy8N
Cj4gPiAgb2JqLXkgKz0gZ3lyby8NCj4gPiAgb2JqLXkgKz0gaW11Lw0KPiA+ICBvYmoteSArPSBs
aWdodC8NCj4gPiArb2JqLXkgKz0gbWFnbmV0b21ldGVyLw0KPiA+DQo+ID4gIG9iai15ICs9IHRy
aWdnZXIvDQo+ID4gXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlDQo+ID4gZGlmZiAtLWdpdCBh
L2RyaXZlcnMvc3RhZ2luZy9paW8vbWFnbmV0b21ldGVyL0tjb25maWcNCj4gYi9kcml2ZXJzL3N0
YWdpbmcvaWlvL21hZ25ldG9tZXRlci9LY29uZmlnDQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQN
Cj4gPiBpbmRleCAwMDAwMDAwLi5kMDE0NDUwDQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBi
L2RyaXZlcnMvc3RhZ2luZy9paW8vbWFnbmV0b21ldGVyL0tjb25maWcNCj4gPiBAQCAtMCwwICsx
LDE1IEBADQo+ID4gKyMNCj4gPiArIyBNYWduZXRvbWV0ZXIgc2Vuc29ycw0KPiA+ICsjDQo+ID4g
K2NvbW1lbnQgIk1hZ25ldG9tZXRlciBzZW5zb3JzIg0KPiA+ICsNCj4gPiArY29uZmlnIFNFTlNP
UlNfSE1DNTg0Mw0KPiA+ICsgICAgICAgdHJpc3RhdGUgIkhvbmV5d2VsbCBITUM1ODQzIDMtQXhp
cyBNYWduZXRvbWV0ZXIiDQo+ID4gKyAgICAgICBkZXBlbmRzIG9uIEkyQw0KPiA+ICsgICAgICAg
aGVscA0KPiA+ICsgICAgICAgICBTYXkgWSBoZXJlIHRvIGFkZCBzdXBwb3J0IGZvciB0aGUgSG9u
ZXl3ZWxsIEhNQyA1ODQzIDMtQXhpcw0KPiA+ICsgICAgICAgICBNYWduZXRvbWV0ZXIgKGRpZ2l0
YWwgY29tcGFzcykuDQo+ID4gKw0KPiA+ICsgICAgICAgICBUbyBjb21waWxlIHRoaXMgZHJpdmVy
IGFzIGEgbW9kdWxlLCBjaG9vc2UgTSBoZXJlOiB0aGUgbW9kdWxlDQo+ID4gKyAgICAgICAgIHdp
bGwgYmUgY2FsbGVkIGhtYzU4NDMNCj4gPiArDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvc3Rh
Z2luZy9paW8vbWFnbmV0b21ldGVyL01ha2VmaWxlDQo+IGIvZHJpdmVycy9zdGFnaW5nL2lpby9t
YWduZXRvbWV0ZXIvTWFrZWZpbGUNCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4
IDAwMDAwMDAuLmY5YmZiMmUNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9z
dGFnaW5nL2lpby9tYWduZXRvbWV0ZXIvTWFrZWZpbGUNCj4gPiBAQCAtMCwwICsxLDUgQEANCj4g
PiArIw0KPiA+ICsjIE1ha2VmaWxlIGZvciBpbmR1c3RyaWFsIEkvTyBNYWduZXRvbWV0ZXIgc2Vu
c29ycw0KPiA+ICsjDQo+ID4gKw0KPiA+ICtvYmotJChDT05GSUdfU0VOU09SU19ITUM1ODQzKSAg
Kz0gaG1jNTg0My5vDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvc3RhZ2luZy9paW8vbWFnbmV0
b21ldGVyL2htYzU4NDMuYw0KPiBiL2RyaXZlcnMvc3RhZ2luZy9paW8vbWFnbmV0b21ldGVyL2ht
YzU4NDMuYw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMC4uOTJm
NmM2Zg0KPiA+IC0tLSAvZGV2L251bGwNCj4gPiArKysgYi9kcml2ZXJzL3N0YWdpbmcvaWlvL21h
Z25ldG9tZXRlci9obWM1ODQzLmMNCj4gPiBAQCAtMCwwICsxLDYyNCBAQA0KPiA+ICsvKiAgQ29w
eXJpZ2h0IChDKSAyMDEwIFRleGFzIEluc3RydW1lbnRzDQo+ID4gKyAgICBBdXRob3I6IFNodWJo
cmFqeW90aSBEYXR0YSA8c2h1YmhyYWp5b3RpQHRpLmNvbT4NCj4gPiArICAgIEFja25vd2xlZGdl
bWVudDogSm9uYXRoYW4gQ2FtZXJvbiA8amljMjNAY2FtLmFjLnVrPiBmb3IgdmFsdWFibGUNCj4g
aW5wdXRzLg0KPiA+ICsNCj4gPiArICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5
b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3INCj4gbW9kaWZ5DQo+ID4gKyAgICBpdCB1bmRl
ciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hl
ZA0KPiBieQ0KPiA+ICsgICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZl
cnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3INCj4gPiArICAgIChhdCB5b3VyIG9wdGlvbikgYW55
IGxhdGVyIHZlcnNpb24uDQo+ID4gKw0KPiA+ICsgICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1
dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQo+ID4gKyAgICBidXQgV0lU
SE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0K
PiA+ICsgICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQ
T1NFLiAgU2VlIHRoZQ0KPiA+ICsgICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1v
cmUgZGV0YWlscy4NCj4gPiArDQo+ID4gKyAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBj
b3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQ0KPiA+ICsgICAgYWxvbmcgd2l0
aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUNCj4gPiAr
ICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwg
VVNBLg0KPiA+ICsqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiA+
ICsjaW5jbHVkZSA8bGludXgvaW5pdC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+DQo+
ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC90eXBlcy5o
Pg0KPiA+ICsjaW5jbHVkZSAiLi4vaWlvLmgiDQo+ID4gKyNpbmNsdWRlICIuLi9zeXNmcy5oIg0K
PiA+ICsjaW5jbHVkZSAibWFnbmV0LmgiDQo+ID4gKw0KPiA+ICsjZGVmaW5lIEhNQzU4NDNfSTJD
X0FERFJFU1MgICAgICAgICAgICAgICAgICAgIDB4MUUNCj4gPiArDQo+ID4gKyNkZWZpbmUgSE1D
NTg0M19DT05GSUdfUkVHX0EgICAgICAgICAgICAgICAgICAgMHgwMA0KPiA+ICsjZGVmaW5lIEhN
QzU4NDNfQ09ORklHX1JFR19CICAgICAgICAgICAgICAgICAgIDB4MDENCj4gPiArI2RlZmluZSBI
TUM1ODQzX01PREVfUkVHICAgICAgICAgICAgICAgICAgICAgICAweDAyDQo+ID4gKyNkZWZpbmUg
SE1DNTg0M19EQVRBX09VVF9YX01TQl9SRUcgICAgICAgICAgICAgMHgwMw0KPiA+ICsjZGVmaW5l
IEhNQzU4NDNfREFUQV9PVVRfWF9MU0JfUkVHICAgICAgICAgICAgIDB4MDQNCj4gPiArI2RlZmlu
ZSBITUM1ODQzX0RBVEFfT1VUX1lfTVNCX1JFRyAgICAgICAgICAgICAweDA1DQo+ID4gKyNkZWZp
bmUgSE1DNTg0M19EQVRBX09VVF9ZX0xTQl9SRUcgICAgICAgICAgICAgMHgwNg0KPiA+ICsjZGVm
aW5lIEhNQzU4NDNfREFUQV9PVVRfWl9NU0JfUkVHICAgICAgICAgICAgIDB4MDcNCj4gPiArI2Rl
ZmluZSBITUM1ODQzX0RBVEFfT1VUX1pfTFNCX1JFRyAgICAgICAgICAgICAweDA4DQo+ID4gKyNk
ZWZpbmUgSE1DNTg0M19TVEFUVVNfUkVHICAgICAgICAgICAgICAgICAgICAgMHgwOQ0KPiA+ICsj
ZGVmaW5lIEhNQzU4NDNfSURfUkVHX0EgICAgICAgICAgICAgICAgICAgICAgIDB4MEENCj4gPiAr
I2RlZmluZSBITUM1ODQzX0lEX1JFR19CICAgICAgICAgICAgICAgICAgICAgICAweDBCDQo+ID4g
KyNkZWZpbmUgSE1DNTg0M19JRF9SRUdfQyAgICAgICAgICAgICAgICAgICAgICAgMHgwQw0KPiA+
ICsNCj4gPiArI2RlZmluZSBITUM1ODQzX0lEX1JFR19MRU5HVEggICAgICAgICAgICAgICAgICAw
eDAzDQo+ID4gKyNkZWZpbmUgSE1DNTg0M19JRF9TVFJJTkcgICAgICAgICAgICAgICAgICAgICAg
Ikg0MyINCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIFJhbmdlIHNldHRpbmdzIGluICAoKy0pR2EN
Cj4gPiArICogKi8NCj4gPiArI2RlZmluZSBSQU5HRV9HQUlOX09GRlNFVCAgICAgICAgICAgICAg
ICAgICAgICAweDA1DQo+ID4gKw0KPiA+ICsjZGVmaW5lICAgICAgICBSQU5HRV8wXzcgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgMHgwMA0KPiA+ICsjZGVmaW5lICAgICAgICBSQU5HRV8x
XzAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMSAvKiBkZWZhdWx0DQo+ICovDQo+
ID4gKyNkZWZpbmUgICAgICAgIFJBTkdFXzFfNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAweDAyDQo+ID4gKyNkZWZpbmUgICAgICAgIFJBTkdFXzJfMCAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAweDAzDQo+ID4gKyNkZWZpbmUgICAgICAgIFJBTkdFXzNfMiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAweDA0DQo+ID4gKyNkZWZpbmUgICAgICAgIFJBTkdFXzNfOCAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA1DQo+ID4gKyNkZWZpbmUgICAgICAgIFJB
TkdFXzRfNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA2DQo+ID4gKyNkZWZpbmUg
ICAgICAgIFJBTkdFXzZfNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA3IC8qIE5v
dA0KPiByZWNvbW1lbmRlZCAqLw0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogRGV2aWNlIHN0YXR1
cw0KPiA+ICsgKi8NCj4gPiArI2RlZmluZSAgICAgICAgREFUQV9SRUFEWSAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIDB4MDENCj4gPiArI2RlZmluZSAgICAgICAgREFUQV9PVVRQVVRfTE9D
SyAgICAgICAgICAgICAgICAgICAgICAgIDB4MDINCj4gPiArI2RlZmluZSAgICAgICAgVk9MVEFH
RV9SRUdVTEFUT1JfRU5BQkxFRCAgICAgICAgICAgICAgIDB4MDQNCj4gPiArDQo+ID4gKy8qDQo+
ID4gKyAqIE1vZGUgcmVnaXN0ZXIgY29uZmlndXJhdGlvbg0KPiA+ICsgKi8NCj4gPiArI2RlZmlu
ZSAgICAgICAgTU9ERV9DT05WRVJTSU9OX0NPTlRJTlVPVVMgICAgICAgICAgICAgIDB4MDANCj4g
PiArI2RlZmluZSAgICAgICAgTU9ERV9DT05WRVJTSU9OX1NJTkdMRSAgICAgICAgICAgICAgICAg
IDB4MDENCj4gPiArI2RlZmluZSAgICAgICAgTU9ERV9JRExFICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIDB4MDINCj4gPiArI2RlZmluZSAgICAgICAgTU9ERV9TTEVFUCAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIDB4MDMNCj4gPiArDQo+ID4gKy8qIE1pbmltdW0gRGF0YSBPdXRw
dXQgUmF0ZSBpbiAxLzEwIEh6ICAqLw0KPiA+ICsjZGVmaW5lIFJBVEVfT0ZGU0VUICAgICAgICAg
ICAgICAgICAgICAgICAgICAgIDB4MDINCj4gPiArI2RlZmluZSBSQVRFX0JJVE1BU0sgICAgICAg
ICAgICAgICAgICAgICAgICAgICAweDFDDQo+ID4gKyNkZWZpbmUgICAgICAgIFJBVEVfNSAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAwDQo+ID4gKyNkZWZpbmUgICAgICAgIFJB
VEVfMTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAxDQo+ID4gKyNkZWZpbmUg
ICAgICAgIFJBVEVfMjAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAyDQo+ID4g
KyNkZWZpbmUgICAgICAgIFJBVEVfNTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAw
eDAzDQo+ID4gKyNkZWZpbmUgICAgICAgIFJBVEVfMTAwICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAweDA0DQo+ID4gKyNkZWZpbmUgICAgICAgIFJBVEVfMjAwICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAweDA1DQo+ID4gKyNkZWZpbmUgICAgICAgIFJBVEVfNTAwICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAweDA2DQo+ID4gKyNkZWZpbmUgICAgICAgIFJBVEVf
Tk9UX1VTRUQgICAgICAgICAgICAgICAgICAgICAgICAgICAweDA3DQo+ID4gKw0KPiA+ICsvKg0K
PiA+ICsgKiBEZXZpY2UgQ29uZmlndXRyYXRpb24NCj4gPiArICovDQo+ID4gKyNkZWZpbmUgICAg
ICAgIENPTkZfTk9STUFMICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAwDQo+ID4gKyNk
ZWZpbmUgICAgICAgIENPTkZfUE9TSVRJVkVfQklBUyAgICAgICAgICAgICAgICAgICAgICAweDAx
DQo+ID4gKyNkZWZpbmUgICAgICAgIENPTkZfTkVHQVRJVkVfQklBUyAgICAgICAgICAgICAgICAg
ICAgICAweDAyDQo+ID4gKyNkZWZpbmUgICAgICAgIENPTkZfTk9UX1VTRUQgICAgICAgICAgICAg
ICAgICAgICAgICAgICAweDAzDQo+ID4gKyNkZWZpbmUgICAgICAgIE1FQVNfQ09ORl9NQVNLICAg
ICAgICAgICAgICAgICAgICAgICAgICAweDAzDQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgaW50
IHJlZ3ZhbF90b19jb3VudHNfcGVyX21nW10gPSB7DQo+ID4gKyAgICAgICAxNjIwLA0KPiA+ICsg
ICAgICAgMTMwMCwNCj4gPiArICAgICAgIDk3MCwNCj4gPiArICAgICAgIDc4MCwNCj4gPiArICAg
ICAgIDUzMCwNCj4gPiArICAgICAgIDQ2MCwNCj4gPiArICAgICAgIDM5MCwNCj4gPiArICAgICAg
IDI4MA0KPiA+ICt9Ow0KPiA+ICtzdGF0aWMgY29uc3QgaW50IHJlZ3ZhbF90b19pbnB1dF9maWVs
ZF9tZ1tdID0gew0KPiA+ICsgICAgICAgNzAwLA0KPiA+ICsgICAgICAgMTAwMCwNCj4gPiArICAg
ICAgIDE1MDAsDQo+ID4gKyAgICAgICAyMDAwLA0KPiA+ICsgICAgICAgMzIwMCwNCj4gPiArICAg
ICAgIDM4MDAsDQo+ID4gKyAgICAgICA0NTAwLA0KPiA+ICsgICAgICAgNjUwMA0KPiA+ICt9Ow0K
PiA+ICtzdGF0aWMgY29uc3QgY2hhciAqcmVndmFsX3RvX3NhbXBfZnJlcVtdID0gew0KPiA+ICsg
ICAgICAgIjAuNSIsDQo+ID4gKyAgICAgICAiMSIsDQo+ID4gKyAgICAgICAiMiIsDQo+ID4gKyAg
ICAgICAiNSIsDQo+ID4gKyAgICAgICAiMTAiLA0KPiA+ICsgICAgICAgIjIwIiwNCj4gPiArICAg
ICAgICI1MCIsDQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKiBBZGRyZXNzZXMgdG8gc2NhbjogMHgx
RSAqLw0KPiA+ICtzdGF0aWMgY29uc3QgdW5zaWduZWQgc2hvcnQgbm9ybWFsX2kyY1tdID0geyBI
TUM1ODQzX0kyQ19BRERSRVNTLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgSTJDX0NMSUVOVF9FTkQNCj4gfTsNCj4gPiArDQo+ID4g
Ky8qIEVhY2ggY2xpZW50IGhhcyB0aGlzIGFkZGl0aW9uYWwgZGF0YSAqLw0KPiA+ICtzdHJ1Y3Qg
aG1jNTg0M19kYXRhIHsNCj4gPiArICAgICAgIHN0cnVjdCBpaW9fZGV2ICAqaW5kaW9fZGV2Ow0K
PiA+ICsgICAgICAgc3RydWN0IG11dGV4IGxvY2s7DQo+ID4gKyAgICAgICB1OCAgICAgICAgICAg
ICAgcmF0ZTsNCj4gPiArICAgICAgIHU4ICAgICAgICAgICAgICBtZWFzX2NvbmY7DQo+ID4gKyAg
ICAgICB1OCAgICAgICAgICAgICAgb3BlcmF0aW5nX21vZGU7DQo+ID4gKyAgICAgICB1OCAgICAg
ICAgICAgICAgcmFuZ2U7DQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBobWM1ODQz
X2luaXRfY2xpZW50KHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpOw0KPiA+ICsNCj4gPiArc3Rh
dGljIHMzMiBobWM1ODQzX2NvbmZpZ3VyZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LA0KPiA+
ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHU4IG9wZXJhdGluZ19tb2Rl
KQ0KPiA+ICt7DQo+ID4gKyAgICAgICAvKiBUaGUgbG93ZXIgdHdvIGJpdHMgY29udGFpbiB0aGUg
Y3VycmVudCBjb252ZXJzaW9uIG1vZGUgKi8NCj4gPiArICAgICAgIHJldHVybiBpMmNfc21idXNf
d3JpdGVfYnl0ZV9kYXRhKGNsaWVudCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgSE1DNTg0M19NT0RFX1JFRywNCj4gPiArICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgKG9wZXJhdGluZ19tb2RlICYgMHgwMykpOw0KPiA+ICt9DQo+ID4g
Kw0KPiA+ICsvKiBSZXR1cm4gdGhlIG1lYXN1cmVtZW50IHZhbHVlIGZyb20gdGhlICBzcGVjaWZp
ZWQgY2hhbm5lbCAqLw0KPiA+ICtzdGF0aWMgc3NpemVfdCBobWM1ODQzX3JlYWRfbWVhc3VyZW1l
bnQoc3RydWN0IGRldmljZSAqZGV2LA0KPiA+ICsgICAgICAgICAgICAgICBzdHJ1Y3QgZGV2aWNl
X2F0dHJpYnV0ZSAqYXR0ciwNCj4gPiArICAgICAgICAgICAgICAgY2hhciAqYnVmKQ0KPiA+ICt7
DQo+ID4gKyAgICAgICBzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2ID0gZGV2X2dldF9kcnZkYXRh
KGRldik7DQo+ID4gKyAgICAgICBzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50ID0gdG9faTJjX2Ns
aWVudChpbmRpb19kZXYtDQo+ID5kZXYucGFyZW50KTsNCj4gPiArICAgICAgIHMxNiBjb29yZGlu
YXRlX3ZhbDsNCj4gPiArICAgICAgIHN0cnVjdCBpaW9fZGV2X2F0dHIgKnRoaXNfYXR0ciA9IHRv
X2lpb19kZXZfYXR0cihhdHRyKTsNCj4gPiArICAgICAgIHN0cnVjdCBobWM1ODQzX2RhdGEgKmRh
dGEgPSBpbmRpb19kZXYtPmRldl9kYXRhOw0KPiA+ICsgICAgICAgczMyIHJlc3VsdDsNCj4gPiAr
DQo+ID4gKyAgICAgICBtdXRleF9sb2NrKCZkYXRhLT5sb2NrKTsNCj4gPiArDQo+ID4gKyAgICAg
ICByZXN1bHQgPSBpMmNfc21idXNfcmVhZF9ieXRlX2RhdGEoY2xpZW50LCBITUM1ODQzX1NUQVRV
U19SRUcpOw0KPiA+ICsgICAgICAgd2hpbGUgKCEocmVzdWx0ICYgREFUQV9SRUFEWSkpDQo+ID4g
KyAgICAgICAgICAgICAgIHJlc3VsdCA9IGkyY19zbWJ1c19yZWFkX2J5dGVfZGF0YShjbGllbnQs
DQo+IEhNQzU4NDNfU1RBVFVTX1JFRyk7DQo+ID4gKw0KPiA+ICsgICAgICAgcmVzdWx0ID0gaTJj
X3NtYnVzX3JlYWRfd29yZF9kYXRhKGNsaWVudCwgdGhpc19hdHRyLT5hZGRyZXNzKTsNCj4gPiAr
ICAgICAgIG11dGV4X3VubG9jaygmZGF0YS0+bG9jayk7DQo+ID4gKyAgICAgICBpZiAocmVzdWx0
IDwgMCkNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsg
ICAgICAgY29vcmRpbmF0ZV92YWwgID0gKHMxNilzd2FiMTYoKHUxNilyZXN1bHQpOw0KPiA+ICsg
ICAgICAgcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGNvb3JkaW5hdGVfdmFsKTsNCj4gPiAr
fQ0KPiA+ICtzdGF0aWMgSUlPX0RFVl9BVFRSX01BR05fWChobWM1ODQzX3JlYWRfbWVhc3VyZW1l
bnQsDQo+ID4gKyAgICAgICAgICAgICAgIEhNQzU4NDNfREFUQV9PVVRfWF9NU0JfUkVHKTsNCj4g
PiArc3RhdGljIElJT19ERVZfQVRUUl9NQUdOX1koaG1jNTg0M19yZWFkX21lYXN1cmVtZW50LA0K
PiA+ICsgICAgICAgICAgICAgICBITUM1ODQzX0RBVEFfT1VUX1lfTVNCX1JFRyk7DQo+ID4gK3N0
YXRpYyBJSU9fREVWX0FUVFJfTUFHTl9aKGhtYzU4NDNfcmVhZF9tZWFzdXJlbWVudCwNCj4gPiAr
ICAgICAgICAgICAgICAgSE1DNTg0M19EQVRBX09VVF9aX01TQl9SRUcpOw0KPiA+ICsNCj4gPiAr
LyoNCj4gPiArICogRnJvbSB0aGUgZGF0YXNoZWV0DQo+ID4gKyAqIDAgLSBDb250aW51b3VzLUNv
bnZlcnNpb24gTW9kZTogSW4gY29udGludW91cy1jb252ZXJzaW9uIG1vZGUsIHRoZQ0KPiA+ICsg
KiBkZXZpY2UgY29udGludW91c2x5IHBlcmZvcm1zIGNvbnZlcnNpb25zIGFuIHBsYWNlcyB0aGUg
cmVzdWx0IGluIHRoZQ0KPiA+ICsgKiBkYXRhIHJlZ2lzdGVyLg0KPiA+ICsgKg0KPiA+ICsgKiAx
IC0gU2luZ2xlLUNvbnZlcnNpb24gTW9kZSA6IGRldmljZSBwZXJmb3JtcyBhIHNpbmdsZSBtZWFz
dXJlbWVudCwNCj4gPiArICogIHNldHMgUkRZIGhpZ2ggYW5kIHJldHVybmVkIHRvIHNsZWVwIG1v
ZGUNCj4gPiArICoNCj4gPiArICogMiAtIElkbGUgTW9kZSA6ICBEZXZpY2UgaXMgcGxhY2VkIGlu
IGlkbGUgbW9kZS4NCj4gPiArICoNCj4gPiArICogMyAtIFNsZWVwIE1vZGUuIERldmljZSBpcyBw
bGFjZWQgaW4gc2xlZXAgbW9kZS4NCj4gPiArICoNCj4gPiArICovDQo+ID4gK3N0YXRpYyBzc2l6
ZV90IGhtYzU4NDNfc2hvd19vcGVyYXRpbmdfbW9kZShzdHJ1Y3QgZGV2aWNlICpkZXYsDQo+ID4g
KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2VfYXR0
cmlidXRlICphdHRyLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICBjaGFyICpidWYpDQo+ID4gK3sNCj4gPiArICAgICAgIHN0cnVjdCBpaW9fZGV2ICppbmRpb19k
ZXYgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsNCj4gPiArICAgICAgIHN0cnVjdCBobWM1ODQzX2Rh
dGEgKmRhdGEgPSBpbmRpb19kZXYtPmRldl9kYXRhOw0KPiA+ICsgICAgICAgcmV0dXJuIHNwcmlu
dGYoYnVmLCAiJWRcbiIsIGRhdGEtPm9wZXJhdGluZ19tb2RlKTsNCj4gPiArfQ0KPiA+ICsNCj4g
PiArc3RhdGljIHNzaXplX3QgaG1jNTg0M19zZXRfb3BlcmF0aW5nX21vZGUoc3RydWN0IGRldmlj
ZSAqZGV2LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRldmlj
ZV9hdHRyaWJ1dGUgKmF0dHIsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBj
b25zdCBjaGFyICpidWYsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXpl
X3QgY291bnQpDQo+ID4gK3sNCj4gPiArICAgICAgIHN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYg
PSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsNCj4gPiArICAgICAgIHN0cnVjdCBpMmNfY2xpZW50ICpj
bGllbnQgPSB0b19pMmNfY2xpZW50KGluZGlvX2Rldi0NCj4gPmRldi5wYXJlbnQpOw0KPiA+ICsg
ICAgICAgc3RydWN0IGhtYzU4NDNfZGF0YSAqZGF0YSA9IGluZGlvX2Rldi0+ZGV2X2RhdGE7DQo+
ID4gKyAgICAgICBzdHJ1Y3QgaWlvX2Rldl9hdHRyICp0aGlzX2F0dHIgPSB0b19paW9fZGV2X2F0
dHIoYXR0cik7DQo+ID4gKyAgICAgICB1bnNpZ25lZCBsb25nIG9wZXJhdGluZ19tb2RlID0gMDsN
Cj4gPiArICAgICAgIHMzMiBzdGF0dXM7DQo+ID4gKyAgICAgICBpbnQgZXJyb3I7DQo+ID4gKyAg
ICAgICBtdXRleF9sb2NrKCZkYXRhLT5sb2NrKTsNCj4gPiArICAgICAgIGVycm9yID0gc3RyaWN0
X3N0cnRvdWwoYnVmLCAxMCwgJm9wZXJhdGluZ19tb2RlKTsNCj4gPiArICAgICAgIGlmIChlcnJv
cikNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yOw0KPiA+ICsgICAgICAgZGV2X2Ri
ZyhkZXYsICJzZXQgQ29udmVyc2lvbiBtb2RlIHRvICVsdVxuIiwgb3BlcmF0aW5nX21vZGUpOw0K
PiA+ICsgICAgICAgaWYgKG9wZXJhdGluZ19tb2RlID4gTU9ERV9TTEVFUCkNCj4gPiArICAgICAg
ICAgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsNCj4gPiArDQo+ID4gKyAgICAgICBzdGF0
dXMgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGNsaWVudCwgdGhpc19hdHRyLT5hZGRyZXNz
LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpbmdf
bW9kZSk7DQo+ID4gKyAgICAgICBpZiAoc3RhdHVzKSB7DQo+ID4gKyAgICAgICAgICAgICAgIGNv
dW50ID0gLUVJTlZBTDsNCj4gPiArICAgICAgICAgICAgICAgZ290byBleGl0Ow0KPiA+ICsgICAg
ICAgfQ0KPiA+ICsgICAgICAgZGF0YS0+b3BlcmF0aW5nX21vZGUgPSBvcGVyYXRpbmdfbW9kZTsN
Cj4gPiArDQo+ID4gK2V4aXQ6DQo+ID4gKyAgICAgICBtdXRleF91bmxvY2soJmRhdGEtPmxvY2sp
Ow0KPiA+ICsgICAgICAgcmV0dXJuIGNvdW50Ow0KPiA+ICt9DQo+ID4gK3N0YXRpYyBJSU9fREVW
SUNFX0FUVFIob3BlcmF0aW5nX21vZGUsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgU19J
V1VTUiB8IFNfSVJVR08sDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgaG1jNTg0M19zaG93
X29wZXJhdGluZ19tb2RlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGhtYzU4NDNfc2V0
X29wZXJhdGluZ19tb2RlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIEhNQzU4NDNfTU9E
RV9SRUcpOw0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogQVBJIGZvciBzZXR0aW5nIHRoZSBtZWFz
dXJlbWVudCBjb25maWd1cmF0aW9uIHRvDQo+ID4gKyAqIE5vcm1hbCwgUG9zaXRpdmUgYmlhcyBh
bmQgTmVnYXRpdmUgYmlhcw0KPiA+ICsgKiBGcm9tIHRoZSBkYXRhc2hlZXQNCj4gPiArICoNCj4g
PiArICogTm9ybWFsIG1lYXN1cmVtZW50IGNvbmZpZ3VyYXRpb24gKGRlZmF1bHQpOiBJbiBub3Jt
YWwgbWVhc3VyZW1lbnQNCj4gPiArICogY29uZmlndXJhdGlvbiB0aGUgZGV2aWNlIGZvbGxvd3Mg
bm9ybWFsIG1lYXN1cmVtZW50IGZsb3cuIFBpbnMgQlANCj4gYW5kIEJODQo+ID4gKyAqIGFyZSBs
ZWZ0IGZsb2F0aW5nIGFuZCBoaWdoIGltcGVkYW5jZS4NCj4gPiArICoNCj4gPiArICogUG9zaXRp
dmUgYmlhcyBjb25maWd1cmF0aW9uOiBJbiBwb3NpdGl2ZSBiaWFzIGNvbmZpZ3VyYXRpb24sIGEN
Cj4gcG9zaXRpdmUNCj4gPiArICogY3VycmVudCBpcyBmb3JjZWQgYWNyb3NzIHRoZSByZXNpc3Rp
dmUgbG9hZCBvbiBwaW5zIEJQIGFuZCBCTi4NCj4gPiArICoNCj4gPiArICogTmVnYXRpdmUgYmlh
cyBjb25maWd1cmF0aW9uLiBJbiBuZWdhdGl2ZSBiaWFzIGNvbmZpZ3VyYXRpb24sIGENCj4gbmVn
YXRpdmUNCj4gPiArICogY3VycmVudCBpcyBmb3JjZWQgYWNyb3NzIHRoZSByZXNpc3RpdmUgbG9h
ZCBvbiBwaW5zIEJQIGFuZCBCTi4NCj4gPiArICoNCj4gPiArICovDQo+ID4gK3N0YXRpYyBzMzIg
aG1jNTg0M19zZXRfbWVhc19jb25mKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQsDQo+ID4gKyAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1OCBtZWFzX2NvbmYpDQo+ID4gK3sN
Cj4gPiArICAgICAgIHN0cnVjdCBobWM1ODQzX2RhdGEgKmRhdGEgPSBpMmNfZ2V0X2NsaWVudGRh
dGEoY2xpZW50KTsNCj4gPiArICAgICAgIHU4IHJlZ192YWw7DQo+ID4gKyAgICAgICByZWdfdmFs
ID0gKG1lYXNfY29uZiAmIE1FQVNfQ09ORl9NQVNLKSB8ICAoZGF0YS0+cmF0ZSA8PA0KPiBSQVRF
X09GRlNFVCk7DQo+ID4gKyAgICAgICByZXR1cm4gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShj
bGllbnQsIEhNQzU4NDNfQ09ORklHX1JFR19BLA0KPiByZWdfdmFsKTsNCj4gPiArfQ0KPiA+ICsN
Cj4gPiArc3RhdGljIHNzaXplX3QgaG1jNTg0M19zaG93X21lYXN1cmVtZW50X2NvbmZpZ3VyYXRp
b24oc3RydWN0IGRldmljZQ0KPiAqZGV2LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlDQo+ICphdHRyLA0K
PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIg
KmJ1ZikNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiA9IGRl
dl9nZXRfZHJ2ZGF0YShkZXYpOw0KPiA+ICsgICAgICAgc3RydWN0IGhtYzU4NDNfZGF0YSAqZGF0
YSA9IGluZGlvX2Rldi0+ZGV2X2RhdGE7DQo+ID4gKyAgICAgICByZXR1cm4gc3ByaW50ZihidWYs
ICIlZFxuIiwgZGF0YS0+bWVhc19jb25mKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHNz
aXplX3QgaG1jNTg0M19zZXRfbWVhc3VyZW1lbnRfY29uZmlndXJhdGlvbihzdHJ1Y3QgZGV2aWNl
DQo+ICpkZXYsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUNCj4gKmF0dHIsDQo+ID4gKyAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYnVmLA0KPiA+
ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBj
b3VudCkNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiA9IGRl
dl9nZXRfZHJ2ZGF0YShkZXYpOw0KPiA+ICsgICAgICAgc3RydWN0IGkyY19jbGllbnQgKmNsaWVu
dCA9IHRvX2kyY19jbGllbnQoaW5kaW9fZGV2LQ0KPiA+ZGV2LnBhcmVudCk7DQo+ID4gKyAgICAg
ICBzdHJ1Y3QgaG1jNTg0M19kYXRhICpkYXRhID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7
DQo+ID4gKyAgICAgICB1bnNpZ25lZCBsb25nIG1lYXNfY29uZiA9IDA7DQo+ID4gKyAgICAgICBp
bnQgZXJyb3IgPSBzdHJpY3Rfc3RydG91bChidWYsIDEwLCAmbWVhc19jb25mKTsNCj4gPiArICAg
ICAgIGlmIChlcnJvcikNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yOw0KPiA+ICsg
ICAgICAgbXV0ZXhfbG9jaygmZGF0YS0+bG9jayk7DQo+ID4gKw0KPiA+ICsgICAgICAgZGV2X2Ri
ZyhkZXYsICJzZXQgbW9kZSB0byAlbHVcbiIsIG1lYXNfY29uZik7DQo+ID4gKyAgICAgICBpZiAo
aG1jNTg0M19zZXRfbWVhc19jb25mKGNsaWVudCwgbWVhc19jb25mKSkgew0KPiA+ICsgICAgICAg
ICAgICAgICBjb3VudCA9IC1FSU5WQUw7DQo+ID4gKyAgICAgICAgICAgICAgIGdvdG8gZXhpdDsN
Cj4gPiArICAgICAgIH0NCj4gPiArICAgICAgIGRhdGEtPm1lYXNfY29uZiA9IG1lYXNfY29uZjsN
Cj4gPiArDQo+ID4gK2V4aXQ6DQo+ID4gKyAgICAgICBtdXRleF91bmxvY2soJmRhdGEtPmxvY2sp
Ow0KPiA+ICsgICAgICAgcmV0dXJuIGNvdW50Ow0KPiA+ICt9DQo+ID4gK3N0YXRpYyBJSU9fREVW
SUNFX0FUVFIobWVhc19jb25mLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIFNfSVdVU1Ig
fCBTX0lSVUdPLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGhtYzU4NDNfc2hvd19tZWFz
dXJlbWVudF9jb25maWd1cmF0aW9uLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGhtYzU4
NDNfc2V0X21lYXN1cmVtZW50X2NvbmZpZ3VyYXRpb24sDQo+ID4gKyAgICAgICAgICAgICAgICAg
ICAgICAgMCk7DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBGcm9tIERhdGFzaGVldA0KPiA+ICsg
KiBUaGUgdGFibGUgc2hvd3MgdGhlIG1pbmltdW0gZGF0YSBvdXRwdXQNCj4gPiArICogVmFsdWUg
ICAgICAgfCBNaW5pbXVtIGRhdGEgb3V0cHV0IHJhdGUoSHopDQo+ID4gKyAqIDAgICAgICAgICAg
IHwgMC41DQo+ID4gKyAqIDEgICAgICAgICAgIHwgMQ0KPiA+ICsgKiAyICAgICAgICAgICB8IDIN
Cj4gPiArICogMyAgICAgICAgICAgfCA1DQo+ID4gKyAqIDQgICAgICAgICAgIHwgMTAgKGRlZmF1
bHQpDQo+ID4gKyAqIDUgICAgICAgICAgIHwgMjANCj4gPiArICogNiAgICAgICAgICAgfCA1MA0K
PiA+ICsgKiA3ICAgICAgICAgICB8IE5vdCB1c2VkDQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgSUlP
X0NPTlNUX0FUVFJfQVZBSUxfU0FNUF9GUkVRKCIwLjUgMSAyIDUgMTAgMjAgNTAiKTsNCj4gPiAr
DQo+ID4gK3N0YXRpYyBzMzIgaG1jNTg0M19zZXRfcmF0ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xp
ZW50LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTggcmF0ZSkNCj4gPiAr
ew0KPiA+ICsgICAgICAgc3RydWN0IGhtYzU4NDNfZGF0YSAqZGF0YSA9IGkyY19nZXRfY2xpZW50
ZGF0YShjbGllbnQpOw0KPiA+ICsgICAgICAgdTggcmVnX3ZhbDsNCj4gPiArDQo+ID4gKyAgICAg
ICByZWdfdmFsID0gKGRhdGEtPm1lYXNfY29uZikgfCAgKHJhdGUgPDwgUkFURV9PRkZTRVQpOw0K
PiA+ICsgICAgICAgaWYgKHJhdGUgPj0gUkFURV9OT1RfVVNFRCkgew0KPiA+ICsgICAgICAgICAg
ICAgICBkZXZfZXJyKCZjbGllbnQtPmRldiwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAi
VGhpcyBkYXRhIG91dHB1dCByYXRlIGlzIG5vdCBzdXBwb3J0ZWQgXG4iKTsNCj4gPiArICAgICAg
ICAgICAgICAgcmV0dXJuIC1FSU5WQUw7DQo+ID4gKyAgICAgICB9DQo+ID4gKyAgICAgICByZXR1
cm4gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShjbGllbnQsIEhNQzU4NDNfQ09ORklHX1JFR19B
LA0KPiByZWdfdmFsKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHNzaXplX3Qgc2V0X3Nh
bXBsaW5nX2ZyZXF1ZW5jeShzdHJ1Y3QgZGV2aWNlICpkZXYsDQo+ID4gKyAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLA0K
PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpi
dWYsIHNpemVfdCBjb3VudCkNCj4gPiArew0KPiA+ICsNCj4gPiArICAgICAgIHN0cnVjdCBpaW9f
ZGV2ICppbmRpb19kZXYgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsNCj4gPiArICAgICAgIHN0cnVj
dCBpMmNfY2xpZW50ICpjbGllbnQgPSB0b19pMmNfY2xpZW50KGluZGlvX2Rldi0NCj4gPmRldi5w
YXJlbnQpOw0KPiA+ICsgICAgICAgc3RydWN0IGhtYzU4NDNfZGF0YSAqZGF0YSA9IGluZGlvX2Rl
di0+ZGV2X2RhdGE7DQo+ID4gKyAgICAgICB1bnNpZ25lZCBsb25nIHJhdGUgPSAwOw0KPiA+ICsN
Cj4gPiArICAgICAgIGlmIChzdHJuY21wKGJ1ZiwgIjAuNSIgLCAzKSA9PSAwKQ0KPiA+ICsgICAg
ICAgICAgICAgICByYXRlID0gUkFURV81Ow0KPiA+ICsgICAgICAgZWxzZSBpZiAoc3RybmNtcChi
dWYsICIxIiAsIDEpID09IDApDQo+ID4gKyAgICAgICAgICAgICAgIHJhdGUgPSBSQVRFXzEwOw0K
PiA+ICsgICAgICAgZWxzZSBpZiAoc3RybmNtcChidWYsICIyIiwgMSkgPT0gMCkNCj4gPiArICAg
ICAgICAgICAgICAgcmF0ZSA9IFJBVEVfMjA7DQo+ID4gKyAgICAgICBlbHNlIGlmIChzdHJuY21w
KGJ1ZiwgIjUiLCAxKSA9PSAwKQ0KPiA+ICsgICAgICAgICAgICAgICByYXRlID0gUkFURV81MDsN
Cj4gPiArICAgICAgIGVsc2UgaWYgKHN0cm5jbXAoYnVmLCAiMTAiLCAyKSA9PSAwKQ0KPiA+ICsg
ICAgICAgICAgICAgICByYXRlID0gUkFURV8xMDA7DQo+ID4gKyAgICAgICBlbHNlIGlmIChzdHJu
Y21wKGJ1ZiwgIjIwIiAsIDIpID09IDApDQo+ID4gKyAgICAgICAgICAgICAgIHJhdGUgPSBSQVRF
XzIwMDsNCj4gPiArICAgICAgIGVsc2UgaWYgKHN0cm5jbXAoYnVmLCAiNTAiICwgMikgPT0gMCkN
Cj4gPiArICAgICAgICAgICAgICAgcmF0ZSA9IFJBVEVfNTAwOw0KPiA+ICsgICAgICAgZWxzZQ0K
PiA+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsNCj4gPiArDQo+ID4gKyAgICAgICBt
dXRleF9sb2NrKCZkYXRhLT5sb2NrKTsNCj4gPiArICAgICAgIGRldl9kYmcoZGV2LCAic2V0IHJh
dGUgdG8gJWx1XG4iLCByYXRlKTsNCj4gPiArICAgICAgIGlmIChobWM1ODQzX3NldF9yYXRlKGNs
aWVudCwgcmF0ZSkpIHsNCj4gPiArICAgICAgICAgICAgICAgY291bnQgPSAtRUlOVkFMOw0KPiA+
ICsgICAgICAgICAgICAgICBnb3RvIGV4aXQ7DQo+ID4gKyAgICAgICB9DQo+ID4gKyAgICAgICBk
YXRhLT5yYXRlID0gcmF0ZTsNCj4gPiArDQo+ID4gK2V4aXQ6DQo+ID4gKyAgICAgICBtdXRleF91
bmxvY2soJmRhdGEtPmxvY2spOw0KPiA+ICsgICAgICAgcmV0dXJuIGNvdW50Ow0KPiA+ICt9DQo+
ID4gKw0KPiA+ICtzdGF0aWMgc3NpemVfdCBzaG93X3NhbXBsaW5nX2ZyZXF1ZW5jeShzdHJ1Y3Qg
ZGV2aWNlICpkZXYsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRldmljZV9h
dHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0IGlp
b19kZXYgKmluZGlvX2RldiA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOw0KPiA+ICsgICAgICAgc3Ry
dWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX2kyY19jbGllbnQoaW5kaW9fZGV2LQ0KPiA+ZGV2
LnBhcmVudCk7DQo+ID4gKyAgICAgICBzdHJ1Y3QgaWlvX2Rldl9hdHRyICp0aGlzX2F0dHIgPSB0
b19paW9fZGV2X2F0dHIoYXR0cik7DQo+ID4gKyAgICAgICB1MzIgcmF0ZTsNCj4gPiArDQo+ID4g
KyAgICAgICByYXRlID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRhKGNsaWVudCwgIHRoaXNfYXR0
ci0+YWRkcmVzcyk7DQo+ID4gKyAgICAgICBpZiAocmF0ZSA8IDApDQo+ID4gKyAgICAgICAgICAg
ICAgIHJldHVybiAtRUlOVkFMOw0KPiA+ICsgICAgICAgcmF0ZSA9IChyYXRlICYgUkFURV9CSVRN
QVNLKSA+PiBSQVRFX09GRlNFVDsNCj4gPiArICAgICAgIHJldHVybiBzcHJpbnRmKGJ1ZiwgIiVz
XG4iLCByZWd2YWxfdG9fc2FtcF9mcmVxW3JhdGVdKTsNCj4gPiArfQ0KPiA+ICtzdGF0aWMgSUlP
X0RFVklDRV9BVFRSKHNhbXBsaW5nX2ZyZXF1ZW5jeSwNCj4gPiArICAgICAgICAgICAgICAgICAg
ICAgICBTX0lXVVNSIHwgU19JUlVHTywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzaG93
X3NhbXBsaW5nX2ZyZXF1ZW5jeSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzZXRfc2Ft
cGxpbmdfZnJlcXVlbmN5LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIEhNQzU4NDNfQ09O
RklHX1JFR19BKTsNCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIEZyb20gRGF0YXNoZWV0DQo+ID4g
KyAqICAgICBOb21pbmFsIGdhaW4gc2V0dGluZ3MNCj4gPiArICogVmFsdWUgICAgICAgfCBTZW5z
b3IgSW5wdXQgRmllbGQgUmFuZ2UoR2EpICB8IEdhaW4oY291bnRzLyBtaWxsaS0NCj4gZ2F1c3Mp
DQo+ID4gKyAqMCAgICAgICAgICAgIHwoKy0pMC43ICAgICAgICAgICAgICAgICAgICAgICAgfDE2
MjANCj4gPiArICoxICAgICAgICAgICAgfCgrLSkxLjAgICAgICAgICAgICAgICAgICAgICAgICB8
MTMwMA0KPiA+ICsgKjIgICAgICAgICAgICB8KCstKTEuNSAgICAgICAgICAgICAgICAgICAgICAg
IHw5NzANCj4gPiArICozICAgICAgICAgICAgfCgrLSkyLjAgICAgICAgICAgICAgICAgICAgICAg
ICB8NzgwDQo+ID4gKyAqNCAgICAgICAgICAgIHwoKy0pMy4yICAgICAgICAgICAgICAgICAgICAg
ICAgfDUzMA0KPiA+ICsgKjUgICAgICAgICAgICB8KCstKTMuOCAgICAgICAgICAgICAgICAgICAg
ICAgIHw0NjANCj4gPiArICo2ICAgICAgICAgICAgfCgrLSk0LjUgICAgICAgICAgICAgICAgICAg
ICAgICB8MzkwDQo+ID4gKyAqNyAgICAgICAgICAgIHwoKy0pNi41ICAgICAgICAgICAgICAgICAg
ICAgICAgfDI4MA0KPiA+ICsgKi8NCj4gPiArc3RhdGljIHNzaXplX3Qgc2hvd19yYW5nZShzdHJ1
Y3QgZGV2aWNlICpkZXYsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1
Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIGNoYXIgKmJ1ZikNCj4gPiArew0KPiA+ICsgICAgICAgdTggcmFuZ2U7DQo+ID4gKyAg
ICAgICBzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2ID0gZGV2X2dldF9kcnZkYXRhKGRldik7DQo+
ID4gKyAgICAgICBzdHJ1Y3QgaG1jNTg0M19kYXRhICpkYXRhID0gaW5kaW9fZGV2LT5kZXZfZGF0
YTsNCj4gPiArDQo+ID4gKyAgICAgICByYW5nZSA9IGRhdGEtPnJhbmdlOw0KPiA+ICsgICAgICAg
cmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHJlZ3ZhbF90b19pbnB1dF9maWVsZF9tZ1tyYW5n
ZV0pOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgc3NpemVfdCBzZXRfcmFuZ2Uoc3RydWN0
IGRldmljZSAqZGV2LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2Vf
YXR0cmlidXRlICphdHRyLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIg
KmJ1ZiwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgY291bnQpDQo+ID4gK3sN
Cj4gPiArICAgICAgIHN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYgPSBkZXZfZ2V0X2RydmRhdGEo
ZGV2KTsNCj4gPiArICAgICAgIHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQgPSB0b19pMmNfY2xp
ZW50KGluZGlvX2Rldi0NCj4gPmRldi5wYXJlbnQpOw0KPiA+ICsgICAgICAgc3RydWN0IGlpb19k
ZXZfYXR0ciAqdGhpc19hdHRyID0gdG9faWlvX2Rldl9hdHRyKGF0dHIpOw0KPiA+ICsgICAgICAg
c3RydWN0IGhtYzU4NDNfZGF0YSAqZGF0YSA9IGluZGlvX2Rldi0+ZGV2X2RhdGE7DQo+ID4gKyAg
ICAgICB1bnNpZ25lZCBsb25nIHJhbmdlID0gMDsNCj4gPiArICAgICAgIGludCBlcnJvcjsNCj4g
PiArICAgICAgIG11dGV4X2xvY2soJmRhdGEtPmxvY2spOw0KPiA+ICsgICAgICAgZXJyb3IgPSBz
dHJpY3Rfc3RydG91bChidWYsIDEwLCAmcmFuZ2UpOw0KPiA+ICsgICAgICAgaWYgKGVycm9yKQ0K
PiA+ICsgICAgICAgICAgICAgICByZXR1cm4gZXJyb3I7DQo+ID4gKyAgICAgICBkZXZfZGJnKGRl
diwgInNldCByYW5nZSB0byAlbHVcbiIsIHJhbmdlKTsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAo
cmFuZ2UgPiBSQU5HRV82XzUpDQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOw0K
PiA+ICsNCj4gPiArICAgICAgIGRhdGEtPnJhbmdlID0gcmFuZ2U7DQo+ID4gKyAgICAgICByYW5n
ZSA9IHJhbmdlIDw8IFJBTkdFX0dBSU5fT0ZGU0VUOw0KPiA+ICsgICAgICAgaWYgKGkyY19zbWJ1
c193cml0ZV9ieXRlX2RhdGEoY2xpZW50LCB0aGlzX2F0dHItPmFkZHJlc3MsDQo+IHJhbmdlKSkN
Cj4gPiArICAgICAgICAgICAgICAgY291bnQgPSAtRUlOVkFMOw0KPiA+ICsNCj4gPiArICAgICAg
IG11dGV4X3VubG9jaygmZGF0YS0+bG9jayk7DQo+ID4gKyAgICAgICByZXR1cm4gY291bnQ7DQo+
ID4gKw0KPiA+ICt9DQo+ID4gK3N0YXRpYyBJSU9fREVWSUNFX0FUVFIobWFnbl9yYW5nZSwNCj4g
PiArICAgICAgICAgICAgICAgICAgICAgICBTX0lXVVNSIHwgU19JUlVHTywNCj4gPiArICAgICAg
ICAgICAgICAgICAgICAgICBzaG93X3JhbmdlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg
IHNldF9yYW5nZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBITUM1ODQzX0NPTkZJR19S
RUdfQik7DQo+ID4gKw0KPiA+ICtzdGF0aWMgc3NpemVfdCBzaG93X2dhaW4oc3RydWN0IGRldmlj
ZSAqZGV2LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkZXZpY2VfYXR0cmli
dXRlICphdHRyLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKmJ1ZikNCj4gPiAr
ew0KPiA+ICsgICAgICAgc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiA9IGRldl9nZXRfZHJ2ZGF0
YShkZXYpOw0KPiA+ICsgICAgICAgc3RydWN0IGhtYzU4NDNfZGF0YSAqZGF0YSA9IGluZGlvX2Rl
di0+ZGV2X2RhdGE7DQo+ID4gKyAgICAgICByZXR1cm4gc3ByaW50ZihidWYsICIlZFxuIiwgcmVn
dmFsX3RvX2NvdW50c19wZXJfbWdbZGF0YS0NCj4gPnJhbmdlXSk7DQo+ID4gK30NCj4gPiArc3Rh
dGljIElJT19ERVZJQ0VfQVRUUihtYWduX2dhaW4sDQo+ID4gKyAgICAgICAgICAgICAgICAgICAg
ICAgU19JUlVHTywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBzaG93X2dhaW4sDQo+ID4g
KyAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAsIDApOw0KPiA+ICsNCj4gPiArc3RhdGljIHN0
cnVjdCBhdHRyaWJ1dGUgKmhtYzU4NDNfYXR0cmlidXRlc1tdID0gew0KPiA+ICsgICAgICAgJmlp
b19kZXZfYXR0cl9tZWFzX2NvbmYuZGV2X2F0dHIuYXR0ciwNCj4gPiArICAgICAgICZpaW9fZGV2
X2F0dHJfb3BlcmF0aW5nX21vZGUuZGV2X2F0dHIuYXR0ciwNCj4gPiArICAgICAgICZpaW9fZGV2
X2F0dHJfc2FtcGxpbmdfZnJlcXVlbmN5LmRldl9hdHRyLmF0dHIsDQo+ID4gKyAgICAgICAmaWlv
X2Rldl9hdHRyX21hZ25fcmFuZ2UuZGV2X2F0dHIuYXR0ciwNCj4gPiArICAgICAgICZpaW9fZGV2
X2F0dHJfbWFnbl9nYWluLmRldl9hdHRyLmF0dHIsDQo+ID4gKyAgICAgICAmaWlvX2Rldl9hdHRy
X21hZ25feF9yYXcuZGV2X2F0dHIuYXR0ciwNCj4gPiArICAgICAgICZpaW9fZGV2X2F0dHJfbWFn
bl95X3Jhdy5kZXZfYXR0ci5hdHRyLA0KPiA+ICsgICAgICAgJmlpb19kZXZfYXR0cl9tYWduX3pf
cmF3LmRldl9hdHRyLmF0dHIsDQo+ID4gKyAgICAgICAmaWlvX2NvbnN0X2F0dHJfYXZhaWxhYmxl
X3NhbXBsaW5nX2ZyZXF1ZW5jeS5kZXZfYXR0ci5hdHRyLA0KPiA+ICsgICAgICAgTlVMTA0KPiA+
ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgaG1j
NTg0M19ncm91cCA9IHsNCj4gPiArICAgICAgIC5hdHRycyA9IGhtYzU4NDNfYXR0cmlidXRlcywN
Cj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgaG1jNTg0M19kZXRlY3Qoc3RydWN0IGky
Y19jbGllbnQgKmNsaWVudCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBp
MmNfYm9hcmRfaW5mbyAqaW5mbykNCj4gPiArew0KPiA+ICsgICAgICAgdW5zaWduZWQgY2hhciBp
ZF9zdHJbSE1DNTg0M19JRF9SRUdfTEVOR1RIXTsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAoY2xp
ZW50LT5hZGRyICE9IEhNQzU4NDNfSTJDX0FERFJFU1MpDQo+ID4gKyAgICAgICAgICAgICAgIHJl
dHVybiAtRU5PREVWOw0KPiA+ICsNCj4gPiArICAgICAgIGlmIChpMmNfc21idXNfcmVhZF9pMmNf
YmxvY2tfZGF0YShjbGllbnQsIEhNQzU4NDNfSURfUkVHX0EsDQo+ID4gKyAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICBITUM1ODQzX0lEX1JFR19MRU5HVEgsIGlkX3N0cikNCj4gPiArICAg
ICAgICAgICAgICAgICAgICAgICAhPSBITUM1ODQzX0lEX1JFR19MRU5HVEgpDQo+ID4gKyAgICAg
ICAgICAgICAgIHJldHVybiAtRU5PREVWOw0KPiA+ICsNCj4gPiArICAgICAgIGlmICgwICE9IHN0
cm5jbXAoaWRfc3RyLCBITUM1ODQzX0lEX1NUUklORywNCj4gSE1DNTg0M19JRF9SRUdfTEVOR1RI
KSkNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FTk9ERVY7DQo+ID4gKw0KPiA+ICsgICAg
ICAgcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qIENhbGxlZCB3aGVuIHdlIGhhdmUg
Zm91bmQgYSBuZXcgSE1DNTg0My4gKi8NCj4gPiArc3RhdGljIHZvaWQgaG1jNTg0M19pbml0X2Ns
aWVudChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1
Y3QgaG1jNTg0M19kYXRhICpkYXRhID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7DQo+ID4g
KyAgICAgICBobWM1ODQzX3NldF9tZWFzX2NvbmYoY2xpZW50LCBkYXRhLT5tZWFzX2NvbmYpOw0K
PiA+ICsgICAgICAgaG1jNTg0M19zZXRfcmF0ZShjbGllbnQsIGRhdGEtPnJhdGUpOw0KPiA+ICsg
ICAgICAgaG1jNTg0M19jb25maWd1cmUoY2xpZW50LCBkYXRhLT5vcGVyYXRpbmdfbW9kZSk7DQo+
ID4gKyAgICAgICBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGNsaWVudCwgSE1DNTg0M19DT05G
SUdfUkVHX0IsIGRhdGEtDQo+ID5yYW5nZSk7DQo+ID4gKyAgICAgICBtdXRleF9pbml0KCZkYXRh
LT5sb2NrKTsNCj4gPiArICAgICAgIHByX2luZm8oIkhNQzU4NDMgaW5pdGlhbGl6ZWRcbiIpOw0K
PiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGhtYzU4NDNfcHJvYmUoc3RydWN0IGkyY19j
bGllbnQgKmNsaWVudCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0
IGkyY19kZXZpY2VfaWQgKmlkKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgaG1jNTg0M19k
YXRhICpkYXRhOw0KPiA+ICsgICAgICAgaW50IGVyciA9IDA7DQo+ID4gKw0KPiA+ICsgICAgICAg
ZGF0YSA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBobWM1ODQzX2RhdGEpLCBHRlBfS0VSTkVMKTsN
Cj4gPiArICAgICAgIGlmICghZGF0YSkgew0KPiA+ICsgICAgICAgICAgICAgICBlcnIgPSAtRU5P
TUVNOw0KPiA+ICsgICAgICAgICAgICAgICBnb3RvIGV4aXQ7DQo+ID4gKyAgICAgICB9DQo+ID4g
Kw0KPiA+ICsgICAgICAgLyogZGVmYXVsdCBzZXR0aW5ncyBhdCBwcm9iZSAqLw0KPiA+ICsNCj4g
PiArICAgICAgIGRhdGEtPm1lYXNfY29uZiA9IENPTkZfTk9STUFMOw0KPiA+ICsgICAgICAgZGF0
YS0+cmFuZ2UgPSBSQU5HRV8xXzA7DQo+ID4gKyAgICAgICBkYXRhLT5vcGVyYXRpbmdfbW9kZSA9
IE1PREVfQ09OVkVSU0lPTl9DT05USU5VT1VTOw0KPiA+ICsNCj4gPiArICAgICAgIGkyY19zZXRf
Y2xpZW50ZGF0YShjbGllbnQsIGRhdGEpOw0KPiA+ICsNCj4gPiArICAgICAgIC8qIEluaXRpYWxp
emUgdGhlIEhNQzU4NDMgY2hpcCAqLw0KPiA+ICsgICAgICAgaG1jNTg0M19pbml0X2NsaWVudChj
bGllbnQpOw0KPiA+ICsNCj4gPiArICAgICAgIGRhdGEtPmluZGlvX2RldiA9IGlpb19hbGxvY2F0
ZV9kZXZpY2UoKTsNCj4gPiArICAgICAgIGlmICghZGF0YS0+aW5kaW9fZGV2KSB7DQo+ID4gKyAg
ICAgICAgICAgICAgIGVyciA9IC1FTk9NRU07DQo+ID4gKyAgICAgICAgICAgICAgIGdvdG8gZXhp
dF9mcmVlMTsNCj4gPiArICAgICAgIH0NCj4gPiArICAgICAgIGRhdGEtPmluZGlvX2Rldi0+YXR0
cnMgPSAmaG1jNTg0M19ncm91cDsNCj4gPiArICAgICAgIGRhdGEtPmluZGlvX2Rldi0+ZGV2LnBh
cmVudCA9ICZjbGllbnQtPmRldjsNCj4gPiArICAgICAgIGRhdGEtPmluZGlvX2Rldi0+ZGV2X2Rh
dGEgPSAodm9pZCAqKShkYXRhKTsNCj4gPiArICAgICAgIGRhdGEtPmluZGlvX2Rldi0+ZHJpdmVy
X21vZHVsZSA9IFRISVNfTU9EVUxFOw0KPiA+ICsgICAgICAgZGF0YS0+aW5kaW9fZGV2LT5tb2Rl
cyA9IElORElPX0RJUkVDVF9NT0RFOw0KPiA+ICsgICAgICAgZXJyID0gaWlvX2RldmljZV9yZWdp
c3RlcihkYXRhLT5pbmRpb19kZXYpOw0KPiA+ICsgICAgICAgaWYgKGVycikNCj4gPiArICAgICAg
ICAgICAgICAgZ290byBleGl0X2ZyZWUyOw0KPiA+ICsgICAgICAgcmV0dXJuIDA7DQo+ID4gK2V4
aXRfZnJlZTI6DQo+ID4gKyAgICAgICBpaW9fZnJlZV9kZXZpY2UoZGF0YS0+aW5kaW9fZGV2KTsN
Cj4gPiArZXhpdF9mcmVlMToNCj4gPiArICAgICAgIGtmcmVlKGRhdGEpOw0KPiA+ICtleGl0Og0K
PiA+ICsgICAgICAgcmV0dXJuIGVycjsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBo
bWM1ODQzX3JlbW92ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQ0KPiA+ICt7DQo+ID4gKyAg
ICAgICBzdHJ1Y3QgaG1jNTg0M19kYXRhICpkYXRhID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVu
dCk7DQo+ID4gKyAgICAgICAgLyogIHNsZWVwIG1vZGUgdG8gc2F2ZSBwb3dlciAqLw0KPiA+ICsg
ICAgICAgaG1jNTg0M19jb25maWd1cmUoY2xpZW50LCBNT0RFX1NMRUVQKTsNCj4gPiArICAgICAg
IGlpb19kZXZpY2VfdW5yZWdpc3RlcihkYXRhLT5pbmRpb19kZXYpOw0KPiA+ICsgICAgICAga2Zy
ZWUoaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCkpOw0KPiA+ICsgICAgICAgcmV0dXJuIDA7DQo+
ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgaG1jNTg0M19zdXNwZW5kKHN0cnVjdCBpMmNf
Y2xpZW50ICpjbGllbnQsIHBtX21lc3NhZ2VfdA0KPiBtZXNnKQ0KPiA+ICt7DQo+ID4gKyAgICAg
ICBobWM1ODQzX2NvbmZpZ3VyZShjbGllbnQsIE1PREVfU0xFRVApOw0KPiA+ICsgICAgICAgcmV0
dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgaG1jNTg0M19yZXN1bWUoc3Ry
dWN0IGkyY19jbGllbnQgKmNsaWVudCkNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0IGhtYzU4
NDNfZGF0YSAqZGF0YSA9IGkyY19nZXRfY2xpZW50ZGF0YShjbGllbnQpOw0KPiA+ICsgICAgICAg
aG1jNTg0M19jb25maWd1cmUoY2xpZW50LCBkYXRhLT5vcGVyYXRpbmdfbW9kZSk7DQo+ID4gKyAg
ICAgICByZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBp
MmNfZGV2aWNlX2lkIGhtYzU4NDNfaWRbXSA9IHsNCj4gPiArICAgICAgIHsgImhtYzU4NDMiLCAw
IH0sDQo+ID4gKyAgICAgICB7IH0NCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBzdHJ1Y3Qg
aTJjX2RyaXZlciBobWM1ODQzX2RyaXZlciA9IHsNCj4gPiArICAgICAgIC5kcml2ZXIgPSB7DQo+
ID4gKyAgICAgICAgICAgICAgIC5uYW1lICAgPSAiaG1jNTg0MyIsDQo+ID4gKyAgICAgICB9LA0K
PiA+ICsgICAgICAgLmlkX3RhYmxlICAgICAgID0gaG1jNTg0M19pZCwNCj4gPiArICAgICAgIC5w
cm9iZSAgICAgICAgICA9IGhtYzU4NDNfcHJvYmUsDQo+ID4gKyAgICAgICAucmVtb3ZlICAgICAg
ICAgPSBobWM1ODQzX3JlbW92ZSwNCj4gPiArICAgICAgIC5kZXRlY3QgICAgICAgICA9IGhtYzU4
NDNfZGV0ZWN0LA0KPiA+ICsgICAgICAgLmFkZHJlc3NfbGlzdCAgID0gbm9ybWFsX2kyYywNCj4g
PiArICAgICAgIC5zdXNwZW5kICAgICAgICA9IGhtYzU4NDNfc3VzcGVuZCwNCj4gPiArICAgICAg
IC5yZXN1bWUgICAgICAgICA9IGhtYzU4NDNfcmVzdW1lLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr
c3RhdGljIGludCBfX2luaXQgaG1jNTg0M19pbml0KHZvaWQpDQo+ID4gK3sNCj4gPiArICAgICAg
IHJldHVybiBpMmNfYWRkX2RyaXZlcigmaG1jNTg0M19kcml2ZXIpOw0KPiA+ICt9DQo+ID4gKw0K
PiA+ICtzdGF0aWMgdm9pZCBfX2V4aXQgaG1jNTg0M19leGl0KHZvaWQpDQo+ID4gK3sNCj4gPiAr
ICAgICAgIGkyY19kZWxfZHJpdmVyKCZobWM1ODQzX2RyaXZlcik7DQo+ID4gK30NCj4gPiArDQo+
ID4gK01PRFVMRV9BVVRIT1IoIlNodWJocmFqeW90aSBEYXR0YSA8c2h1YmhyYWp5b3RpQHRpLmNv
bSIpOw0KPiA+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkhNQzU4NDMgZHJpdmVyIik7DQo+ID4gK01P
RFVMRV9MSUNFTlNFKCJHUEwiKTsNCj4gPiArDQo+ID4gK21vZHVsZV9pbml0KGhtYzU4NDNfaW5p
dCk7DQo+ID4gK21vZHVsZV9leGl0KGhtYzU4NDNfZXhpdCk7DQo+ID4gLS0NCj4gPiAxLjUuNC43
DQo+ID4NCj4gPiAtLQ0KPiA+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRo
ZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC1paW8iIGluDQo+ID4gdGhlIGJvZHkgb2YgYSBtZXNz
YWdlIHRvIG1ham9yZG9tb0B2Z2VyLmtlcm5lbC5vcmcNCj4gPiBNb3JlIG1ham9yZG9tbyBpbmZv
IGF0ICBodHRwOi8vdmdlci5rZXJuZWwub3JnL21ham9yZG9tby1pbmZvLmh0bWwNCj4gPg0K

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] digital compass hmc5843
       [not found] ` <AANLkTinsbpx2HVNlkSIHXY_huwllBDHObk_WAEFz0TQh@mail.gmail.com>
  2010-07-21 13:57   ` [PATCH] digital compass hmc5843 Datta, Shubhrajyoti
@ 2010-07-22 18:40   ` Greg KH
       [not found]     ` <4C48A762.4050307@cam.ac.uk>
  1 sibling, 1 reply; 5+ messages in thread
From: Greg KH @ 2010-07-22 18:40 UTC (permalink / raw)
  To: Barry Song, Jonathan Cameron; +Cc: Shubhrajyoti D, linux-iio, gregkh

On Wed, Jul 21, 2010 at 03:48:48PM +0800, Barry Song wrote:
> The patch should be sent to Jonathan Cameron <jic23@cam.ac.uk>.
> -barry
> 
> On Sat, Jul 17, 2010 at 9:02 PM, Shubhrajyoti D <shubhrajyoti@ti.com> wrote:
> > Adding support for the Honeywell HMC5843. The interface to the device is
> > i2c
> >
> > TODO:
> > Adding the documentation
> >
> > Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> > Acked-by: Jonathan Cameron <jic23@cam.ac.uk>

Barry, it has Jonathan's ack on it, so I'm guessing that he already saw
it?

Jonathan, care to verify this?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] digital compass hmc5843
       [not found]     ` <4C48A762.4050307@cam.ac.uk>
@ 2010-07-22 20:55       ` Greg KH
  0 siblings, 0 replies; 5+ messages in thread
From: Greg KH @ 2010-07-22 20:55 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: Barry Song, Shubhrajyoti D, linux-iio, gregkh

On Thu, Jul 22, 2010 at 09:17:38PM +0100, Jonathan Cameron wrote:
> On 07/22/10 19:40, Greg KH wrote:
> > On Wed, Jul 21, 2010 at 03:48:48PM +0800, Barry Song wrote:
> >> The patch should be sent to Jonathan Cameron <jic23@cam.ac.uk>.
> >> -barry
> >>
> >> On Sat, Jul 17, 2010 at 9:02 PM, Shubhrajyoti D <shubhrajyoti@ti.com> wrote:
> >>> Adding support for the Honeywell HMC5843. The interface to the device is
> >>> i2c
> >>>
> >>> TODO:
> >>> Adding the documentation
> >>>
> >>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> >>> Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> > 
> > Barry, it has Jonathan's ack on it, so I'm guessing that he already saw
> > it?
> > 
> > Jonathan, care to verify this?
> 
> Yes, this driver is fine with me.

Great, thanks for letting me know.

greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-07-22 20:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1279371772-2127-1-git-send-email-shubhrajyoti@ti.com>
     [not found] ` <AANLkTinsbpx2HVNlkSIHXY_huwllBDHObk_WAEFz0TQh@mail.gmail.com>
2010-07-21 13:57   ` [PATCH] digital compass hmc5843 Datta, Shubhrajyoti
2010-07-22 18:40   ` Greg KH
     [not found]     ` <4C48A762.4050307@cam.ac.uk>
2010-07-22 20:55       ` Greg KH
2010-07-06 11:08 Shubhrajyoti D
2010-07-06 11:09 ` Datta, Shubhrajyoti

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.