/*
 * STMicroelectronics sensors core library driver
 *
 * Copyright 2012-2013 STMicroelectronics Inc.
 *
 * Denis Ciocca <denis.ciocca@st.com>
 *
 * Licensed under the GPL-2.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/regulator/consumer.h>
#include <linux/of.h>
#include <asm/unaligned.h>
#include <linux/iio/common/st_sensors.h>


#define ST_SENSORS_WAI_ADDRESS		0x0f

static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
{
	return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8;
}

static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
						u8 reg_addr, u8 mask, u8 data)
{
	int err;
	u8 new_data;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	if (reg_addr <= 0) {
		err = -EINVAL;
		goto st_sensors_write_data_with_mask_error;
	}

	err = sdata->tf->read_byte(&sdata->tb, sdata->dev, reg_addr, &new_data);
	if (err < 0) {
		printk("SUN-5941: %s read_byte %d\n", __PRETTY_FUNCTION__, err);
		goto st_sensors_write_data_with_mask_error;
	}

	new_data = ((new_data & (~mask)) | ((data << __ffs(mask)) & mask));
	err = sdata->tf->write_byte(&sdata->tb, sdata->dev, reg_addr, new_data);
	if (err < 0)
		printk("SUN-5941: %s write_byte %d\n", __PRETTY_FUNCTION__, err);

st_sensors_write_data_with_mask_error:
	return err;
}

static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings,
			unsigned int odr, struct st_sensor_odr_avl *odr_out)
{
	int i, ret = -EINVAL;

	for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
		if (sensor_settings->odr.odr_avl[i].hz == 0)
			goto st_sensors_match_odr_error;

		if (sensor_settings->odr.odr_avl[i].hz == odr) {
			odr_out->hz = sensor_settings->odr.odr_avl[i].hz;
			odr_out->value = sensor_settings->odr.odr_avl[i].value;
			ret = 0;
			break;
		}
	}

st_sensors_match_odr_error:
	return ret;
}

int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
{
	int err;
	struct st_sensor_odr_avl odr_out = {0, 0};
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out);
	if (err < 0)
		goto st_sensors_match_odr_error;

	if ((sdata->sensor_settings->odr.addr ==
					sdata->sensor_settings->pw.addr) &&
				(sdata->sensor_settings->odr.mask ==
					sdata->sensor_settings->pw.mask)) {
		if (sdata->enabled == true) {
			err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->odr.addr,
				sdata->sensor_settings->odr.mask,
				odr_out.value);
		} else {
			err = 0;
		}
	} else {
		err = st_sensors_write_data_with_mask(indio_dev,
			sdata->sensor_settings->odr.addr,
			sdata->sensor_settings->odr.mask,
			odr_out.value);
	}
	if (err >= 0)
		sdata->odr = odr_out.hz;

st_sensors_match_odr_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_set_odr);

static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings,
					unsigned int fs, int *index_fs_avl)
{
	int i, ret = -EINVAL;

	for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
		if (sensor_settings->fs.fs_avl[i].num == 0)
			goto st_sensors_match_odr_error;

		if (sensor_settings->fs.fs_avl[i].num == fs) {
			*index_fs_avl = i;
			ret = 0;
			break;
		}
	}

st_sensors_match_odr_error:
	return ret;
}

static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
{
	int err, i = 0;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = st_sensors_match_fs(sdata->sensor_settings, fs, &i);
	if (err < 0)
		goto st_accel_set_fullscale_error;

	err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->fs.addr,
				sdata->sensor_settings->fs.mask,
				sdata->sensor_settings->fs.fs_avl[i].value);
	if (err < 0)
		goto st_accel_set_fullscale_error;

	sdata->current_fullscale = (struct st_sensor_fullscale_avl *)
					&sdata->sensor_settings->fs.fs_avl[i];
	return err;

st_accel_set_fullscale_error:
	dev_err(&indio_dev->dev, "failed to set new fullscale.\n");
	return err;
}

int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
{
	u8 tmp_value;
	int err = -EINVAL;
	bool found = false;
	struct st_sensor_odr_avl odr_out = {0, 0};
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	if (enable) {
		tmp_value = sdata->sensor_settings->pw.value_on;
		if ((sdata->sensor_settings->odr.addr ==
					sdata->sensor_settings->pw.addr) &&
				(sdata->sensor_settings->odr.mask ==
					sdata->sensor_settings->pw.mask)) {
			err = st_sensors_match_odr(sdata->sensor_settings,
							sdata->odr, &odr_out);
			if (err < 0)
				goto set_enable_error;
			tmp_value = odr_out.value;
			found = true;
		}
		err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->pw.addr,
				sdata->sensor_settings->pw.mask, tmp_value);
		if (err < 0)
			goto set_enable_error;

		sdata->enabled = true;

		if (found)
			sdata->odr = odr_out.hz;
	} else {
		err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->pw.addr,
				sdata->sensor_settings->pw.mask,
				sdata->sensor_settings->pw.value_off);
		if (err < 0)
			goto set_enable_error;

		sdata->enabled = false;
	}

set_enable_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_set_enable);

int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	return st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->enable_axis.addr,
				sdata->sensor_settings->enable_axis.mask,
				axis_enable);
}
EXPORT_SYMBOL(st_sensors_set_axis_enable);

void st_sensors_power_enable(struct iio_dev *indio_dev)
{
	struct st_sensor_data *pdata = iio_priv(indio_dev);
	int err;

	/* Regulators not mandatory, but if requested we should enable them. */
	pdata->vdd = devm_regulator_get_optional(indio_dev->dev.parent, "vdd");
	if (!IS_ERR(pdata->vdd)) {
		err = regulator_enable(pdata->vdd);
		if (err != 0)
			dev_warn(&indio_dev->dev,
				 "Failed to enable specified Vdd supply\n");
	}

	pdata->vdd_io = devm_regulator_get_optional(indio_dev->dev.parent, "vddio");
	if (!IS_ERR(pdata->vdd_io)) {
		err = regulator_enable(pdata->vdd_io);
		if (err != 0)
			dev_warn(&indio_dev->dev,
				 "Failed to enable specified Vdd_IO supply\n");
	}
}
EXPORT_SYMBOL(st_sensors_power_enable);

