static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) { int ret, i; struct kxsd9_state *st = iio_priv(indio_dev); bool foundit = false; for (i = 0; i < 4; i++) if (micro == kxsd9_micro_scales[i]) { foundit = true; break; } if (!foundit) return -EINVAL; mutex_lock(&st->buf_lock); ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C)); if (ret) goto error_ret; st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C); st->tx[1] = (ret & ~KXSD9_FS_MASK) | i; ret = spi_write(st->us, st->tx, 2); error_ret: mutex_unlock(&st->buf_lock); return ret; }
struct kxsd9_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .bits_per_word = 8, .len = 1, .delay_usecs = 200, .tx_buf = st->tx, }, { .bits_per_word = 8, .len = 2, .rx_buf = st->rx, }, }; mutex_lock(&st->buf_lock); st->tx[0] = KXSD9_READ(address); spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->us, &msg); if (ret) return ret; return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0); } static IIO_CONST_ATTR(accel_scale_available, KXSD9_SCALE_2G " " KXSD9_SCALE_4G " " KXSD9_SCALE_6G " " KXSD9_SCALE_8G);
/* This may want to move to mili g to allow for non integer ranges */ static ssize_t kxsd9_read_scale(struct device *dev, struct device_attribute *attr, char *buf) { int ret; ssize_t len = 0; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct kxsd9_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .bits_per_word = 8, .len = 2, .cs_change = 1, .tx_buf = st->tx, .rx_buf = st->rx, }; struct spi_message msg; mutex_lock(&st->buf_lock); st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C); st->tx[1] = 0; spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->us, &msg); if (ret) goto error_ret; switch (st->rx[1] & KXSD9_FS_MASK) { case KXSD9_FS_8: len += sprintf(buf, "%s\n", KXSD9_SCALE_8G); break; case KXSD9_FS_6: len += sprintf(buf, "%s\n", KXSD9_SCALE_6G); break; case KXSD9_FS_4: len += sprintf(buf, "%s\n", KXSD9_SCALE_4G); break; case KXSD9_FS_2: len += sprintf(buf, "%s\n", KXSD9_SCALE_2G); break; } error_ret: mutex_unlock(&st->buf_lock); return ret ? ret : len; } static ssize_t kxsd9_write_scale(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct spi_message msg; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct kxsd9_state *st = iio_priv(indio_dev); u8 val; struct spi_transfer xfers[] = { { .bits_per_word = 8, .len = 2, .cs_change = 1, .tx_buf = st->tx, .rx_buf = st->rx, }, { .bits_per_word = 8, .len = 2, .cs_change = 1, .tx_buf = st->tx, }, };