diff --git a/drivers/hwmon/adt7310.c b/drivers/hwmon/adt7310.c index da5f0789fb97..5994cf68e0a4 100644 --- a/drivers/hwmon/adt7310.c +++ b/drivers/hwmon/adt7310.c @@ -42,13 +42,8 @@ static const u8 adt7310_reg_table[] = { static int adt7310_spi_read_word(struct device *dev, u8 reg) { struct spi_device *spi = to_spi_device(dev); - int ret; - ret = spi_w8r16(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ); - if (ret < 0) - return ret; - - return be16_to_cpu((__force __be16)ret); + return spi_w8r16be(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ); } static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data) diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 74025fbae679..abfc8bd1794d 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -86,7 +86,7 @@ static int ade7753_spi_read_reg_16(struct device *dev, struct ade7753_state *st = iio_priv(indio_dev); ssize_t ret; - ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address)); + ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address)); if (ret < 0) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", reg_address); @@ -94,7 +94,6 @@ static int ade7753_spi_read_reg_16(struct device *dev, } *val = ret; - *val = be16_to_cpup(val); return 0; } diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index f649ebe55a04..3d1c02cd6538 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -86,7 +86,7 @@ static int ade7754_spi_read_reg_16(struct device *dev, struct ade7754_state *st = iio_priv(indio_dev); int ret; - ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address)); + ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address)); if (ret < 0) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", reg_address); @@ -94,7 +94,6 @@ static int ade7754_spi_read_reg_16(struct device *dev, } *val = ret; - *val = be16_to_cpup(val); return 0; } diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index d214ac4932cb..7467e51fd424 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -86,7 +86,7 @@ static int ade7759_spi_read_reg_16(struct device *dev, struct ade7759_state *st = iio_priv(indio_dev); int ret; - ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address)); + ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address)); if (ret < 0) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", reg_address); @@ -94,7 +94,6 @@ static int ade7759_spi_read_reg_16(struct device *dev, } *val = ret; - *val = be16_to_cpup(val); return 0; } diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 1619ed48e75d..8c62ba74dd91 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -853,6 +853,33 @@ static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd) return (status < 0) ? status : result; } +/** + * spi_w8r16be - SPI synchronous 8 bit write followed by 16 bit big-endian read + * @spi: device with which data will be exchanged + * @cmd: command to be written before data is read back + * Context: can sleep + * + * This returns the (unsigned) sixteen bit number returned by the device in cpu + * endianness, or else a negative error code. Callable only from contexts that + * can sleep. + * + * This function is similar to spi_w8r16, with the exception that it will + * convert the read 16 bit data word from big-endian to native endianness. + * + */ +static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd) + +{ + ssize_t status; + __be16 result; + + status = spi_write_then_read(spi, &cmd, 1, &result, 2); + if (status < 0) + return status; + + return be16_to_cpu(result); +} + /*---------------------------------------------------------------------------*/ /*