void st_sensors_power_disable(struct iio_dev *indio_dev)
{
	struct st_sensor_data *pdata = iio_priv(indio_dev);

	if (!IS_ERR(pdata->vdd))
		regulator_disable(pdata->vdd);

	if (!IS_ERR(pdata->vdd_io))
		regulator_disable(pdata->vdd_io);
}
EXPORT_SYMBOL(st_sensors_power_disable);

static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
					struct st_sensors_platform_data *pdata)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	switch (pdata->drdy_int_pin) {
	case 1:
		if (sdata->sensor_settings->drdy_irq.mask_int1 == 0) {
			dev_err(&indio_dev->dev,
					"DRDY on INT1 not available.\n");
			return -EINVAL;
		}
		sdata->drdy_int_pin = 1;
		break;
	case 2:
		if (sdata->sensor_settings->drdy_irq.mask_int2 == 0) {
			dev_err(&indio_dev->dev,
					"DRDY on INT2 not available.\n");
			return -EINVAL;
		}
		sdata->drdy_int_pin = 2;
		break;
	default:
		dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
		return -EINVAL;
	}

	return 0;
}

#ifdef CONFIG_OF
static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
		struct st_sensors_platform_data *defdata)
{
	struct st_sensors_platform_data *pdata;
	struct device_node *np = dev->of_node;
	u32 val;

	if (!np)
		return NULL;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!of_property_read_u32(np, "st,drdy-int-pin", &val) && (val <= 2))
		pdata->drdy_int_pin = (u8) val;
	else
		pdata->drdy_int_pin = defdata ? defdata->drdy_int_pin : 1;

	return pdata;
}
#else
static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
		struct st_sensors_platform_data *defdata)
{
	return NULL;
}
#endif

int st_sensors_init_sensor(struct iio_dev *indio_dev,
					struct st_sensors_platform_data *pdata)
{
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	struct st_sensors_platform_data *of_pdata;
	int err = 0;

	/* If OF/DT pdata exists, it will take precedence of anything else */
	of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata);
	if (of_pdata)
		pdata = of_pdata;

	if (pdata) {
		err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
		if (err < 0)
			return err;
	}

	err = st_sensors_set_enable(indio_dev, false);
	if (err < 0)
		return err;

	/* Disable DRDY, this might be still be enabled after reboot. */
	err = st_sensors_set_dataready_irq(indio_dev, false);
	if (err < 0)
		return err;

	if (sdata->current_fullscale) {
		err = st_sensors_set_fullscale(indio_dev,
						sdata->current_fullscale->num);
		if (err < 0)
			return err;
	} else
		dev_info(&indio_dev->dev, "Full-scale not possible\n");

	err = st_sensors_set_odr(indio_dev, sdata->odr);
	if (err < 0)
		return err;

	/* set BDU */
	err = st_sensors_write_data_with_mask(indio_dev,
					sdata->sensor_settings->bdu.addr,
					sdata->sensor_settings->bdu.mask, true);
	if (err < 0)
		return err;

	err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);

	return err;
}
EXPORT_SYMBOL(st_sensors_init_sensor);

