Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Freescale MPL115A1 pressure/temperature sensor
0004  *
0005  * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
0006  *
0007  * Datasheet: http://www.nxp.com/files/sensors/doc/data_sheet/MPL115A1.pdf
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/spi/spi.h>
0012 
0013 #include "mpl115.h"
0014 
0015 #define MPL115_SPI_WRITE(address)   ((address) << 1)
0016 #define MPL115_SPI_READ(address)    (0x80 | (address) << 1)
0017 
0018 struct mpl115_spi_buf {
0019     u8 tx[4];
0020     u8 rx[4];
0021 };
0022 
0023 static int mpl115_spi_init(struct device *dev)
0024 {
0025     struct spi_device *spi = to_spi_device(dev);
0026     struct mpl115_spi_buf *buf;
0027 
0028     buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL);
0029     if (!buf)
0030         return -ENOMEM;
0031 
0032     spi_set_drvdata(spi, buf);
0033 
0034     return 0;
0035 }
0036 
0037 static int mpl115_spi_read(struct device *dev, u8 address)
0038 {
0039     struct spi_device *spi = to_spi_device(dev);
0040     struct mpl115_spi_buf *buf = spi_get_drvdata(spi);
0041     struct spi_transfer xfer = {
0042         .tx_buf = buf->tx,
0043         .rx_buf = buf->rx,
0044         .len = 4,
0045     };
0046     int ret;
0047 
0048     buf->tx[0] = MPL115_SPI_READ(address);
0049     buf->tx[2] = MPL115_SPI_READ(address + 1);
0050 
0051     ret = spi_sync_transfer(spi, &xfer, 1);
0052     if (ret)
0053         return ret;
0054 
0055     return (buf->rx[1] << 8) | buf->rx[3];
0056 }
0057 
0058 static int mpl115_spi_write(struct device *dev, u8 address, u8 value)
0059 {
0060     struct spi_device *spi = to_spi_device(dev);
0061     struct mpl115_spi_buf *buf = spi_get_drvdata(spi);
0062     struct spi_transfer xfer = {
0063         .tx_buf = buf->tx,
0064         .len = 2,
0065     };
0066 
0067     buf->tx[0] = MPL115_SPI_WRITE(address);
0068     buf->tx[1] = value;
0069 
0070     return spi_sync_transfer(spi, &xfer, 1);
0071 }
0072 
0073 static const struct mpl115_ops mpl115_spi_ops = {
0074     .init = mpl115_spi_init,
0075     .read = mpl115_spi_read,
0076     .write = mpl115_spi_write,
0077 };
0078 
0079 static int mpl115_spi_probe(struct spi_device *spi)
0080 {
0081     const struct spi_device_id *id = spi_get_device_id(spi);
0082 
0083     return mpl115_probe(&spi->dev, id->name, &mpl115_spi_ops);
0084 }
0085 
0086 static const struct spi_device_id mpl115_spi_ids[] = {
0087     { "mpl115", 0 },
0088     {}
0089 };
0090 MODULE_DEVICE_TABLE(spi, mpl115_spi_ids);
0091 
0092 static struct spi_driver mpl115_spi_driver = {
0093     .driver = {
0094         .name   = "mpl115",
0095     },
0096     .probe = mpl115_spi_probe,
0097     .id_table = mpl115_spi_ids,
0098 };
0099 module_spi_driver(mpl115_spi_driver);
0100 
0101 MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
0102 MODULE_DESCRIPTION("Freescale MPL115A1 pressure/temperature driver");
0103 MODULE_LICENSE("GPL");
0104 MODULE_IMPORT_NS(IIO_MPL115);