#define SCA3000_MEAS_MODE_NORMAL               0x00
 #define SCA3000_MEAS_MODE_OP_1                 0x01
 #define SCA3000_MEAS_MODE_OP_2                 0x02
+#define SCA3000_MODE_MASK                      0x03
 
 /*
  * In motion detection mode the accelerations are band pass filtered
                .num_event_specs = 1,                           \
        }
 
+static const struct iio_event_spec sca3000_freefall_event_spec = {
+       .type = IIO_EV_TYPE_MAG,
+       .dir = IIO_EV_DIR_FALLING,
+       .mask_separate = BIT(IIO_EV_INFO_ENABLE) |
+               BIT(IIO_EV_INFO_PERIOD),
+};
+
 static const struct iio_chan_spec sca3000_channels[] = {
        SCA3000_CHAN(0, IIO_MOD_X),
        SCA3000_CHAN(1, IIO_MOD_Y),
        SCA3000_CHAN(2, IIO_MOD_Z),
+       {
+               .type = IIO_ACCEL,
+               .modified = 1,
+               .channel2 = IIO_MOD_X_AND_Y_AND_Z,
+               .scan_index = -1, /* Fake channel */
+               .event_spec = &sca3000_freefall_event_spec,
+               .num_event_specs = 1,
+       },
 };
 
 static const struct iio_chan_spec sca3000_channels_with_temp[] = {
                /* No buffer support */
                .scan_index = -1,
        },
+       {
+               .type = IIO_ACCEL,
+               .modified = 1,
+               .channel2 = IIO_MOD_X_AND_Y_AND_Z,
+               .scan_index = -1, /* Fake channel */
+               .event_spec = &sca3000_freefall_event_spec,
+               .num_event_specs = 1,
+       },
 };
 
 static u8 sca3000_addresses[3][3] = {
 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sca3000_read_av_freq);
 
 /**
- * sca3000_read_thresh() - query of a threshold
+ * sca3000_read_event_value() - query of a threshold or period
  **/