static int st_sensors_set_ths(struct iio_dev *indio_dev, unsigned int ths)
{
	int err;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = st_sensors_write_data_with_mask(indio_dev,
					      sdata->sensor_settings->ths.addr,
					      sdata->sensor_settings->ths.mask,
					      ths);
	if (err < 0)
		return err;

	return 0;
}

static int st_sensors_set_dur(struct iio_dev *indio_dev, unsigned int dur)
{
	int err;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = st_sensors_write_data_with_mask(indio_dev,
						sdata->sensor_settings->dur.addr,
						sdata->sensor_settings->dur.mask, dur);
	if (err < 0)
		return err;

	return 0;
}

int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
{
	int err;
	u8 drdy_mask;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	if (!sdata->sensor_settings->drdy_irq.addr)
		return 0;

	/* Set non-latched mode as data-ready is anyways going to flood
	 * us with interrupts */
	if (sdata->sensor_settings->lir1.addr > 0) {
		err = st_sensors_write_data_with_mask(indio_dev,
						sdata->sensor_settings->lir1.addr,
						sdata->sensor_settings->lir1.mask,
						(int)0x0);
		if (err < 0)
			goto st_accel_set_dataready_irq_error;
	}

	/* Clear any pending latched interrupts */
	if (sdata->sensor_settings->int1_src.addr > 0) {
		u8 data;
		err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
					   sdata->sensor_settings->int1_src.addr, &data);
		if (err < 0)
			goto st_accel_set_dataready_irq_error;
	}

	/* Disable {XYZ}{HL}IE INT1 interrupt generation bits */
	if (sdata->sensor_settings->int1_cfg.addr > 0) {
		err = st_sensors_write_data_with_mask(indio_dev,
					sdata->sensor_settings->int1_cfg.addr,
					sdata->sensor_settings->int1_cfg.mask,
					(int)sdata->sensor_settings->int1_cfg.value_off);
		if (err < 0)
			goto st_accel_set_dataready_irq_error;
	}

	/* Reset HP Filter settings */
	if (sdata->sensor_settings->hp_filter_mode.addr > 0) {
		err = st_sensors_write_data_with_mask(indio_dev,
			       sdata->sensor_settings->hp_filter_mode.addr,
			       sdata->sensor_settings->hp_filter_mode.fds_mask,
			       false);
		if (err < 0)
			goto st_accel_set_dataready_irq_error;

		err = st_sensors_write_data_with_mask(indio_dev,
			       sdata->sensor_settings->hp_filter_mode.addr,
			       sdata->sensor_settings->hp_filter_mode.hpis1_mask,
			       false);
		if (err < 0)
			goto st_accel_set_dataready_irq_error;
	}

	/* Enable/Disable the interrupt generator 1. */
	if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) {
		err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->drdy_irq.ig1.en_addr,
				sdata->sensor_settings->drdy_irq.ig1.en_mask,
				(int)enable);
		if (err < 0)
			goto st_accel_set_dataready_irq_error;
	}

	if (sdata->drdy_int_pin == 1)
		drdy_mask = sdata->sensor_settings->drdy_irq.mask_int1;
	else
		drdy_mask = sdata->sensor_settings->drdy_irq.mask_int2;

	/* Enable/Disable the interrupt generator for data ready. */
	err = st_sensors_write_data_with_mask(indio_dev,
					sdata->sensor_settings->drdy_irq.addr,
					drdy_mask, (int)enable);

st_accel_set_dataready_irq_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_set_dataready_irq);

