/* inverted crc value as described in device data sheet */
crc = ~crc8(sca3300_crc_table, &sca_data->txbuf[0], 3, CRC8_INIT_VALUE);
sca_data->txbuf[3] = crc;
ret = spi_sync_transfer(sca_data->spi, xfers, ARRAY_SIZE(xfers)); if (ret) {
dev_err(&sca_data->spi->dev, "transfer error, error: %d\n", ret); return -EIO;
}
staticint sca3300_get_op_mode(struct sca3300_data *sca_data, int *index)
{ int reg_val; int ret; int i;
ret = sca3300_read_reg(sca_data, SCA3300_REG_MODE, ®_val); if (ret) return ret;
for (i = 0; i < sca_data->chip->num_avail_modes; i++) { if (sca_data->chip->avail_modes_table[i] == reg_val) break;
} if (i == sca_data->chip->num_avail_modes) return -EINVAL;
*index = i; return 0;
}
staticint sca3300_set_frequency(struct sca3300_data *data, int val)
{ conststruct sca3300_chip_info *chip = data->chip; unsignedint index; int *opmode_scale; int *new_scale; unsignedint i;
if (sca3300_get_op_mode(data, &index)) return -EINVAL;
/* * Find a mode in which the requested sampling frequency is available * and the scaling currently set is retained.
*/
opmode_scale = (int *)chip->accel_scale[chip->accel_scale_map[index]]; for (i = 0; i < chip->num_avail_modes; i++) {
new_scale = (int *)chip->accel_scale[chip->accel_scale_map[i]]; if ((val == chip->freq_table[chip->freq_map[i]]) &&
(opmode_scale[1] == new_scale[1]) &&
(opmode_scale[0] == new_scale[0])) break;
} if (i == chip->num_avail_modes) return -EINVAL;
return sca3300_set_op_mode(data, i);
}
staticint sca3300_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ struct sca3300_data *data = iio_priv(indio_dev); int index; int i;
switch (mask) { case IIO_CHAN_INFO_SCALE: if (chan->type != IIO_ACCEL) return -EINVAL; /* * Letting scale take priority over sampling frequency. * That makes sense given we can only ever end up increasing * the sampling frequency which is unlikely to be a problem.
*/ for (i = 0; i < data->chip->num_avail_modes; i++) {
index = data->chip->accel_scale_map[i]; if ((val == data->chip->accel_scale[index][0]) &&
(val2 == data->chip->accel_scale[index][1])) return sca3300_set_op_mode(data, i);
} return -EINVAL; case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: return sca3300_set_frequency(data, val); default: return -EINVAL;
}
}
staticint sca3300_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ struct sca3300_data *data = iio_priv(indio_dev); int index; int ret;
switch (mask) { case IIO_CHAN_INFO_RAW:
ret = sca3300_read_reg(data, chan->address, val); if (ret) return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE:
ret = sca3300_get_op_mode(data, &index); if (ret) return ret; switch (chan->type) { case IIO_INCLI:
index = data->chip->incli_scale_map[index];
*val = data->chip->incli_scale[index][0];
*val2 = data->chip->incli_scale[index][1]; return IIO_VAL_INT_PLUS_MICRO; case IIO_ACCEL:
index = data->chip->accel_scale_map[index];
*val = data->chip->accel_scale[index][0];
*val2 = data->chip->accel_scale[index][1]; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL;
} case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
ret = sca3300_get_op_mode(data, &index); if (ret) return ret;
index = data->chip->freq_map[index];
*val = data->chip->freq_table[index]; return IIO_VAL_INT; default: return -EINVAL;
}
}
iio_for_each_active_channel(indio_dev, bit) {
ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val); if (ret) {
dev_err_ratelimited(&data->spi->dev, "failed to read register, error: %d\n", ret); /* handled, but bailing out due to errors */ goto out;
}
channels[i++] = val;
}
/* * sca3300_init - Device init sequence. See datasheet rev 2 section * 4.2 Start-Up Sequence for details.
*/ staticint sca3300_init(struct sca3300_data *sca_data, struct iio_dev *indio_dev)
{ int value = 0; int ret; int i;
ret = sca3300_write_reg(sca_data, SCA3300_REG_MODE,
SCA3300_MODE_SW_RESET); if (ret) return ret;
/* * Wait 1ms after SW-reset command. * Wait for the settling of signal paths, * 15ms for SCA3300 and 25ms for SCL3300,
*/
usleep_range(26e3, 50e3);
ret = sca3300_read_reg(sca_data, SCA3300_REG_WHOAMI, &value); if (ret) return ret;
for (i = 0; i < ARRAY_SIZE(sca3300_chip_tbl); i++) { if (sca3300_chip_tbl[i].chip_id == value) break;
} if (i == ARRAY_SIZE(sca3300_chip_tbl)) {
dev_err(&sca_data->spi->dev, "unknown chip id %x\n", value); return -ENODEV;
}
sca_data->chip = &sca3300_chip_tbl[i];
if (sca_data->chip->angle_supported) {
ret = sca3300_write_reg(sca_data, SCL3300_REG_ANG_CTRL,
SCL3300_ANG_ENABLE); if (ret) return ret;
}
return 0;
}
staticint sca3300_debugfs_reg_access(struct iio_dev *indio_dev, unsignedint reg, unsignedint writeval, unsignedint *readval)
{ struct sca3300_data *data = iio_priv(indio_dev); int value; int ret;
if (reg > SCA3300_REG_SELBANK) return -EINVAL;
if (!readval) return sca3300_write_reg(data, reg, writeval);
ret = sca3300_read_reg(data, reg, &value); if (ret) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.