2929#define MMA8452_INT_SRC 0x0c
3030#define MMA8452_WHO_AM_I 0x0d
3131#define MMA8452_DATA_CFG 0x0e
32+ #define MMA8452_HP_FILTER_CUTOFF 0x0f
33+ #define MMA8452_HP_FILTER_CUTOFF_SEL_MASK (BIT(0) | BIT(1))
3234#define MMA8452_TRANSIENT_CFG 0x1d
3335#define MMA8452_TRANSIENT_CFG_ELE BIT(4)
3436#define MMA8452_TRANSIENT_CFG_CHAN (chan ) BIT(chan + 1)
37+ #define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0)
3538#define MMA8452_TRANSIENT_SRC 0x1e
3639#define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1)
3740#define MMA8452_TRANSIENT_SRC_YTRANSE BIT(3)
6164#define MMA8452_DATA_CFG_FS_2G 0
6265#define MMA8452_DATA_CFG_FS_4G 1
6366#define MMA8452_DATA_CFG_FS_8G 2
67+ #define MMA8452_DATA_CFG_HPF_MASK BIT(4)
6468
6569#define MMA8452_INT_TRANS BIT(5)
6670
@@ -158,6 +162,18 @@ static const int mma8452_transient_time_step_us[8] = {
158162 20000
159163};
160164
165+ /* Datasheet table 18 (normal mode) */
166+ static const int mma8452_hp_filter_cutoff [8 ][4 ][2 ] = {
167+ { {16 , 0 }, {8 , 0 }, {4 , 0 }, {2 , 0 } }, /* 800 Hz sample */
168+ { {16 , 0 }, {8 , 0 }, {4 , 0 }, {2 , 0 } }, /* 400 Hz sample */
169+ { {8 , 0 }, {4 , 0 }, {2 , 0 }, {1 , 0 } }, /* 200 Hz sample */
170+ { {4 , 0 }, {2 , 0 }, {1 , 0 }, {0 , 500000 } }, /* 100 Hz sample */
171+ { {2 , 0 }, {1 , 0 }, {0 , 500000 }, {0 , 250000 } }, /* 50 Hz sample */
172+ { {2 , 0 }, {1 , 0 }, {0 , 500000 }, {0 , 250000 } }, /* 12.5 Hz sample */
173+ { {2 , 0 }, {1 , 0 }, {0 , 500000 }, {0 , 250000 } }, /* 6.25 Hz sample */
174+ { {2 , 0 }, {1 , 0 }, {0 , 500000 }, {0 , 250000 } } /* 1.56 Hz sample */
175+ };
176+
161177static ssize_t mma8452_show_samp_freq_avail (struct device * dev ,
162178 struct device_attribute * attr , char * buf )
163179{
@@ -172,9 +188,23 @@ static ssize_t mma8452_show_scale_avail(struct device *dev,
172188 ARRAY_SIZE (mma8452_scales ));
173189}
174190
191+ static ssize_t mma8452_show_hp_cutoff_avail (struct device * dev ,
192+ struct device_attribute * attr ,
193+ char * buf )
194+ {
195+ struct iio_dev * indio_dev = dev_to_iio_dev (dev );
196+ struct mma8452_data * data = iio_priv (indio_dev );
197+ int i = mma8452_get_odr_index (data );
198+
199+ return mma8452_show_int_plus_micros (buf , mma8452_hp_filter_cutoff [i ],
200+ ARRAY_SIZE (mma8452_hp_filter_cutoff [0 ]));
201+ }
202+
175203static IIO_DEV_ATTR_SAMP_FREQ_AVAIL (mma8452_show_samp_freq_avail );
176204static IIO_DEVICE_ATTR (in_accel_scale_available , S_IRUGO ,
177205 mma8452_show_scale_avail , NULL, 0 ) ;
206+ static IIO_DEVICE_ATTR (in_accel_filter_high_pass_3db_frequency_available ,
207+ S_IRUGO , mma8452_show_hp_cutoff_avail , NULL, 0 ) ;
178208
179209static int mma8452_get_samp_freq_index (struct mma8452_data * data ,
180210 int val , int val2 )
@@ -190,6 +220,31 @@ static int mma8452_get_scale_index(struct mma8452_data *data,
190220 ARRAY_SIZE (mma8452_scales ), val , val2 );
191221}
192222
223+ static int mma8452_get_hp_filter_index (struct mma8452_data * data ,
224+ int val , int val2 )
225+ {
226+ int i = mma8452_get_odr_index (data );
227+
228+ return mma8452_get_int_plus_micros_index (mma8452_hp_filter_cutoff [i ],
229+ ARRAY_SIZE (mma8452_scales [0 ]), val , val2 );
230+ }
231+
232+ static int mma8452_read_hp_filter (struct mma8452_data * data , int * hz , int * uHz )
233+ {
234+ int i , ret ;
235+
236+ ret = i2c_smbus_read_byte_data (data -> client , MMA8452_HP_FILTER_CUTOFF );
237+ if (ret < 0 )
238+ return ret ;
239+
240+ i = mma8452_get_odr_index (data );
241+ ret &= MMA8452_HP_FILTER_CUTOFF_SEL_MASK ;
242+ * hz = mma8452_hp_filter_cutoff [i ][ret ][0 ];
243+ * uHz = mma8452_hp_filter_cutoff [i ][ret ][1 ];
244+
245+ return 0 ;
246+ }
247+
193248static int mma8452_read_raw (struct iio_dev * indio_dev ,
194249 struct iio_chan_spec const * chan ,
195250 int * val , int * val2 , long mask )
@@ -228,6 +283,16 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
228283 return ret ;
229284 * val = sign_extend32 (ret , 7 );
230285 return IIO_VAL_INT ;
286+ case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY :
287+ if (data -> data_cfg & MMA8452_DATA_CFG_HPF_MASK ) {
288+ ret = mma8452_read_hp_filter (data , val , val2 );
289+ if (ret < 0 )
290+ return ret ;
291+ } else {
292+ * val = 0 ;
293+ * val2 = 0 ;
294+ }
295+ return IIO_VAL_INT_PLUS_MICRO ;
231296 }
232297 return - EINVAL ;
233298}
@@ -269,12 +334,31 @@ static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
269334 return ret ;
270335}
271336
337+ static int mma8452_set_hp_filter_frequency (struct mma8452_data * data ,
338+ int val , int val2 )
339+ {
340+ int i , reg ;
341+
342+ i = mma8452_get_hp_filter_index (data , val , val2 );
343+ if (i < 0 )
344+ return - EINVAL ;
345+
346+ reg = i2c_smbus_read_byte_data (data -> client ,
347+ MMA8452_HP_FILTER_CUTOFF );
348+ if (reg < 0 )
349+ return reg ;
350+ reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK ;
351+ reg |= i ;
352+
353+ return mma8452_change_config (data , MMA8452_HP_FILTER_CUTOFF , reg );
354+ }
355+
272356static int mma8452_write_raw (struct iio_dev * indio_dev ,
273357 struct iio_chan_spec const * chan ,
274358 int val , int val2 , long mask )
275359{
276360 struct mma8452_data * data = iio_priv (indio_dev );
277- int i ;
361+ int i , ret ;
278362
279363 if (iio_buffer_enabled (indio_dev ))
280364 return - EBUSY ;
@@ -302,6 +386,19 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
302386 return - EINVAL ;
303387 return mma8452_change_config (data , MMA8452_OFF_X +
304388 chan -> scan_index , val );
389+
390+ case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY :
391+ if (val == 0 && val2 == 0 ) {
392+ data -> data_cfg &= ~MMA8452_DATA_CFG_HPF_MASK ;
393+ } else {
394+ data -> data_cfg |= MMA8452_DATA_CFG_HPF_MASK ;
395+ ret = mma8452_set_hp_filter_frequency (data , val , val2 );
396+ if (ret < 0 )
397+ return ret ;
398+ }
399+ return mma8452_change_config (data , MMA8452_DATA_CFG ,
400+ data -> data_cfg );
401+
305402 default :
306403 return - EINVAL ;
307404 }
@@ -339,6 +436,22 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
339436 * val2 = us % USEC_PER_SEC ;
340437 return IIO_VAL_INT_PLUS_MICRO ;
341438
439+ case IIO_EV_INFO_HIGH_PASS_FILTER_3DB :
440+ ret = i2c_smbus_read_byte_data (data -> client ,
441+ MMA8452_TRANSIENT_CFG );
442+ if (ret < 0 )
443+ return ret ;
444+
445+ if (ret & MMA8452_TRANSIENT_CFG_HPF_BYP ) {
446+ * val = 0 ;
447+ * val2 = 0 ;
448+ } else {
449+ ret = mma8452_read_hp_filter (data , val , val2 );
450+ if (ret < 0 )
451+ return ret ;
452+ }
453+ return IIO_VAL_INT_PLUS_MICRO ;
454+
342455 default :
343456 return - EINVAL ;
344457 }
@@ -352,7 +465,7 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
352465 int val , int val2 )
353466{
354467 struct mma8452_data * data = iio_priv (indio_dev );
355- int steps ;
468+ int ret , reg , steps ;
356469
357470 switch (info ) {
358471 case IIO_EV_INFO_VALUE :
@@ -369,6 +482,22 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
369482
370483 return mma8452_change_config (data , MMA8452_TRANSIENT_COUNT ,
371484 steps );
485+ case IIO_EV_INFO_HIGH_PASS_FILTER_3DB :
486+ reg = i2c_smbus_read_byte_data (data -> client ,
487+ MMA8452_TRANSIENT_CFG );
488+ if (reg < 0 )
489+ return reg ;
490+
491+ if (val == 0 && val2 == 0 ) {
492+ reg |= MMA8452_TRANSIENT_CFG_HPF_BYP ;
493+ } else {
494+ reg &= ~MMA8452_TRANSIENT_CFG_HPF_BYP ;
495+ ret = mma8452_set_hp_filter_frequency (data , val , val2 );
496+ if (ret < 0 )
497+ return ret ;
498+ }
499+ return mma8452_change_config (data , MMA8452_TRANSIENT_CFG , reg );
500+
372501 default :
373502 return - EINVAL ;
374503 }
@@ -510,7 +639,8 @@ static const struct iio_event_spec mma8452_transient_event[] = {
510639 .dir = IIO_EV_DIR_RISING ,
511640 .mask_separate = BIT (IIO_EV_INFO_ENABLE ),
512641 .mask_shared_by_type = BIT (IIO_EV_INFO_VALUE ) |
513- BIT (IIO_EV_INFO_PERIOD )
642+ BIT (IIO_EV_INFO_PERIOD ) |
643+ BIT (IIO_EV_INFO_HIGH_PASS_FILTER_3DB )
514644 },
515645};
516646
@@ -537,7 +667,8 @@ static struct attribute_group mma8452_event_attribute_group = {
537667 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
538668 BIT(IIO_CHAN_INFO_CALIBBIAS), \
539669 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
540- BIT(IIO_CHAN_INFO_SCALE), \
670+ BIT(IIO_CHAN_INFO_SCALE) | \
671+ BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
541672 .scan_index = idx, \
542673 .scan_type = { \
543674 .sign = 's', \
@@ -560,6 +691,7 @@ static const struct iio_chan_spec mma8452_channels[] = {
560691static struct attribute * mma8452_attributes [] = {
561692 & iio_dev_attr_sampling_frequency_available .dev_attr .attr ,
562693 & iio_dev_attr_in_accel_scale_available .dev_attr .attr ,
694+ & iio_dev_attr_in_accel_filter_high_pass_3db_frequency_available .dev_attr .attr ,
563695 NULL
564696};
565697
0 commit comments