int st_sensors_set_wakeup_irq(struct iio_dev *indio_dev, bool enable)
{
	int err;
	u8 data;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	/* Map AOI1 interrupt on INT1 line */
	err = st_sensors_write_data_with_mask(indio_dev,
						sdata->sensor_settings->aoi1_irq.addr,
						sdata->sensor_settings->aoi1_irq.mask,
						(int)enable);
	if (err < 0)
		goto st_set_wakeup_irq_error;

	/* Enable/Disable latched interrupt for INT1 */
	err = st_sensors_write_data_with_mask(indio_dev,
						sdata->sensor_settings->lir1.addr,
						sdata->sensor_settings->lir1.mask,
						(int)enable);
	if (err < 0)
		goto st_set_wakeup_irq_error;

	/* Clear any pending latched interrupts */
	err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
				   sdata->sensor_settings->int1_src.addr, &data);
	if (err < 0)
		goto st_set_wakeup_irq_error;

	if (enable) {
		/* Set HP Filter enable on AOI function on INT1 */
		err = st_sensors_write_data_with_mask(indio_dev,
			       sdata->sensor_settings->hp_filter_mode.addr,
			       sdata->sensor_settings->hp_filter_mode.hpis1_mask,
			       true);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/* Set HP Filter enable on sensor_settings data */
		err = st_sensors_write_data_with_mask(indio_dev,
			       sdata->sensor_settings->hp_filter_mode.addr,
			       sdata->sensor_settings->hp_filter_mode.fds_mask,
			       true);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/* Set threshold */
		err = st_sensors_set_ths(indio_dev,
					 (unsigned int)sdata->int_thres);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/* Set duration */
		err = st_sensors_set_dur(indio_dev,
					 (unsigned int)sdata->int_dur);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/*
		 * Force dummy read of HP_FILTER_ENABLE. This forces the HP
		 * Filter to current acceleration value, i.e. sets the reference
		 * acceleration value
		 */
		err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
					   sdata->sensor_settings->ref_data.addr, &data);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/* Set "OR" combination INT1 irq generation for XH, YH and ZH */
		err = st_sensors_write_data_with_mask(indio_dev,
				sdata->sensor_settings->int1_cfg.addr,
				sdata->sensor_settings->int1_cfg.mask,
				(int)((sdata->ev_l_enable_state[0] <<
					sdata->sensor_settings->int1_cfg.l_shift[0]) |
				(sdata->ev_h_enable_state[0] <<
					sdata->sensor_settings->int1_cfg.h_shift[0]) |
				(sdata->ev_l_enable_state[1] <<
					sdata->sensor_settings->int1_cfg.l_shift[1]) |
				(sdata->ev_h_enable_state[1] <<
					sdata->sensor_settings->int1_cfg.h_shift[1]) |
				(sdata->ev_l_enable_state[2] <<
					sdata->sensor_settings->int1_cfg.l_shift[2]) |
				(sdata->ev_h_enable_state[2] <<
					sdata->sensor_settings->int1_cfg.h_shift[2])));
		if (err < 0)
			goto st_set_wakeup_irq_error;
	} else {
		/* Disable {XYZ}{HL}IE INT1 interrupt generation bits */
		err = st_sensors_write_data_with_mask(indio_dev,
					sdata->sensor_settings->int1_cfg.addr,
					sdata->sensor_settings->int1_cfg.mask,
					(int)sdata->sensor_settings->int1_cfg.value_off);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/* Clear HP Filter enable on sensor data */
		err = st_sensors_write_data_with_mask(indio_dev,
			       sdata->sensor_settings->hp_filter_mode.addr,
			       sdata->sensor_settings->hp_filter_mode.fds_mask,
			       false);
		if (err < 0)
			goto st_set_wakeup_irq_error;

		/* Clear HP Filter enable on AOI function on INT1 */
		err = st_sensors_write_data_with_mask(indio_dev,
			       sdata->sensor_settings->hp_filter_mode.addr,
			       sdata->sensor_settings->hp_filter_mode.hpis1_mask,
			       false);
		if (err < 0)
			goto st_set_wakeup_irq_error;
	}

	return 0;

st_set_wakeup_irq_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_set_wakeup_irq);

int st_sensors_reset_latched_int(struct iio_dev *indio_dev)
{
	int err;
	u8 data;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
				   sdata->sensor_settings->int1_src.addr, &data);
	if (err < 0)
		goto st_sensors_error;

	return 0;

st_sensors_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_reset_latched_int);

int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale)
{
	int err = -EINVAL, i;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
		if ((sdata->sensor_settings->fs.fs_avl[i].gain == scale) &&
				(sdata->sensor_settings->fs.fs_avl[i].gain != 0)) {
			err = 0;
			break;
		}
	}
	if (err < 0)
		goto st_sensors_match_scale_error;

	err = st_sensors_set_fullscale(indio_dev,
				sdata->sensor_settings->fs.fs_avl[i].num);

st_sensors_match_scale_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain);

