@@ -118,6 +118,38 @@ static const struct bmi323_hw bmi323_hw[2] = {
118
118
},
119
119
};
120
120
121
+ static const unsigned int bmi323_reg_savestate [] = {
122
+ BMI323_INT_MAP1_REG ,
123
+ BMI323_INT_MAP2_REG ,
124
+ BMI323_IO_INT_CTR_REG ,
125
+ BMI323_IO_INT_CONF_REG ,
126
+ BMI323_ACC_CONF_REG ,
127
+ BMI323_GYRO_CONF_REG ,
128
+ BMI323_FEAT_IO0_REG ,
129
+ BMI323_FIFO_WTRMRK_REG ,
130
+ BMI323_FIFO_CONF_REG
131
+ };
132
+
133
+ static const unsigned int bmi323_ext_reg_savestate [] = {
134
+ BMI323_GEN_SET1_REG ,
135
+ BMI323_TAP1_REG ,
136
+ BMI323_TAP2_REG ,
137
+ BMI323_TAP3_REG ,
138
+ BMI323_FEAT_IO0_S_TAP_MSK ,
139
+ BMI323_STEP_SC1_REG ,
140
+ BMI323_ANYMO1_REG ,
141
+ BMI323_NOMO1_REG ,
142
+ BMI323_ANYMO1_REG + BMI323_MO2_OFFSET ,
143
+ BMI323_NOMO1_REG + BMI323_MO2_OFFSET ,
144
+ BMI323_ANYMO1_REG + BMI323_MO3_OFFSET ,
145
+ BMI323_NOMO1_REG + BMI323_MO3_OFFSET
146
+ };
147
+
148
+ struct bmi323_regs_runtime_pm {
149
+ unsigned int reg_settings [ARRAY_SIZE (bmi323_reg_savestate )];
150
+ unsigned int ext_reg_settings [ARRAY_SIZE (bmi323_ext_reg_savestate )];
151
+ };
152
+
121
153
struct bmi323_data {
122
154
struct device * dev ;
123
155
struct regmap * regmap ;
@@ -130,6 +162,7 @@ struct bmi323_data {
130
162
u32 odrns [BMI323_SENSORS_CNT ];
131
163
u32 odrhz [BMI323_SENSORS_CNT ];
132
164
unsigned int feature_events ;
165
+ struct bmi323_regs_runtime_pm runtime_pm_status ;
133
166
134
167
/*
135
168
* Lock to protect the members of device's private data from concurrent
@@ -1972,6 +2005,11 @@ static void bmi323_disable(void *data_ptr)
1972
2005
1973
2006
bmi323_set_mode (data , BMI323_ACCEL , ACC_GYRO_MODE_DISABLE );
1974
2007
bmi323_set_mode (data , BMI323_GYRO , ACC_GYRO_MODE_DISABLE );
2008
+
2009
+ /*
2010
+ * Place the peripheral in its lowest power consuming state.
2011
+ */
2012
+ regmap_write (data -> regmap , BMI323_CMD_REG , BMI323_RST_VAL );
1975
2013
}
1976
2014
1977
2015
static int bmi323_set_bw (struct bmi323_data * data ,
@@ -2030,6 +2068,13 @@ static int bmi323_init(struct bmi323_data *data)
2030
2068
return dev_err_probe (data -> dev , - EINVAL ,
2031
2069
"Sensor power error = 0x%x\n" , val );
2032
2070
2071
+ return 0 ;
2072
+ }
2073
+
2074
+ static int bmi323_init_reset (struct bmi323_data * data )
2075
+ {
2076
+ int ret ;
2077
+
2033
2078
/*
2034
2079
* Set the Bandwidth coefficient which defines the 3 dB cutoff
2035
2080
* frequency in relation to the ODR.
@@ -2078,12 +2123,18 @@ int bmi323_core_probe(struct device *dev)
2078
2123
data = iio_priv (indio_dev );
2079
2124
data -> dev = dev ;
2080
2125
data -> regmap = regmap ;
2126
+ data -> irq_pin = BMI323_IRQ_DISABLED ;
2127
+ data -> state = BMI323_IDLE ;
2081
2128
mutex_init (& data -> mutex );
2082
2129
2083
2130
ret = bmi323_init (data );
2084
2131
if (ret )
2085
2132
return - EINVAL ;
2086
2133
2134
+ ret = bmi323_init_reset (data );
2135
+ if (ret )
2136
+ return - EINVAL ;
2137
+
2087
2138
if (!iio_read_acpi_mount_matrix (dev , & data -> orientation , "ROTM" )) {
2088
2139
ret = iio_read_mount_matrix (dev , & data -> orientation );
2089
2140
if (ret )
@@ -2117,21 +2168,127 @@ int bmi323_core_probe(struct device *dev)
2117
2168
return dev_err_probe (data -> dev , ret ,
2118
2169
"Unable to register iio device\n" );
2119
2170
2120
- return 0 ;
2171
+ return bmi323_fifo_disable ( data ) ;
2121
2172
}
2122
2173
EXPORT_SYMBOL_NS_GPL (bmi323_core_probe , IIO_BMI323 );
2123
2174
2124
2175
#if defined(CONFIG_PM )
2125
2176
static int bmi323_core_runtime_suspend (struct device * dev )
2126
2177
{
2127
2178
struct iio_dev * indio_dev = dev_get_drvdata (dev );
2179
+ struct bmi323_data * data = iio_priv (indio_dev );
2180
+ struct bmi323_regs_runtime_pm * savestate = & data -> runtime_pm_status ;
2181
+ int ret ;
2182
+
2183
+ guard (mutex )(& data -> mutex );
2128
2184
2129
- return iio_device_suspend_triggering (indio_dev );
2185
+ ret = iio_device_suspend_triggering (indio_dev );
2186
+ if (ret )
2187
+ return ret ;
2188
+
2189
+ /* Save registers meant to be restored by resume pm callback. */
2190
+ for (unsigned int i = 0 ; i < ARRAY_SIZE (bmi323_reg_savestate ); i ++ ) {
2191
+ ret = regmap_read (data -> regmap , bmi323_reg_savestate [i ],
2192
+ & savestate -> reg_settings [i ]);
2193
+ if (ret ) {
2194
+ dev_err (data -> dev ,
2195
+ "Error reading bmi323 reg 0x%x: %d\n" ,
2196
+ bmi323_reg_savestate [i ], ret );
2197
+ return ret ;
2198
+ }
2199
+ }
2200
+
2201
+ for (unsigned int i = 0 ; i < ARRAY_SIZE (bmi323_ext_reg_savestate ); i ++ ) {
2202
+ ret = bmi323_read_ext_reg (data , bmi323_reg_savestate [i ],
2203
+ & savestate -> reg_settings [i ]);
2204
+ if (ret ) {
2205
+ dev_err (data -> dev ,
2206
+ "Error reading bmi323 external reg 0x%x: %d\n" ,
2207
+ bmi323_reg_savestate [i ], ret );
2208
+ return ret ;
2209
+ }
2210
+ }
2211
+
2212
+ /* Perform soft reset to place the device in its lowest power state. */
2213
+ ret = regmap_write (data -> regmap , BMI323_CMD_REG , BMI323_RST_VAL );
2214
+ if (ret )
2215
+ return ret ;
2216
+
2217
+ return 0 ;
2130
2218
}
2131
2219
2132
2220
static int bmi323_core_runtime_resume (struct device * dev )
2133
2221
{
2134
2222
struct iio_dev * indio_dev = dev_get_drvdata (dev );
2223
+ struct bmi323_data * data = iio_priv (indio_dev );
2224
+ struct bmi323_regs_runtime_pm * savestate = & data -> runtime_pm_status ;
2225
+ unsigned int val ;
2226
+ int ret ;
2227
+
2228
+ guard (mutex )(& data -> mutex );
2229
+
2230
+ /*
2231
+ * Perform the device power-on and initial setup once again
2232
+ * after being reset in the lower power state by runtime-pm.
2233
+ */
2234
+ ret = bmi323_init (data );
2235
+ if (!ret )
2236
+ return ret ;
2237
+
2238
+ /* Register must be cleared before changing an active config */
2239
+ ret = regmap_write (data -> regmap , BMI323_FEAT_IO0_REG , 0 );
2240
+ if (ret ) {
2241
+ dev_err (data -> dev , "Error stopping feature engine\n" );
2242
+ return ret ;
2243
+ }
2244
+
2245
+ for (unsigned int i = 0 ; i < ARRAY_SIZE (bmi323_ext_reg_savestate ); i ++ ) {
2246
+ ret = bmi323_write_ext_reg (data , bmi323_reg_savestate [i ],
2247
+ savestate -> reg_settings [i ]);
2248
+ if (ret ) {
2249
+ dev_err (data -> dev ,
2250
+ "Error writing bmi323 external reg 0x%x: %d\n" ,
2251
+ bmi323_reg_savestate [i ], ret );
2252
+ return ret ;
2253
+ }
2254
+ }
2255
+
2256
+ for (unsigned int i = 0 ; i < ARRAY_SIZE (bmi323_reg_savestate ); i ++ ) {
2257
+ ret = regmap_write (data -> regmap , bmi323_reg_savestate [i ],
2258
+ savestate -> reg_settings [i ]);
2259
+ if (ret ) {
2260
+ dev_err (data -> dev ,
2261
+ "Error writing bmi323 reg 0x%x: %d\n" ,
2262
+ bmi323_reg_savestate [i ], ret );
2263
+ return ret ;
2264
+ }
2265
+ }
2266
+
2267
+ /*
2268
+ * Clear old FIFO samples that might be generated before suspend
2269
+ * or generated from a peripheral state not equal to the saved one.
2270
+ */
2271
+ if (data -> state == BMI323_BUFFER_FIFO ) {
2272
+ ret = regmap_write (data -> regmap , BMI323_FIFO_CTRL_REG ,
2273
+ BMI323_FIFO_FLUSH_MSK );
2274
+ if (ret ) {
2275
+ dev_err (data -> dev , "Error flushing FIFO buffer: %d\n" , ret );
2276
+ return ret ;
2277
+ }
2278
+ }
2279
+
2280
+ ret = regmap_read (data -> regmap , BMI323_ERR_REG , & val );
2281
+ if (ret ) {
2282
+ dev_err (data -> dev ,
2283
+ "Error reading bmi323 error register: %d\n" , ret );
2284
+ return ret ;
2285
+ }
2286
+
2287
+ if (val ) {
2288
+ dev_err (data -> dev ,
2289
+ "Sensor power error in PM = 0x%x\n" , val );
2290
+ return - EINVAL ;
2291
+ }
2135
2292
2136
2293
return iio_device_resume_triggering (indio_dev );
2137
2294
}
0 commit comments