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