static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
				struct iio_chan_spec const *ch, int *data)
{
	int err;
	u8 *outdata;
	struct st_sensor_data *sdata = iio_priv(indio_dev);
	unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;

	outdata = kmalloc(byte_for_channel, GFP_KERNEL);
	if (!outdata)
		return -ENOMEM;

	err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
				ch->address, byte_for_channel,
				outdata, sdata->multiread_bit);
	if (err < 0)
		goto st_sensors_free_memory;

	if (byte_for_channel == 2)
		*data = (s16)get_unaligned_le16(outdata);
	else if (byte_for_channel == 3)
		*data = (s32)st_sensors_get_unaligned_le24(outdata);

st_sensors_free_memory:
	kfree(outdata);

	return err;
}

int st_sensors_read_info_raw(struct iio_dev *indio_dev,
				struct iio_chan_spec const *ch, int *val)
{
	int err;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	mutex_lock(&indio_dev->mlock);
	if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
		err = -EBUSY;
		goto out;
	} else {
		err = st_sensors_set_enable(indio_dev, true);
		if (err < 0)
			goto out;

		msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr);
		err = st_sensors_read_axis_data(indio_dev, ch, val);
		if (err < 0)
			goto out;

		*val = *val >> ch->scan_type.shift;

		err = st_sensors_set_enable(indio_dev, false);
	}
out:
	mutex_unlock(&indio_dev->mlock);

	return err;
}
EXPORT_SYMBOL(st_sensors_read_info_raw);

int st_sensors_check_device_support(struct iio_dev *indio_dev,
			int num_sensors_list,
			const struct st_sensor_settings *sensor_settings)
{
	u8 wai;
	int i, n, err;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
					ST_SENSORS_DEFAULT_WAI_ADDRESS, &wai);
	if (err < 0) {
		dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
		goto read_wai_error;
	}

	for (i = 0; i < num_sensors_list; i++) {
		if (sensor_settings[i].wai == wai)
			break;
	}
	if (i == num_sensors_list)
		goto device_not_supported;

	for (n = 0; n < ARRAY_SIZE(sensor_settings[i].sensors_supported); n++) {
		if (strcmp(indio_dev->name,
				&sensor_settings[i].sensors_supported[n][0]) == 0)
			break;
	}
	if (n == ARRAY_SIZE(sensor_settings[i].sensors_supported)) {
		dev_err(&indio_dev->dev, "device name and WhoAmI mismatch.\n");
		goto sensor_name_mismatch;
	}

	sdata->sensor_settings =
			(struct st_sensor_settings *)&sensor_settings[i];

	return i;

device_not_supported:
	dev_err(&indio_dev->dev, "device not supported: WhoAmI (0x%x).\n", wai);
sensor_name_mismatch:
	err = -ENODEV;
read_wai_error:
	return err;
}
EXPORT_SYMBOL(st_sensors_check_device_support);

ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct st_sensor_data *adata = iio_priv(dev_get_drvdata(dev));

	return sprintf(buf, "%d\n", adata->odr);
}
EXPORT_SYMBOL(st_sensors_sysfs_get_sampling_frequency);

ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
				struct device_attribute *attr, const char *buf, size_t size)
{
	int err;
	unsigned int odr;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);

	err = kstrtoint(buf, 10, &odr);
	if (err < 0)
		goto conversion_error;

	mutex_lock(&indio_dev->mlock);
	err = st_sensors_set_odr(indio_dev, odr);
	mutex_unlock(&indio_dev->mlock);

conversion_error:
	return err < 0 ? err : size;
}
EXPORT_SYMBOL(st_sensors_sysfs_set_sampling_frequency);

ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	int i, len = 0;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	mutex_lock(&indio_dev->mlock);
	for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
		if (sdata->sensor_settings->odr.odr_avl[i].hz == 0)
			break;

		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
				sdata->sensor_settings->odr.odr_avl[i].hz);
	}
	mutex_unlock(&indio_dev->mlock);
	buf[len - 1] = '\n';

	return len;
}
EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail);

ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	int i, len = 0;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	mutex_lock(&indio_dev->mlock);
	for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
		if (sdata->sensor_settings->fs.fs_avl[i].num == 0)
			break;

		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
				sdata->sensor_settings->fs.fs_avl[i].gain);
	}
	mutex_unlock(&indio_dev->mlock);
	buf[len - 1] = '\n';

	return len;
}
EXPORT_SYMBOL(st_sensors_sysfs_scale_avail);

MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics ST-sensors core");
MODULE_LICENSE("GPL v2");
