31
31
#define BMI270_INT_STATUS_1_REG 0x1d
32
32
#define BMI270_INT_STATUS_1_ACC_GYR_DRDY_MSK GENMASK(7, 6)
33
33
34
+ #define BMI270_SC_OUT_0_REG 0x1e
35
+
34
36
#define BMI270_INTERNAL_STATUS_REG 0x21
35
37
#define BMI270_INTERNAL_STATUS_MSG_MSK GENMASK(3, 0)
36
38
#define BMI270_INTERNAL_STATUS_MSG_INIT_OK 0x01
39
41
40
42
#define BMI270_TEMPERATURE_0_REG 0x22
41
43
44
+ #define BMI270_FEAT_PAGE_REG 0x2f
45
+
42
46
#define BMI270_ACC_CONF_REG 0x40
43
47
#define BMI270_ACC_CONF_ODR_MSK GENMASK(3, 0)
44
48
#define BMI270_ACC_CONF_ODR_100HZ 0x08
90
94
#define BMI270_PWR_CTRL_ACCEL_EN_MSK BIT(2)
91
95
#define BMI270_PWR_CTRL_TEMP_EN_MSK BIT(3)
92
96
97
+ #define BMI270_STEP_SC26_RST_CNT_MSK BIT(10)
98
+ #define BMI270_STEP_SC26_EN_CNT_MSK BIT(12)
99
+
93
100
/* See datasheet section 4.6.14, Temperature Sensor */
94
101
#define BMI270_TEMP_OFFSET 11776
95
102
#define BMI270_TEMP_SCALE 1953125
@@ -111,6 +118,7 @@ struct bmi270_data {
111
118
struct iio_trigger * trig ;
112
119
/* Protect device's private data from concurrent access */
113
120
struct mutex mutex ;
121
+ bool steps_enabled ;
114
122
115
123
/*
116
124
* Where IIO_DMA_MINALIGN may be larger than 8 bytes, align to
@@ -120,6 +128,11 @@ struct bmi270_data {
120
128
__le16 channels [6 ];
121
129
aligned_s64 timestamp ;
122
130
} buffer __aligned (IIO_DMA_MINALIGN );
131
+ /*
132
+ * Variable to access feature registers. It can be accessed concurrently
133
+ * with the 'buffer' variable
134
+ */
135
+ __le16 regval __aligned (IIO_DMA_MINALIGN );
123
136
};
124
137
125
138
enum bmi270_scan {
@@ -282,6 +295,107 @@ static const struct bmi270_odr_item bmi270_odr_table[] = {
282
295
},
283
296
};
284
297
298
+ enum bmi270_feature_reg_id {
299
+ BMI270_SC_26_REG ,
300
+ };
301
+
302
+ struct bmi270_feature_reg {
303
+ u8 page ;
304
+ u8 addr ;
305
+ };
306
+
307
+ static const struct bmi270_feature_reg bmi270_feature_regs [] = {
308
+ [BMI270_SC_26_REG ] = {
309
+ .page = 6 ,
310
+ .addr = 0x32 ,
311
+ },
312
+ };
313
+
314
+ static int bmi270_write_feature_reg (struct bmi270_data * data ,
315
+ enum bmi270_feature_reg_id id ,
316
+ u16 val )
317
+ {
318
+ const struct bmi270_feature_reg * reg = & bmi270_feature_regs [id ];
319
+ int ret ;
320
+
321
+ ret = regmap_write (data -> regmap , BMI270_FEAT_PAGE_REG , reg -> page );
322
+ if (ret )
323
+ return ret ;
324
+
325
+ data -> regval = cpu_to_le16 (val );
326
+ return regmap_bulk_write (data -> regmap , reg -> addr , & data -> regval ,
327
+ sizeof (data -> regval ));
328
+ }
329
+
330
+ static int bmi270_read_feature_reg (struct bmi270_data * data ,
331
+ enum bmi270_feature_reg_id id ,
332
+ u16 * val )
333
+ {
334
+ const struct bmi270_feature_reg * reg = & bmi270_feature_regs [id ];
335
+ int ret ;
336
+
337
+ ret = regmap_write (data -> regmap , BMI270_FEAT_PAGE_REG , reg -> page );
338
+ if (ret )
339
+ return ret ;
340
+
341
+ ret = regmap_bulk_read (data -> regmap , reg -> addr , & data -> regval ,
342
+ sizeof (data -> regval ));
343
+ if (ret )
344
+ return ret ;
345
+
346
+ * val = le16_to_cpu (data -> regval );
347
+ return 0 ;
348
+ }
349
+
350
+ static int bmi270_update_feature_reg (struct bmi270_data * data ,
351
+ enum bmi270_feature_reg_id id ,
352
+ u16 mask , u16 val )
353
+ {
354
+ u16 regval ;
355
+ int ret ;
356
+
357
+ ret = bmi270_read_feature_reg (data , id , & regval );
358
+ if (ret )
359
+ return ret ;
360
+
361
+ regval = (regval & ~mask ) | (val & mask );
362
+
363
+ return bmi270_write_feature_reg (data , id , regval );
364
+ }
365
+
366
+ static int bmi270_enable_steps (struct bmi270_data * data , int val )
367
+ {
368
+ int ret ;
369
+
370
+ guard (mutex )(& data -> mutex );
371
+ if (data -> steps_enabled )
372
+ return 0 ;
373
+
374
+ ret = bmi270_update_feature_reg (data , BMI270_SC_26_REG ,
375
+ BMI270_STEP_SC26_EN_CNT_MSK ,
376
+ FIELD_PREP (BMI270_STEP_SC26_EN_CNT_MSK ,
377
+ val ? 1 : 0 ));
378
+ if (ret )
379
+ return ret ;
380
+
381
+ data -> steps_enabled = true;
382
+ return 0 ;
383
+ }
384
+
385
+ static int bmi270_read_steps (struct bmi270_data * data , int * val )
386
+ {
387
+ __le16 steps_count ;
388
+ int ret ;
389
+
390
+ ret = regmap_bulk_read (data -> regmap , BMI270_SC_OUT_0_REG , & steps_count ,
391
+ sizeof (steps_count ));
392
+ if (ret )
393
+ return ret ;
394
+
395
+ * val = sign_extend32 (le16_to_cpu (steps_count ), 15 );
396
+ return IIO_VAL_INT ;
397
+ }
398
+
285
399
static int bmi270_set_scale (struct bmi270_data * data , int chan_type , int uscale )
286
400
{
287
401
int i ;
@@ -551,6 +665,8 @@ static int bmi270_read_raw(struct iio_dev *indio_dev,
551
665
struct bmi270_data * data = iio_priv (indio_dev );
552
666
553
667
switch (mask ) {
668
+ case IIO_CHAN_INFO_PROCESSED :
669
+ return bmi270_read_steps (data , val );
554
670
case IIO_CHAN_INFO_RAW :
555
671
if (!iio_device_claim_direct (indio_dev ))
556
672
return - EBUSY ;
@@ -571,6 +687,9 @@ static int bmi270_read_raw(struct iio_dev *indio_dev,
571
687
case IIO_CHAN_INFO_SAMP_FREQ :
572
688
ret = bmi270_get_odr (data , chan -> type , val , val2 );
573
689
return ret ? ret : IIO_VAL_INT_PLUS_MICRO ;
690
+ case IIO_CHAN_INFO_ENABLE :
691
+ * val = data -> steps_enabled ? 1 : 0 ;
692
+ return IIO_VAL_INT ;
574
693
default :
575
694
return - EINVAL ;
576
695
}
@@ -596,6 +715,19 @@ static int bmi270_write_raw(struct iio_dev *indio_dev,
596
715
ret = bmi270_set_odr (data , chan -> type , val , val2 );
597
716
iio_device_release_direct (indio_dev );
598
717
return ret ;
718
+ case IIO_CHAN_INFO_ENABLE :
719
+ return bmi270_enable_steps (data , val );
720
+ case IIO_CHAN_INFO_PROCESSED : {
721
+ if (val || !data -> steps_enabled )
722
+ return - EINVAL ;
723
+
724
+ guard (mutex )(& data -> mutex );
725
+ /* Clear step counter value */
726
+ return bmi270_update_feature_reg (data , BMI270_SC_26_REG ,
727
+ BMI270_STEP_SC26_RST_CNT_MSK ,
728
+ FIELD_PREP (BMI270_STEP_SC26_RST_CNT_MSK ,
729
+ 1 ));
730
+ }
599
731
default :
600
732
return - EINVAL ;
601
733
}
@@ -698,6 +830,12 @@ static const struct iio_chan_spec bmi270_channels[] = {
698
830
BIT (IIO_CHAN_INFO_OFFSET ),
699
831
.scan_index = -1 , /* No buffer support */
700
832
},
833
+ {
834
+ .type = IIO_STEPS ,
835
+ .info_mask_separate = BIT (IIO_CHAN_INFO_ENABLE ) |
836
+ BIT (IIO_CHAN_INFO_PROCESSED ),
837
+ .scan_index = -1 , /* No buffer support */
838
+ },
701
839
IIO_CHAN_SOFT_TIMESTAMP (BMI270_SCAN_TIMESTAMP ),
702
840
};
703
841
0 commit comments