Commit ae6f54d2 authored by Peter Meerwald's avatar Peter Meerwald Committed by Jonathan Cameron

staging:iio:hmc5843: Use SCALE instead of magn_range

v3:
* rename _check_scale() to _get_scale_index()
v2:
* use SCALE instead of CALIBSCALE to control the range/gain
  of measurements
Signed-off-by: default avatarPeter Meerwald <pmeerw@pmeerw.net>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 701a0dc0
...@@ -49,7 +49,7 @@ enum hmc5843_ids { ...@@ -49,7 +49,7 @@ enum hmc5843_ids {
*/ */
#define HMC5843_RANGE_GAIN_OFFSET 0x05 #define HMC5843_RANGE_GAIN_OFFSET 0x05
#define HMC5843_RANGE_GAIN_DEFAULT 0x01 #define HMC5843_RANGE_GAIN_DEFAULT 0x01
#define HMC5843_RANGE_GAIN_MAX 0x07 #define HMC5843_RANGE_GAINS 8
/* Device status */ /* Device status */
#define HMC5843_DATA_READY 0x01 #define HMC5843_DATA_READY 0x01
...@@ -79,64 +79,18 @@ enum hmc5843_ids { ...@@ -79,64 +79,18 @@ enum hmc5843_ids {
#define HMC5843_MEAS_CONF_MASK 0x03 #define HMC5843_MEAS_CONF_MASK 0x03
/* Scaling factors: 10000000/Gain */ /* Scaling factors: 10000000/Gain */
static const int hmc5843_regval_to_nanoscale[] = { static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
}; };
static const int hmc5883_regval_to_nanoscale[] = { static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662 7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
}; };
static const int hmc5883l_regval_to_nanoscale[] = { static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478 7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
}; };
/*
* From the HMC5843 datasheet:
* Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
* 0 | (+-)0.7 | 1620
* 1 | (+-)1.0 | 1300
* 2 | (+-)1.5 | 970
* 3 | (+-)2.0 | 780
* 4 | (+-)3.2 | 530
* 5 | (+-)3.8 | 460
* 6 | (+-)4.5 | 390
* 7 | (+-)6.5 | 280
*
* From the HMC5883 datasheet:
* Value | Recommended sensor field range (Ga) | Gain (counts/Gauss)
* 0 | (+-)0.9 | 1280
* 1 | (+-)1.2 | 1024
* 2 | (+-)1.9 | 768
* 3 | (+-)2.5 | 614
* 4 | (+-)4.0 | 415
* 5 | (+-)4.6 | 361
* 6 | (+-)5.5 | 307
* 7 | (+-)7.9 | 219
*
* From the HMC5883L datasheet:
* Value | Recommended sensor field range (Ga) | Gain (LSB/Gauss)
* 0 | (+-)0.88 | 1370
* 1 | (+-)1.3 | 1090
* 2 | (+-)1.9 | 820
* 3 | (+-)2.5 | 660
* 4 | (+-)4.0 | 440
* 5 | (+-)4.7 | 390
* 6 | (+-)5.6 | 330
* 7 | (+-)8.1 | 230
*/
static const int hmc5843_regval_to_input_field_mga[] = {
700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
};
static const int hmc5883_regval_to_input_field_mga[] = {
900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
};
static const int hmc5883l_regval_to_input_field_mga[] = {
880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
};
/* /*
* From the datasheet: * From the datasheet:
* Value | HMC5843 | HMC5883/HMC5883L * Value | HMC5843 | HMC5883/HMC5883L
...@@ -163,7 +117,6 @@ static const int hmc5883_regval_to_samp_freq[7][2] = { ...@@ -163,7 +117,6 @@ static const int hmc5883_regval_to_samp_freq[7][2] = {
struct hmc5843_chip_info { struct hmc5843_chip_info {
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
const int (*regval_to_samp_freq)[2]; const int (*regval_to_samp_freq)[2];
const int *regval_to_input_field_mga;
const int *regval_to_nanoscale; const int *regval_to_nanoscale;
}; };
...@@ -412,58 +365,41 @@ static int hmc5843_check_samp_freq(struct hmc5843_data *data, ...@@ -412,58 +365,41 @@ static int hmc5843_check_samp_freq(struct hmc5843_data *data,
val, val2); val, val2);
} }
static ssize_t hmc5843_show_range_gain(struct device *dev, static ssize_t hmc5843_show_scale_avail(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr, char *buf)
char *buf)
{ {
u8 range; struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct hmc5843_data *data = iio_priv(indio_dev);
range = data->range; size_t len = 0;
return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]); int i;
for (i = 0; i < HMC5843_RANGE_GAINS; 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';
return len;
} }
static ssize_t hmc5843_set_range_gain(struct device *dev, static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
struct device_attribute *attr, hmc5843_show_scale_avail, NULL, 0);
const char *buf,
size_t count)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
struct hmc5843_data *data = iio_priv(indio_dev);
unsigned long range = 0;
int error;
mutex_lock(&data->lock); static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
error = kstrtoul(buf, 10, &range); {
if (error) { int i;
count = error;
goto exit;
}
dev_dbg(dev, "set range to %lu\n", range);
if (range > HMC5843_RANGE_GAIN_MAX) { if (val != 0)
count = -EINVAL; return -EINVAL;
goto exit;
}
data->range = range; for (i = 0; i < HMC5843_RANGE_GAINS; i++)
range = range << HMC5843_RANGE_GAIN_OFFSET; if (val2 == data->variant->regval_to_nanoscale[i])
if (i2c_smbus_write_byte_data(data->client, this_attr->address, range)) return i;
count = -EINVAL;
exit: return -EINVAL;
mutex_unlock(&data->lock);
return count;
} }
static IIO_DEVICE_ATTR(in_magn_range,
S_IWUSR | S_IRUGO,
hmc5843_show_range_gain,
hmc5843_set_range_gain,
HMC5843_CONFIG_REG_B);
static int hmc5843_read_raw(struct iio_dev *indio_dev, static int hmc5843_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
int *val, int *val2, long mask) int *val, int *val2, long mask)
...@@ -490,7 +426,7 @@ static int hmc5843_write_raw(struct iio_dev *indio_dev, ...@@ -490,7 +426,7 @@ static int hmc5843_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask) int val, int val2, long mask)
{ {
struct hmc5843_data *data = iio_priv(indio_dev); struct hmc5843_data *data = iio_priv(indio_dev);
int ret, rate; int ret, rate, range;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
...@@ -505,6 +441,33 @@ static int hmc5843_write_raw(struct iio_dev *indio_dev, ...@@ -505,6 +441,33 @@ static int hmc5843_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
return ret; return ret;
case IIO_CHAN_INFO_SCALE:
range = hmc5843_get_scale_index(data, val, val2);
if (range < 0)
return -EINVAL;
range <<= HMC5843_RANGE_GAIN_OFFSET;
mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(data->client,
HMC5843_CONFIG_REG_B, range);
if (ret >= 0)
data->range = range;
mutex_unlock(&data->lock);
return ret;
default:
return -EINVAL;
}
}
static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, long mask)
{
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SCALE:
return IIO_VAL_INT_PLUS_NANO;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -536,7 +499,7 @@ static const struct iio_chan_spec hmc5883_channels[] = { ...@@ -536,7 +499,7 @@ static const struct iio_chan_spec hmc5883_channels[] = {
static struct attribute *hmc5843_attributes[] = { static struct attribute *hmc5843_attributes[] = {
&iio_dev_attr_meas_conf.dev_attr.attr, &iio_dev_attr_meas_conf.dev_attr.attr,
&iio_dev_attr_operating_mode.dev_attr.attr, &iio_dev_attr_operating_mode.dev_attr.attr,
&iio_dev_attr_in_magn_range.dev_attr.attr, &iio_dev_attr_scale_available.dev_attr.attr,
&iio_dev_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL NULL
}; };
...@@ -549,22 +512,16 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = { ...@@ -549,22 +512,16 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = { [HMC5843_ID] = {
.channels = hmc5843_channels, .channels = hmc5843_channels,
.regval_to_samp_freq = hmc5843_regval_to_samp_freq, .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
.regval_to_input_field_mga =
hmc5843_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5843_regval_to_nanoscale, .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
}, },
[HMC5883_ID] = { [HMC5883_ID] = {
.channels = hmc5883_channels, .channels = hmc5883_channels,
.regval_to_samp_freq = hmc5883_regval_to_samp_freq, .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
.regval_to_input_field_mga =
hmc5883_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5883_regval_to_nanoscale, .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
}, },
[HMC5883L_ID] = { [HMC5883L_ID] = {
.channels = hmc5883_channels, .channels = hmc5883_channels,
.regval_to_samp_freq = hmc5883_regval_to_samp_freq, .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
.regval_to_input_field_mga =
hmc5883l_regval_to_input_field_mga,
.regval_to_nanoscale = hmc5883l_regval_to_nanoscale, .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
}, },
}; };
...@@ -582,6 +539,7 @@ static const struct iio_info hmc5843_info = { ...@@ -582,6 +539,7 @@ static const struct iio_info hmc5843_info = {
.attrs = &hmc5843_group, .attrs = &hmc5843_group,
.read_raw = &hmc5843_read_raw, .read_raw = &hmc5843_read_raw,
.write_raw = &hmc5843_write_raw, .write_raw = &hmc5843_write_raw,
.write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment