On 10/16/13 23:19, Peter Meerwald wrote: > v3: > * rename _check_scale() to _get_scale_index() > v2: > * use SCALE instead of CALIBSCALE to control the range/gain > of measurements > > Signed-off-by: Peter Meerwald <pmeerw@xxxxxxxxxx> Applied to the togreg branch of iio.git Thanks > --- > drivers/staging/iio/magnetometer/hmc5843.c | 160 +++++++++++------------------ > 1 file changed, 59 insertions(+), 101 deletions(-) > > diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c > index b29622c..c56db41 100644 > --- a/drivers/staging/iio/magnetometer/hmc5843.c > +++ b/drivers/staging/iio/magnetometer/hmc5843.c > @@ -49,7 +49,7 @@ enum hmc5843_ids { > */ > #define HMC5843_RANGE_GAIN_OFFSET 0x05 > #define HMC5843_RANGE_GAIN_DEFAULT 0x01 > -#define HMC5843_RANGE_GAIN_MAX 0x07 > +#define HMC5843_RANGE_GAINS 8 > > /* Device status */ > #define HMC5843_DATA_READY 0x01 > @@ -79,65 +79,19 @@ enum hmc5843_ids { > #define HMC5843_MEAS_CONF_MASK 0x03 > > /* 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 > }; > > -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 > }; > > -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 > }; > > /* > - * 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: > * Value | HMC5843 | HMC5883/HMC5883L > * | Data output rate (Hz) | Data output rate (Hz) > @@ -163,7 +117,6 @@ static const int hmc5883_regval_to_samp_freq[7][2] = { > struct hmc5843_chip_info { > const struct iio_chan_spec *channels; > const int (*regval_to_samp_freq)[2]; > - const int *regval_to_input_field_mga; > const int *regval_to_nanoscale; > }; > > @@ -412,58 +365,41 @@ static int hmc5843_check_samp_freq(struct hmc5843_data *data, > val, val2); > } > > -static ssize_t hmc5843_show_range_gain(struct device *dev, > - struct device_attribute *attr, > - char *buf) > +static ssize_t hmc5843_show_scale_avail(struct device *dev, > + struct device_attribute *attr, char *buf) > { > - u8 range; > - struct iio_dev *indio_dev = dev_to_iio_dev(dev); > - struct hmc5843_data *data = iio_priv(indio_dev); > + struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev)); > + > + size_t len = 0; > + int i; > > - range = data->range; > - return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]); > + 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, > - struct device_attribute *attr, > - 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; > +static IIO_DEVICE_ATTR(scale_available, S_IRUGO, > + hmc5843_show_scale_avail, NULL, 0); > > - mutex_lock(&data->lock); > - error = kstrtoul(buf, 10, &range); > - if (error) { > - count = error; > - goto exit; > - } > - dev_dbg(dev, "set range to %lu\n", range); > +static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2) > +{ > + int i; > > - if (range > HMC5843_RANGE_GAIN_MAX) { > - count = -EINVAL; > - goto exit; > - } > + if (val != 0) > + return -EINVAL; > > - data->range = range; > - range = range << HMC5843_RANGE_GAIN_OFFSET; > - if (i2c_smbus_write_byte_data(data->client, this_attr->address, range)) > - count = -EINVAL; > + for (i = 0; i < HMC5843_RANGE_GAINS; i++) > + if (val2 == data->variant->regval_to_nanoscale[i]) > + return i; > > -exit: > - mutex_unlock(&data->lock); > - return count; > + return -EINVAL; > } > > -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, > struct iio_chan_spec const *chan, > int *val, int *val2, long mask) > @@ -490,7 +426,7 @@ static int hmc5843_write_raw(struct iio_dev *indio_dev, > int val, int val2, long mask) > { > struct hmc5843_data *data = iio_priv(indio_dev); > - int ret, rate; > + int ret, rate, range; > > switch (mask) { > case IIO_CHAN_INFO_SAMP_FREQ: > @@ -505,6 +441,33 @@ static int hmc5843_write_raw(struct iio_dev *indio_dev, > mutex_unlock(&data->lock); > > 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: > return -EINVAL; > } > @@ -536,7 +499,7 @@ static const struct iio_chan_spec hmc5883_channels[] = { > static struct attribute *hmc5843_attributes[] = { > &iio_dev_attr_meas_conf.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, > NULL > }; > @@ -549,22 +512,16 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = { > [HMC5843_ID] = { > .channels = hmc5843_channels, > .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, > }, > [HMC5883_ID] = { > .channels = hmc5883_channels, > .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, > }, > [HMC5883L_ID] = { > .channels = hmc5883_channels, > .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, > }, > }; > @@ -582,6 +539,7 @@ static const struct iio_info hmc5843_info = { > .attrs = &hmc5843_group, > .read_raw = &hmc5843_read_raw, > .write_raw = &hmc5843_write_raw, > + .write_raw_get_fmt = &hmc5843_write_raw_get_fmt, > .driver_module = THIS_MODULE, > }; > > -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html