/drivers/staging/iio/meter/ade7854-spi.c
C | 370 lines | 315 code | 48 blank | 7 comment | 7 complexity | 39a5cf0e206a0a483a84293b87ef3e47 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
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");