Ejemplo n.º 1
0
static int mma8452_read_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);
    __be16 buffer[3];
    int i, ret;

    switch (mask) {
    case IIO_CHAN_INFO_RAW:
        if (iio_buffer_enabled(indio_dev))
            return -EBUSY;

        mutex_lock(&data->lock);
        ret = mma8452_read(data, buffer);
        mutex_unlock(&data->lock);
        if (ret < 0)
            return ret;

        *val = sign_extend32(be16_to_cpu(
                                 buffer[chan->scan_index]) >> chan->scan_type.shift,
                             chan->scan_type.realbits - 1);

        return IIO_VAL_INT;
    case IIO_CHAN_INFO_SCALE:
        i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
        *val = data->chip_info->mma_scales[i][0];
        *val2 = data->chip_info->mma_scales[i][1];

        return IIO_VAL_INT_PLUS_MICRO;
    case IIO_CHAN_INFO_SAMP_FREQ:
        i = mma8452_get_odr_index(data);
        *val = mma8452_samp_freq[i][0];
        *val2 = mma8452_samp_freq[i][1];

        return IIO_VAL_INT_PLUS_MICRO;
    case IIO_CHAN_INFO_CALIBBIAS:
        ret = i2c_smbus_read_byte_data(data->client,
                                       MMA8452_OFF_X + chan->scan_index);
        if (ret < 0)
            return ret;

        *val = sign_extend32(ret, 7);

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

        return IIO_VAL_INT_PLUS_MICRO;
    }

    return -EINVAL;
}
Ejemplo n.º 2
0
static int mma8452_get_hp_filter_index(struct mma8452_data *data,
                                       int val, int val2)
{
    int i = mma8452_get_odr_index(data);

    return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i],
            ARRAY_SIZE(mma8452_hp_filter_cutoff[0]), val, val2);
}
Ejemplo n.º 3
0
static int mma8452_read_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, us;

    switch (info) {
    case IIO_EV_INFO_VALUE:
        ret = i2c_smbus_read_byte_data(data->client,
                                       data->chip_info->ev_ths);
        if (ret < 0)
            return ret;

        *val = ret & data->chip_info->ev_ths_mask;

        return IIO_VAL_INT;

    case IIO_EV_INFO_PERIOD:
        ret = i2c_smbus_read_byte_data(data->client,
                                       data->chip_info->ev_count);
        if (ret < 0)
            return ret;

        us = ret * mma8452_transient_time_step_us[
                 mma8452_get_odr_index(data)];
        *val = us / USEC_PER_SEC;
        *val2 = us % USEC_PER_SEC;

        return IIO_VAL_INT_PLUS_MICRO;

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

        if (ret & MMA8452_TRANSIENT_CFG_HPF_BYP) {
            *val = 0;
            *val2 = 0;
        } else {
            ret = mma8452_read_hp_filter(data, val, val2);
            if (ret < 0)
                return ret;
        }

        return IIO_VAL_INT_PLUS_MICRO;

    default:
        return -EINVAL;
    }
}
Ejemplo n.º 4
0
static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
        struct device_attribute *attr,
        char *buf)
{
    struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    struct mma8452_data *data = iio_priv(indio_dev);
    int i = mma8452_get_odr_index(data);

    return mma8452_show_int_plus_micros(buf, mma8452_hp_filter_cutoff[i],
                                        ARRAY_SIZE(mma8452_hp_filter_cutoff[0]));
}
Ejemplo n.º 5
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;
    }
}
Ejemplo n.º 6
0
static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
{
    int i, ret;

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

    i = mma8452_get_odr_index(data);
    ret &= MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
    *hz = mma8452_hp_filter_cutoff[i][ret][0];
    *uHz = mma8452_hp_filter_cutoff[i][ret][1];

    return 0;
}
Ejemplo n.º 7
0
static int mma8452_runtime_resume(struct device *dev)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
	struct mma8452_data *data = iio_priv(indio_dev);
	int ret, sleep_val;

	ret = mma8452_active(data);
	if (ret < 0)
		return ret;

	ret = mma8452_get_odr_index(data);
	sleep_val = 1000 / mma8452_samp_freq[ret][0];
	if (sleep_val < 20)
		usleep_range(sleep_val * 1000, 20000);
	else
		msleep_interruptible(sleep_val);

	return 0;
}