@@ -118,6 +118,38 @@ static const struct bmi323_hw bmi323_hw[2] = {
118118 },
119119};
120120
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+
121153struct bmi323_data {
122154 struct device * dev ;
123155 struct regmap * regmap ;
@@ -130,6 +162,7 @@ struct bmi323_data {
130162 u32 odrns [BMI323_SENSORS_CNT ];
131163 u32 odrhz [BMI323_SENSORS_CNT ];
132164 unsigned int feature_events ;
165+ struct bmi323_regs_runtime_pm runtime_pm_status ;
133166
134167 /*
135168 * Lock to protect the members of device's private data from concurrent
@@ -1972,6 +2005,11 @@ static void bmi323_disable(void *data_ptr)
19722005
19732006 bmi323_set_mode (data , BMI323_ACCEL , ACC_GYRO_MODE_DISABLE );
19742007 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 );
19752013}
19762014
19772015static int bmi323_set_bw (struct bmi323_data * data ,
@@ -2030,6 +2068,13 @@ static int bmi323_init(struct bmi323_data *data)
20302068 return dev_err_probe (data -> dev , - EINVAL ,
20312069 "Sensor power error = 0x%x\n" , val );
20322070
2071+ return 0 ;
2072+ }
2073+
2074+ static int bmi323_init_reset (struct bmi323_data * data )
2075+ {
2076+ int ret ;
2077+
20332078 /*
20342079 * Set the Bandwidth coefficient which defines the 3 dB cutoff
20352080 * frequency in relation to the ODR.
@@ -2078,12 +2123,18 @@ int bmi323_core_probe(struct device *dev)
20782123 data = iio_priv (indio_dev );
20792124 data -> dev = dev ;
20802125 data -> regmap = regmap ;
2126+ data -> irq_pin = BMI323_IRQ_DISABLED ;
2127+ data -> state = BMI323_IDLE ;
20812128 mutex_init (& data -> mutex );
20822129
20832130 ret = bmi323_init (data );
20842131 if (ret )
20852132 return - EINVAL ;
20862133
2134+ ret = bmi323_init_reset (data );
2135+ if (ret )
2136+ return - EINVAL ;
2137+
20872138 if (!iio_read_acpi_mount_matrix (dev , & data -> orientation , "ROTM" )) {
20882139 ret = iio_read_mount_matrix (dev , & data -> orientation );
20892140 if (ret )
@@ -2117,21 +2168,127 @@ int bmi323_core_probe(struct device *dev)
21172168 return dev_err_probe (data -> dev , ret ,
21182169 "Unable to register iio device\n" );
21192170
2120- return 0 ;
2171+ return bmi323_fifo_disable ( data ) ;
21212172}
21222173EXPORT_SYMBOL_NS_GPL (bmi323_core_probe , IIO_BMI323 );
21232174
21242175#if defined(CONFIG_PM )
21252176static int bmi323_core_runtime_suspend (struct device * dev )
21262177{
21272178 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 );
21282184
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 ;
21302218}
21312219
21322220static int bmi323_core_runtime_resume (struct device * dev )
21332221{
21342222 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+ }
21352292
21362293 return iio_device_resume_triggering (indio_dev );
21372294}
0 commit comments