linux/drivers/staging/iio/meter/ade7854-spi.c
<<
>>
Prefs
   1/*
   2 * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (SPI Bus)
   3 *
   4 * Copyright 2010 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/device.h>
  10#include <linux/kernel.h>
  11#include <linux/spi/spi.h>
  12#include <linux/slab.h>
  13#include <linux/module.h>
  14
  15#include <linux/iio/iio.h>
  16#include "ade7854.h"
  17
  18static int ade7854_spi_write_reg_8(struct device *dev,
  19                u16 reg_address,
  20                u8 value)
  21{
  22        int ret;
  23        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  24        struct ade7854_state *st = iio_priv(indio_dev);
  25        struct spi_transfer xfer = {
  26                .tx_buf = st->tx,
  27                .bits_per_word = 8,
  28                .len = 4,
  29        };
  30
  31        mutex_lock(&st->buf_lock);
  32        st->tx[0] = ADE7854_WRITE_REG;
  33        st->tx[1] = (reg_address >> 8) & 0xFF;
  34        st->tx[2] = reg_address & 0xFF;
  35        st->tx[3] = value & 0xFF;
  36
  37        ret = spi_sync_transfer(st->spi, &xfer, 1);
  38        mutex_unlock(&st->buf_lock);
  39
  40        return ret;
  41}
  42
  43static int ade7854_spi_write_reg_16(struct device *dev,
  44                u16 reg_address,
  45                u16 value)
  46{
  47        int ret;
  48        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  49        struct ade7854_state *st = iio_priv(indio_dev);
  50        struct spi_transfer xfer = {
  51                .tx_buf = st->tx,
  52                .bits_per_word = 8,
  53                .len = 5,
  54        };
  55
  56        mutex_lock(&st->buf_lock);
  57        st->tx[0] = ADE7854_WRITE_REG;
  58        st->tx[1] = (reg_address >> 8) & 0xFF;
  59        st->tx[2] = reg_address & 0xFF;
  60        st->tx[3] = (value >> 8) & 0xFF;
  61        st->tx[4] = value & 0xFF;
  62
  63        ret = spi_sync_transfer(st->spi, &xfer, 1);
  64        mutex_unlock(&st->buf_lock);
  65
  66        return ret;
  67}
  68
  69static int ade7854_spi_write_reg_24(struct device *dev,
  70                u16 reg_address,
  71                u32 value)
  72{
  73        int ret;
  74        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  75        struct ade7854_state *st = iio_priv(indio_dev);
  76        struct spi_transfer xfer = {
  77                .tx_buf = st->tx,
  78                .bits_per_word = 8,
  79                .len = 6,
  80        };
  81
  82        mutex_lock(&st->buf_lock);
  83        st->tx[0] = ADE7854_WRITE_REG;
  84        st->tx[1] = (reg_address >> 8) & 0xFF;
  85        st->tx[2] = reg_address & 0xFF;
  86        st->tx[3] = (value >> 16) & 0xFF;
  87        st->tx[4] = (value >> 8) & 0xFF;
  88        st->tx[5] = value & 0xFF;
  89
  90        ret = spi_sync_transfer(st->spi, &xfer, 1);
  91        mutex_unlock(&st->buf_lock);
  92
  93        return ret;
  94}
  95
  96static int ade7854_spi_write_reg_32(struct device *dev,
  97                u16 reg_address,
  98                u32 value)
  99{
 100        int ret;
 101        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 102        struct ade7854_state *st = iio_priv(indio_dev);
 103        struct spi_transfer xfer = {
 104                .tx_buf = st->tx,
 105                .bits_per_word = 8,
 106                .len = 7,
 107        };
 108
 109        mutex_lock(&st->buf_lock);
 110        st->tx[0] = ADE7854_WRITE_REG;
 111        st->tx[1] = (reg_address >> 8) & 0xFF;
 112        st->tx[2] = reg_address & 0xFF;
 113        st->tx[3] = (value >> 24) & 0xFF;
 114        st->tx[4] = (value >> 16) & 0xFF;
 115        st->tx[5] = (value >> 8) & 0xFF;
 116        st->tx[6] = value & 0xFF;
 117
 118        ret = spi_sync_transfer(st->spi, &xfer, 1);
 119        mutex_unlock(&st->buf_lock);
 120
 121        return ret;
 122}
 123
 124static int ade7854_spi_read_reg_8(struct device *dev,
 125                u16 reg_address,
 126                u8 *val)
 127{
 128        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 129        struct ade7854_state *st = iio_priv(indio_dev);
 130        int ret;
 131        struct spi_transfer xfers[] = {
 132                {
 133                        .tx_buf = st->tx,
 134                        .bits_per_word = 8,
 135                        .len = 3,
 136                }, {
 137                        .rx_buf = st->rx,
 138                        .bits_per_word = 8,
 139                        .len = 1,
 140                }
 141        };
 142
 143        mutex_lock(&st->buf_lock);
 144
 145        st->tx[0] = ADE7854_READ_REG;
 146        st->tx[1] = (reg_address >> 8) & 0xFF;
 147        st->tx[2] = reg_address & 0xFF;
 148
 149        ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
 150        if (ret) {
 151                dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X",
 152                                reg_address);
 153                goto error_ret;
 154        }
 155        *val = st->rx[0];
 156
 157error_ret:
 158        mutex_unlock(&st->buf_lock);
 159        return ret;
 160}
 161
 162static int ade7854_spi_read_reg_16(struct device *dev,
 163                u16 reg_address,
 164                u16 *val)
 165{
 166        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 167        struct ade7854_state *st = iio_priv(indio_dev);
 168        int ret;
 169        struct spi_transfer xfers[] = {
 170                {
 171                        .tx_buf = st->tx,
 172                        .bits_per_word = 8,
 173                        .len = 3,
 174                }, {
 175                        .rx_buf = st->rx,
 176                        .bits_per_word = 8,
 177                        .len = 2,
 178                }
 179        };
 180
 181        mutex_lock(&st->buf_lock);
 182        st->tx[0] = ADE7854_READ_REG;
 183        st->tx[1] = (reg_address >> 8) & 0xFF;
 184        st->tx[2] = reg_address & 0xFF;
 185
 186        ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
 187        if (ret) {
 188                dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X",
 189                                reg_address);
 190                goto error_ret;
 191        }
 192        *val = be16_to_cpup((const __be16 *)st->rx);
 193
 194error_ret:
 195        mutex_unlock(&st->buf_lock);
 196        return ret;
 197}
 198
 199static int ade7854_spi_read_reg_24(struct device *dev,
 200                u16 reg_address,
 201                u32 *val)
 202{
 203        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 204        struct ade7854_state *st = iio_priv(indio_dev);
 205        int ret;
 206        struct spi_transfer xfers[] = {
 207                {
 208                        .tx_buf = st->tx,
 209                        .bits_per_word = 8,
 210                        .len = 3,
 211                }, {
 212                        .rx_buf = st->rx,
 213                        .bits_per_word = 8,
 214                        .len = 3,
 215                }
 216        };
 217
 218        mutex_lock(&st->buf_lock);
 219
 220        st->tx[0] = ADE7854_READ_REG;
 221        st->tx[1] = (reg_address >> 8) & 0xFF;
 222        st->tx[2] = reg_address & 0xFF;
 223
 224        ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
 225        if (ret) {
 226                dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X",
 227                                reg_address);
 228                goto error_ret;
 229        }
 230        *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
 231
 232error_ret:
 233        mutex_unlock(&st->buf_lock);
 234        return ret;
 235}
 236
 237static int ade7854_spi_read_reg_32(struct device *dev,
 238                u16 reg_address,
 239                u32 *val)
 240{
 241        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 242        struct ade7854_state *st = iio_priv(indio_dev);
 243        int ret;
 244        struct spi_transfer xfers[] = {
 245                {
 246                        .tx_buf = st->tx,
 247                        .bits_per_word = 8,
 248                        .len = 3,
 249                }, {
 250                        .rx_buf = st->rx,
 251                        .bits_per_word = 8,
 252                        .len = 4,
 253                }
 254        };
 255
 256        mutex_lock(&st->buf_lock);
 257
 258        st->tx[0] = ADE7854_READ_REG;
 259        st->tx[1] = (reg_address >> 8) & 0xFF;
 260        st->tx[2] = reg_address & 0xFF;
 261
 262        ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
 263        if (ret) {
 264                dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X",
 265                                reg_address);
 266                goto error_ret;
 267        }
 268        *val = be32_to_cpup((const __be32 *)st->rx);
 269
 270error_ret:
 271        mutex_unlock(&st->buf_lock);
 272        return ret;
 273}
 274
 275static int ade7854_spi_probe(struct spi_device *spi)
 276{
 277        int ret;
 278        struct ade7854_state *st;
 279        struct iio_dev *indio_dev;
 280
 281        indio_dev = iio_device_alloc(sizeof(*st));
 282        if (indio_dev == NULL)
 283                return -ENOMEM;
 284        st = iio_priv(indio_dev);
 285        spi_set_drvdata(spi, indio_dev);
 286        st->read_reg_8 = ade7854_spi_read_reg_8;
 287        st->read_reg_16 = ade7854_spi_read_reg_16;
 288        st->read_reg_24 = ade7854_spi_read_reg_24;
 289        st->read_reg_32 = ade7854_spi_read_reg_32;
 290        st->write_reg_8 = ade7854_spi_write_reg_8;
 291        st->write_reg_16 = ade7854_spi_write_reg_16;
 292        st->write_reg_24 = ade7854_spi_write_reg_24;
 293        st->write_reg_32 = ade7854_spi_write_reg_32;
 294        st->irq = spi->irq;
 295        st->spi = spi;
 296
 297
 298        ret = ade7854_probe(indio_dev, &spi->dev);
 299        if (ret)
 300                iio_device_free(indio_dev);
 301
 302        return 0;
 303}
 304
 305static int ade7854_spi_remove(struct spi_device *spi)
 306{
 307        ade7854_remove(spi_get_drvdata(spi));
 308
 309        return 0;
 310}
 311static const struct spi_device_id ade7854_id[] = {
 312        { "ade7854", 0 },
 313        { "ade7858", 0 },
 314        { "ade7868", 0 },
 315        { "ade7878", 0 },
 316        { }
 317};
 318MODULE_DEVICE_TABLE(spi, ade7854_id);
 319
 320static struct spi_driver ade7854_driver = {
 321        .driver = {
 322                .name = "ade7854",
 323                .owner = THIS_MODULE,
 324        },
 325        .probe = ade7854_spi_probe,
 326        .remove = ade7854_spi_remove,
 327        .id_table = ade7854_id,
 328};
 329module_spi_driver(ade7854_driver);
 330
 331MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 332MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 SPI Driver");
 333MODULE_LICENSE("GPL v2");
 334