-static int sca3000_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)
+static int sca3000_read_event_value(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)
 {
        int ret, i;
        struct sca3000_state *st = iio_priv(indio_dev);
        int num = chan->channel2;
+       switch (info) {
+       case IIO_EV_INFO_VALUE:
+               mutex_lock(&st->lock);
+               ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
+               mutex_unlock(&st->lock);
+               if (ret < 0)
+                       return ret;
+               *val = 0;
+               if (num == 1)
+                       for_each_set_bit(i, (unsigned long *)&ret,
+                                        ARRAY_SIZE(st->info->mot_det_mult_y))
+                               *val += st->info->mot_det_mult_y[i];
+               else
+                       for_each_set_bit(i, (unsigned long *)&ret,
+                                        ARRAY_SIZE(st->info->mot_det_mult_xz))
+                               *val += st->info->mot_det_mult_xz[i];
 
-       mutex_lock(&st->lock);
-       ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
-       mutex_unlock(&st->lock);
-       if (ret < 0)
-               return ret;
-       *val = 0;
-       if (num == 1)
-               for_each_set_bit(i, (unsigned long *)&ret,
-                                ARRAY_SIZE(st->info->mot_det_mult_y))
-                       *val += st->info->mot_det_mult_y[i];
-       else
-               for_each_set_bit(i, (unsigned long *)&ret,
-                                ARRAY_SIZE(st->info->mot_det_mult_xz))
-                       *val += st->info->mot_det_mult_xz[i];
-
-       return IIO_VAL_INT;
+               return IIO_VAL_INT;
+       case IIO_EV_INFO_PERIOD:
+               *val = 0;
+               *val2 = 226000;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
 }
 
 /**
- * sca3000_write_thresh() control of threshold
+ * sca3000_write_value() control of threshold and period
  **/
-static int sca3000_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)
+static int sca3000_write_event_value(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 sca3000_state *st = iio_priv(indio_dev);
        int num = chan->channel2;
        int i;
        u8 nonlinear = 0;
 
-       if (num == 1) {
+       if (num == IIO_MOD_Y) {
                i = ARRAY_SIZE(st->info->mot_det_mult_y);
                while (i > 0)
                        if (val >= st->info->mot_det_mult_y[--i]) {
 
        /* read current value of mode register */
        mutex_lock(&st->lock);
+
        ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
        if (ret)
                goto error_ret;
 
-       if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET) {
-               ret = 0;
-       } else {
-               ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
-               if (ret < 0)
-                       goto error_ret;
-               /* only supporting logical or's for now */
-               ret = !!(ret & sca3000_addresses[num][2]);
+       switch (chan->channel2) {
+       case IIO_MOD_X_AND_Y_AND_Z:
+               ret = !!(st->rx[0] & SCA3000_FREE_FALL_DETECT);
+               break;
+       case IIO_MOD_X:
+       case IIO_MOD_Y:
+       case IIO_MOD_Z:
+               /*
+                * Motion detection mode cannot run at the same time as
+                * acceleration data being read.
+                */
+               if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET) {
+                       ret = 0;
+               } else {
+                       ret = sca3000_read_ctrl_reg(st,
+                                               SCA3000_REG_CTRL_SEL_MD_CTRL);
+                       if (ret < 0)
+                               goto error_ret;
+                       /* only supporting logical or's for now */
+                       ret = !!(ret & sca3000_addresses[num][2]);
+               }
+               break;
+       default:
+               ret = -EINVAL;
        }
+
 error_ret:
        mutex_unlock(&st->lock);
 
        return ret;
 }
 
-/**
- * sca3000_query_free_fall_mode() is free fall mode enabled
- **/
-static ssize_t sca3000_query_free_fall_mode(struct device *dev,
-                                           struct device_attribute *attr,
-                                           char *buf)
+static int sca3000_freefall_set_state(struct iio_dev *indio_dev, int state)
 {
-       int ret;
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct sca3000_state *st = iio_priv(indio_dev);
-       int val;
-
-       mutex_lock(&st->lock);
-       ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
-       val = st->rx[0];
-       mutex_unlock(&st->lock);
-       if (ret < 0)
-               return ret;
-       return sprintf(buf, "%d\n", !!(val & SCA3000_FREE_FALL_DETECT));
-}
-
-/**
- * sca3000_set_free_fall_mode() simple on off control for free fall int
- *
- * In these chips the free fall detector should send an interrupt if
- * the device falls more than 25cm.  This has not been tested due
- * to fragile wiring.
- **/
-static ssize_t sca3000_set_free_fall_mode(struct device *dev,
-                                         struct device_attribute *attr,
-                                         const char *buf,
-                                         size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct sca3000_state *st = iio_priv(indio_dev);
-       u8 val;
        int ret;
-       u8 protect_mask = SCA3000_FREE_FALL_DETECT;
-
-       mutex_lock(&st->lock);
-       ret = kstrtou8(buf, 10, &val);
-       if (ret)
-               goto error_ret;
 
        /* read current value of mode register */
        ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
        if (ret)
-               goto error_ret;
+               return ret;
 
        /* if off and should be on */
-       if (val && !(st->rx[0] & protect_mask))
-               ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-                                       (st->rx[0] | SCA3000_FREE_FALL_DETECT));
+       if (state && !(st->rx[0] & SCA3000_FREE_FALL_DETECT))
+               return sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+                                        st->rx[0] | SCA3000_FREE_FALL_DETECT);
        /* if on and should be off */
-       else if (!val && (st->rx[0] & protect_mask))
-               ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-                                       (st->rx[0] & ~protect_mask));
-error_ret:
-       mutex_unlock(&st->lock);
-
-       return ret ? ret : len;
+       else if (!state && (st->rx[0] & SCA3000_FREE_FALL_DETECT))
+               return sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+                                        st->rx[0] & ~SCA3000_FREE_FALL_DETECT);
+       else
+               return 0;
 }
 
