lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed,  7 Sep 2011 17:19:43 +0100
From:	Jonathan Cameron <jic23@....ac.uk>
To:	broonie@...nsource.wolfsonmicro.com
Cc:	linux-kernel@...r.kernel.org, Michael.Hennerich@...log.com,
	linux-iio@...r.kernel.org, Jonathan Cameron <jic23@....ac.uk>
Subject: [PATCH 2/6] regmap: Add a magic bus type to handle quirks of analog devices ADIS sensors.

These devices look like 8 bit registers for writes and 16 bit registers for
reads.  As you might imagine this causes some 'issues' hence this regmap
bus implementation claims they are always 16bit and does the mangling to
make the writes work.
---
 drivers/base/regmap/Kconfig          |    5 ++-
 drivers/base/regmap/Makefile         |    1 +
 drivers/base/regmap/regmap-spi-adi.c |   70 ++++++++++++++++++++++++++++++++++
 include/linux/regmap.h               |    2 +
 4 files changed, 77 insertions(+), 1 deletions(-)

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index fabbf6c..e4991fe 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -3,7 +3,7 @@
 # subsystems should select the appropriate symbols.
 
 config REGMAP
-	default y if (REGMAP_I2C || REGMAP_SPI)
+	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPI_ADI)
 	bool
 
 config REGMAP_I2C
@@ -11,3 +11,6 @@ config REGMAP_I2C
 
 config REGMAP_SPI
 	tristate
+
+config REGMAP_SPI_ADI
+	tristate
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index 057c13f..9e71bf8 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_REGMAP) += regmap.o
 obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
+obj-$(CONFIG_REGMAP_SPI_ADI) += regmap-spi-adi.o
diff --git a/drivers/base/regmap/regmap-spi-adi.c b/drivers/base/regmap/regmap-spi-adi.c
new file mode 100644
index 0000000..a98c000
--- /dev/null
+++ b/drivers/base/regmap/regmap-spi-adi.c
@@ -0,0 +1,70 @@
+/*
+ * Register map access API - SPI support
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@...nsource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+static int regmap_spi_write(struct device *dev, const void *data, size_t count)
+{
+/* Now this only works for 8 bit addresss 16 bit register first byte of data
+ * is the lower address, second two the value */
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 *rawdata = (u8 *)data;
+
+	BUG_ON(count != 3);
+	/* Fiddling needed as the value is bigendian */
+	rawdata[0] += 1;
+	ret = spi_write(spi, data, 2);
+	if (ret < 0)
+		return ret;
+
+	rawdata[1] = rawdata[0] - 1;
+	ret = spi_write(spi, data + 1, 2);
+	return ret;
+}
+
+static int regmap_spi_read(struct device *dev,
+			   const void *reg, size_t reg_size,
+			   void *val, size_t val_size)
+{
+	struct spi_device *spi = to_spi_device(dev);
+
+	BUG_ON(reg_size != 1 || val_size != 2);
+
+	return spi_write_then_read(spi, reg, 2, val, val_size);
+}
+
+static struct regmap_bus regmap_spi_adi = {
+	.write = regmap_spi_write,
+	.read = regmap_spi_read,
+};
+
+/**
+ * regmap_init_spi_adi(): Initialise register map
+ *
+ * @spi: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+struct regmap *regmap_init_spi_adi(struct spi_device *spi,
+				   const struct regmap_config *config)
+{
+	return regmap_init(&spi->dev, &regmap_spi_adi, config);
+}
+EXPORT_SYMBOL_GPL(regmap_init_spi_adi);
+
+MODULE_LICENSE("GPL");
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 18d4afa..a827c30 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -111,6 +111,8 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c,
 			       const struct regmap_config *config);
 struct regmap *regmap_init_spi(struct spi_device *dev,
 			       const struct regmap_config *config);
+struct regmap *regmap_init_spi_adi(struct spi_device *dev,
+			       const struct regmap_config *config);
 
 void regmap_exit(struct regmap *map);
 int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
-- 
1.7.3.4

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