summaryrefslogtreecommitdiff
path: root/drivers/iio/pressure/mpl115_spi.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-02-02 00:10:03 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-02-02 00:10:03 +0300
commitfec2f3335c637ca95166a9eb753fe2b49aee4e71 (patch)
treea5fba6b13c171730ec986e9c456430f023b2797d /drivers/iio/pressure/mpl115_spi.c
parent4cff7adbebf4d25f662b13c6582b945d9d549e25 (diff)
parentea4570d6c29994017e09196d1f8077fb5942b676 (diff)
downloadlinux-fec2f3335c637ca95166a9eb753fe2b49aee4e71.tar.xz
Merge tag 'iio-for-4.6a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: First round of new IIO device support, features and cleanups for the 4.6 cycle. Device Support * ad5761 - new driver * at91_sama5d2 ADC. - new driver and MAINTAINERS entry. - minor cleanups followed. * atlas pH-SM - new driver (this has possibly the prettiest data sheet I've ever seen) * mcp3422 - mcp3425 ADC added. * mcp4725 - mcp4726 DAC added. * mma8452 - mma8451q accelerometer added. * mpl115 - mpl115a1 added (a lot bigger than it seems as this is an SPI part whereas previous parts were i2c). * si7005 - Hoperf th02 (seems to be a repackaged part) * si7020 - Hoperf th06 (seems to be a repackaged part) New features * Core - IIO_PH type. Does what it says on the tin. * max30100 - LED current configuration support. * mcp320x - more differential measurement combinations. * mma8452 - free fall deteciton - opt3001 - enable operation without a IRQ line. - device tree docs. Somehow the original docs have disappeared down a rabbit hole, so here is a new set. * st-sensors - Support active-low interrupts. Cleanups and minor / not so minor reworks * Documentation - drop some defunct ABI from the docs in staging. * presure / Kconfig - white space cleanup. * ad7150 - BIT macro usage - Alignment fixes * ad7192 - false indent fixed. * ak8975 - constify the ak_def structures * axp288 - drop a redundant double const. * dht11 - substantial reliability improvements by being more tolerant of missing start bits. - simplify the decoding algorithm * mma8452 - whitespace cleanup * mpl115 - don't bother setting i2c_client_data as nothing uses it. * mpu6050 - drop unused function parameter. * opt3001 - extract integration time as constants. - trivial refactoring.
Diffstat (limited to 'drivers/iio/pressure/mpl115_spi.c')
-rw-r--r--drivers/iio/pressure/mpl115_spi.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/drivers/iio/pressure/mpl115_spi.c b/drivers/iio/pressure/mpl115_spi.c
new file mode 100644
index 000000000000..9ebf55f5b3aa
--- /dev/null
+++ b/drivers/iio/pressure/mpl115_spi.c
@@ -0,0 +1,106 @@
+/*
+ * Freescale MPL115A1 pressure/temperature sensor
+ *
+ * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Datasheet: http://www.nxp.com/files/sensors/doc/data_sheet/MPL115A1.pdf
+ */
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#include "mpl115.h"
+
+#define MPL115_SPI_WRITE(address) ((address) << 1)
+#define MPL115_SPI_READ(address) (0x80 | (address) << 1)
+
+struct mpl115_spi_buf {
+ u8 tx[4];
+ u8 rx[4];
+};
+
+static int mpl115_spi_init(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mpl115_spi_buf *buf;
+
+ buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, buf);
+
+ return 0;
+}
+
+static int mpl115_spi_read(struct device *dev, u8 address)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mpl115_spi_buf *buf = spi_get_drvdata(spi);
+ struct spi_transfer xfer = {
+ .tx_buf = buf->tx,
+ .rx_buf = buf->rx,
+ .len = 4,
+ };
+ int ret;
+
+ buf->tx[0] = MPL115_SPI_READ(address);
+ buf->tx[2] = MPL115_SPI_READ(address + 1);
+
+ ret = spi_sync_transfer(spi, &xfer, 1);
+ if (ret)
+ return ret;
+
+ return (buf->rx[1] << 8) | buf->rx[3];
+}
+
+static int mpl115_spi_write(struct device *dev, u8 address, u8 value)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mpl115_spi_buf *buf = spi_get_drvdata(spi);
+ struct spi_transfer xfer = {
+ .tx_buf = buf->tx,
+ .len = 2,
+ };
+
+ buf->tx[0] = MPL115_SPI_WRITE(address);
+ buf->tx[1] = value;
+
+ return spi_sync_transfer(spi, &xfer, 1);
+}
+
+static const struct mpl115_ops mpl115_spi_ops = {
+ .init = mpl115_spi_init,
+ .read = mpl115_spi_read,
+ .write = mpl115_spi_write,
+};
+
+static int mpl115_spi_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+
+ return mpl115_probe(&spi->dev, id->name, &mpl115_spi_ops);
+}
+
+static const struct spi_device_id mpl115_spi_ids[] = {
+ { "mpl115", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, mpl115_spi_ids);
+
+static struct spi_driver mpl115_spi_driver = {
+ .driver = {
+ .name = "mpl115",
+ },
+ .probe = mpl115_spi_probe,
+ .id_table = mpl115_spi_ids,
+};
+module_spi_driver(mpl115_spi_driver);
+
+MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
+MODULE_DESCRIPTION("Freescale MPL115A1 pressure/temperature driver");
+MODULE_LICENSE("GPL");