-/**
- * sca3000_write_event_config() simple on off control for motion detector
- *
- * This is a per axis control, but enabling any will result in the
- * motion detector unit being enabled.
- * N.B. enabling motion detector stops normal data acquisition.
- * There is a complexity in knowing which mode to return to when
- * this mode is disabled.  Currently normal mode is assumed.
- **/
-static int sca3000_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)
+static int sca3000_motion_detect_set_state(struct iio_dev *indio_dev, int axis,
+                                          int state)
 {
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret, ctrlval;
-       u8 protect_mask = 0x03;
-       int num = chan->channel2;
 
-       mutex_lock(&st->lock);
        /*
         * First read the motion detector config to find out if
         * this axis is on
         */
        ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
        if (ret < 0)
-               goto exit_point;
+               return ret;
        ctrlval = ret;
        /* if off and should be on */
-       if (state && !(ctrlval & sca3000_addresses[num][2])) {
+       if (state && !(ctrlval & sca3000_addresses[axis][2])) {
                ret = sca3000_write_ctrl_reg(st,
                                             SCA3000_REG_CTRL_SEL_MD_CTRL,
                                             ctrlval |
-                                            sca3000_addresses[num][2]);
+                                            sca3000_addresses[axis][2]);
                if (ret)
-                       goto exit_point;
+                       return ret;
                st->mo_det_use_count++;
-       } else if (!state && (ctrlval & sca3000_addresses[num][2])) {
+       } else if (!state && (ctrlval & sca3000_addresses[axis][2])) {
                ret = sca3000_write_ctrl_reg(st,
                                             SCA3000_REG_CTRL_SEL_MD_CTRL,
                                             ctrlval &
-                                            ~(sca3000_addresses[num][2]));
+                                            ~(sca3000_addresses[axis][2]));
                if (ret)
-                       goto exit_point;
+                       return ret;
                st->mo_det_use_count--;
        }
 
        /* read current value of mode register */
        ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
        if (ret)
-               goto exit_point;
+               return ret;
        /* if off and should be on */
        if ((st->mo_det_use_count) &&
-           ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
-               ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-                                       (st->rx[0] & ~protect_mask)
+           ((st->rx[0] & SCA3000_MODE_MASK) != SCA3000_MEAS_MODE_MOT_DET))
+               return sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+                                       (st->rx[0] & ~SCA3000_MODE_MASK)
                                        | SCA3000_MEAS_MODE_MOT_DET);
        /* if on and should be off */
        else if (!(st->mo_det_use_count) &&
-                ((st->rx[0] & protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
-               ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-                                       (st->rx[0] & ~protect_mask));
-exit_point:
+                ((st->rx[0] & SCA3000_MODE_MASK) == SCA3000_MEAS_MODE_MOT_DET))
+               return sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+                                       st->rx[0] & SCA3000_MODE_MASK);
+       else
+               return 0;
+}
+
+/**
+ * sca3000_write_event_config() simple on off control for motion detector
+ *
+ * This is a per axis control, but enabling any will result in the
+ * motion detector unit being enabled.
+ * N.B. enabling motion detector stops normal data acquisition.
+ * There is a complexity in knowing which mode to return to when
+ * this mode is disabled.  Currently normal mode is assumed.
+ **/
+static int sca3000_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 sca3000_state *st = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&st->lock);
+       switch (chan->channel2) {
+       case IIO_MOD_X_AND_Y_AND_Z:
+               ret = sca3000_freefall_set_state(indio_dev, state);
+               break;
+
+       case IIO_MOD_X:
+       case IIO_MOD_Y:
+       case IIO_MOD_Z:
+               ret = sca3000_motion_detect_set_state(indio_dev, chan->channel2,
+                                                     state);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
        mutex_unlock(&st->lock);
 
        return ret;
 }
 
-/* Free fall detector related event attribute */
-static IIO_DEVICE_ATTR_NAMED(accel_xayaz_mag_falling_en,
-                            in_accel_x & y & z_mag_falling_en,
-                            S_IRUGO | S_IWUSR,
-                            sca3000_query_free_fall_mode,
-                            sca3000_set_free_fall_mode,
-                            0);
-
-static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
-                           in_accel_x & y & z_mag_falling_period,
-                           "0.226");
-
-static struct attribute *sca3000_event_attributes[] = {
-       &iio_dev_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
-       &iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr,
-       NULL,
-};
-
-static struct attribute_group sca3000_event_attribute_group = {
-       .attrs = sca3000_event_attributes,
-       .name = "events",
-};
-
 static int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
        struct iio_buffer *buffer;
        .attrs = &sca3000_attribute_group,
        .read_raw = &sca3000_read_raw,
        .write_raw = &sca3000_write_raw,
-       .event_attrs = &sca3000_event_attribute_group,
-       .read_event_value = &sca3000_read_thresh,
-       .write_event_value = &sca3000_write_thresh,
+       .read_event_value = &sca3000_read_event_value,
+       .write_event_value = &sca3000_write_event_value,
        .read_event_config = &sca3000_read_event_config,
        .write_event_config = &sca3000_write_event_config,
        .driver_module = THIS_MODULE,