Exemplo n.º 1
0
static int mma8452_write_raw(struct iio_dev *indio_dev,
                             struct iio_chan_spec const *chan,
                             int val, int val2, long mask)
{
    struct mma8452_data *data = iio_priv(indio_dev);
    int i, ret;

    if (iio_buffer_enabled(indio_dev))
        return -EBUSY;

    switch (mask) {
    case IIO_CHAN_INFO_SAMP_FREQ:
        i = mma8452_get_samp_freq_index(data, val, val2);
        if (i < 0)
            return i;

        data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
        data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;

        return mma8452_change_config(data, MMA8452_CTRL_REG1,
                                     data->ctrl_reg1);
    case IIO_CHAN_INFO_SCALE:
        i = mma8452_get_scale_index(data, val, val2);
        if (i < 0)
            return i;

        data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
        data->data_cfg |= i;

        return mma8452_change_config(data, MMA8452_DATA_CFG,
                                     data->data_cfg);
    case IIO_CHAN_INFO_CALIBBIAS:
        if (val < -128 || val > 127)
            return -EINVAL;

        return mma8452_change_config(data,
                                     MMA8452_OFF_X + chan->scan_index,
                                     val);

    case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
        if (val == 0 && val2 == 0) {
            data->data_cfg &= ~MMA8452_DATA_CFG_HPF_MASK;
        } else {
            data->data_cfg |= MMA8452_DATA_CFG_HPF_MASK;
            ret = mma8452_set_hp_filter_frequency(data, val, val2);
            if (ret < 0)
                return ret;
        }

        return mma8452_change_config(data, MMA8452_DATA_CFG,
                                     data->data_cfg);

    default:
        return -EINVAL;
    }
}
Exemplo n.º 2
0
static int mma8452_write_thresh(struct iio_dev *indio_dev,
                                const struct iio_chan_spec *chan,
                                enum iio_event_type type,
                                enum iio_event_direction dir,
                                enum iio_event_info info,
                                int val, int val2)
{
    struct mma8452_data *data = iio_priv(indio_dev);
    int ret, reg, steps;

    switch (info) {
    case IIO_EV_INFO_VALUE:
        if (val < 0 || val > MMA8452_TRANSIENT_THS_MASK)
            return -EINVAL;

        return mma8452_change_config(data, data->chip_info->ev_ths,
                                     val);

    case IIO_EV_INFO_PERIOD:
        steps = (val * USEC_PER_SEC + val2) /
                mma8452_transient_time_step_us[
                    mma8452_get_odr_index(data)];

        if (steps < 0 || steps > 0xff)
            return -EINVAL;

        return mma8452_change_config(data, data->chip_info->ev_count,
                                     steps);

    case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
        reg = i2c_smbus_read_byte_data(data->client,
                                       MMA8452_TRANSIENT_CFG);
        if (reg < 0)
            return reg;

        if (val == 0 && val2 == 0) {
            reg |= MMA8452_TRANSIENT_CFG_HPF_BYP;
        } else {
            reg &= ~MMA8452_TRANSIENT_CFG_HPF_BYP;
            ret = mma8452_set_hp_filter_frequency(data, val, val2);
            if (ret < 0)
                return ret;
        }

        return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);

    default:
        return -EINVAL;
    }
}
Exemplo n.º 3
0
static int mma8452_set_freefall_mode(struct mma8452_data *data, bool state)
{
	int val;
	const struct mma_chip_info *chip = data->chip_info;

	if ((state && mma8452_freefall_mode_enabled(data)) ||
	    (!state && !(mma8452_freefall_mode_enabled(data))))
		return 0;

	val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg);
	if (val < 0)
		return val;

	if (state) {
		val |= BIT(idx_x + chip->ev_cfg_chan_shift);
		val |= BIT(idx_y + chip->ev_cfg_chan_shift);
		val |= BIT(idx_z + chip->ev_cfg_chan_shift);
		val &= ~MMA8452_FF_MT_CFG_OAE;
	} else {
		val &= ~BIT(idx_x + chip->ev_cfg_chan_shift);
		val &= ~BIT(idx_y + chip->ev_cfg_chan_shift);
		val &= ~BIT(idx_z + chip->ev_cfg_chan_shift);
		val |= MMA8452_FF_MT_CFG_OAE;
	}

	val = mma8452_change_config(data, chip->ev_cfg, val);
	if (val)
		return val;

	return 0;
}
Exemplo n.º 4
0
static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig,
        bool state)
{
    struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
    struct mma8452_data *data = iio_priv(indio_dev);
    int reg;

    reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG4);
    if (reg < 0)
        return reg;

    if (state)
        reg |= MMA8452_INT_DRDY;
    else
        reg &= ~MMA8452_INT_DRDY;

    return mma8452_change_config(data, MMA8452_CTRL_REG4, reg);
}
Exemplo n.º 5
0
static int mma8452_write_event_config(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan,
				      enum iio_event_type type,
				      enum iio_event_direction dir,
				      int state)
{
	struct mma8452_data *data = iio_priv(indio_dev);
	const struct mma_chip_info *chip = data->chip_info;
	int val, ret;

	ret = mma8452_set_runtime_pm_state(data->client, state);
	if (ret)
		return ret;

	switch (dir) {
	case IIO_EV_DIR_FALLING:
		return mma8452_set_freefall_mode(data, state);
	case IIO_EV_DIR_RISING:
		val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg);
		if (val < 0)
			return val;

		if (state) {
			if (mma8452_freefall_mode_enabled(data)) {
				val &= ~BIT(idx_x + chip->ev_cfg_chan_shift);
				val &= ~BIT(idx_y + chip->ev_cfg_chan_shift);
				val &= ~BIT(idx_z + chip->ev_cfg_chan_shift);
				val |= MMA8452_FF_MT_CFG_OAE;
			}
			val |= BIT(chan->scan_index + chip->ev_cfg_chan_shift);
		} else {
			if (mma8452_freefall_mode_enabled(data))
				return 0;

			val &= ~BIT(chan->scan_index + chip->ev_cfg_chan_shift);
		}

		val |= chip->ev_cfg_ele;

		return mma8452_change_config(data, chip->ev_cfg, val);
	default:
		return -EINVAL;
	}
}
Exemplo n.º 6
0
static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
        int val, int val2)
{
    int i, reg;

    i = mma8452_get_hp_filter_index(data, val, val2);
    if (i < 0)
        return i;

    reg = i2c_smbus_read_byte_data(data->client,
                                   MMA8452_HP_FILTER_CUTOFF);
    if (reg < 0)
        return reg;

    reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
    reg |= i;

    return mma8452_change_config(data, MMA8452_HP_FILTER_CUTOFF, reg);
}
Exemplo n.º 7
0
static int mma8452_reg_access_dbg(struct iio_dev *indio_dev,
                                  unsigned reg, unsigned writeval,
                                  unsigned *readval)
{
    int ret;
    struct mma8452_data *data = iio_priv(indio_dev);

    if (reg > MMA8452_MAX_REG)
        return -EINVAL;

    if (!readval)
        return mma8452_change_config(data, reg, writeval);

    ret = i2c_smbus_read_byte_data(data->client, reg);
    if (ret < 0)
        return ret;

    *readval = ret;

    return 0;
}
Exemplo n.º 8
0
static int mma8452_write_event_config(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan,
				      enum iio_event_type type,
				      enum iio_event_direction dir,
				      int state)
{
	struct mma8452_data *data = iio_priv(indio_dev);
	int val;

	val = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_CFG);
	if (val < 0)
		return val;

	if (state)
		val |= MMA8452_TRANSIENT_CFG_CHAN(chan->scan_index);
	else
		val &= ~MMA8452_TRANSIENT_CFG_CHAN(chan->scan_index);

	val |= MMA8452_TRANSIENT_CFG_ELE;

	return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, val);
}
Exemplo n.º 9
0
static int mma8452_write_event_config(struct iio_dev *indio_dev,
                                      const struct iio_chan_spec *chan,
                                      enum iio_event_type type,
                                      enum iio_event_direction dir,
                                      int state)
{
    struct mma8452_data *data = iio_priv(indio_dev);
    const struct mma_chip_info *chip = data->chip_info;
    int val;

    val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg);
    if (val < 0)
        return val;

    if (state)
        val |= BIT(chan->scan_index + chip->ev_cfg_chan_shift);
    else
        val &= ~BIT(chan->scan_index + chip->ev_cfg_chan_shift);

    val |= chip->ev_cfg_ele;
    val |= MMA8452_FF_MT_CFG_OAE;

    return mma8452_change_config(data, chip->ev_cfg, val);
}