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