// SPDX-License-Identifier: GPL-2.0-or-later /* * Device driver for the HMC5843 multi-chip module designed * for low field magnetic sensing. * * Copyright (C) 2010 Texas Instruments * * Author: Shubhrajyoti Datta <shubhrajyoti@ti.com> * Acknowledgment: Jonathan Cameron <jic23@kernel.org> for valuable inputs. * Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>. * Split to multiple files by Josef Gajdusek <atx@atx.name> - 2014
*/
/* * Range gain settings in (+-)Ga * Beware: HMC5843 and HMC5883 have different recommended sensor field * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
*/ #define HMC5843_RANGE_GAIN_OFFSET 0x05 #define HMC5843_RANGE_GAIN_DEFAULT 0x01 #define HMC5843_RANGE_GAIN_MASK 0xe0
/* Device status */ #define HMC5843_DATA_READY 0x01 #define HMC5843_DATA_OUTPUT_LOCK 0x02
/* * API for setting the measurement configuration to * Normal, Positive bias and Negative bias * * From the datasheet: * 0 - Normal measurement configuration (default): In normal measurement * configuration the device follows normal measurement flow. Pins BP * and BN are left floating and high impedance. * * 1 - Positive bias configuration: In positive bias configuration, a * positive current is forced across the resistive load on pins BP * and BN. * * 2 - Negative bias configuration. In negative bias configuration, a * negative current is forced across the resistive load on pins BP * and BN. * * 3 - Only available on HMC5983. Magnetic sensor is disabled. * Temperature sensor is enabled.
*/
/* The lower two bits contain the current conversion mode */ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
{ int ret;
mutex_lock(&data->lock);
ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
HMC5843_MODE_MASK, operating_mode);
mutex_unlock(&data->lock);
return ret;
}
staticint hmc5843_wait_measurement(struct hmc5843_data *data)
{ int tries = 150; unsignedint val; int ret;
while (tries-- > 0) {
ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val); if (ret < 0) return ret; if (val & HMC5843_DATA_READY) break;
msleep(20);
}
if (tries < 0) {
dev_err(data->dev, "data not ready\n"); return -EIO;
}
return 0;
}
/* Return the measurement value from the specified channel */ staticint hmc5843_read_measurement(struct hmc5843_data *data, int idx, int *val)
{
__be16 values[3]; int ret;
mutex_lock(&data->lock);
ret = hmc5843_wait_measurement(data); if (ret < 0) {
mutex_unlock(&data->lock); return ret;
}
ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
values, sizeof(values));
mutex_unlock(&data->lock); if (ret < 0) return ret;
for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%d ", data->variant->regval_to_samp_freq[i][0],
data->variant->regval_to_samp_freq[i][1]);
/* replace trailing space by newline */
buf[len - 1] = '\n';
staticint hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
{ int ret;
mutex_lock(&data->lock);
ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
HMC5843_RATE_MASK,
rate << HMC5843_RATE_OFFSET);
mutex_unlock(&data->lock);
return ret;
}
staticint hmc5843_get_samp_freq_index(struct hmc5843_data *data, int val, int val2)
{ int i;
for (i = 0; i < data->variant->n_regval_to_samp_freq; i++) if (val == data->variant->regval_to_samp_freq[i][0] &&
val2 == data->variant->regval_to_samp_freq[i][1]) return i;
return -EINVAL;
}
staticint hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
{ int ret;
mutex_lock(&data->lock);
ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
HMC5843_RANGE_GAIN_MASK,
range << HMC5843_RANGE_GAIN_OFFSET);
mutex_unlock(&data->lock);
for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09d ", data->variant->regval_to_nanoscale[i]);
/* replace trailing space by newline */
buf[len - 1] = '\n';
/* Beware: Y and Z are exchanged on HMC5883 and 5983 */ staticconststruct iio_chan_spec hmc5883_channels[] = {
HMC5843_CHANNEL(X, 0),
HMC5843_CHANNEL(Z, 1),
HMC5843_CHANNEL(Y, 2),
IIO_CHAN_SOFT_TIMESTAMP(3),
};
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.