linux-imx/drivers/iio/accel/fxls8962af-i2c.c
Carlos Song d7348e0308 LF-12697: support shutdown for for fxls8962 sensor
When system do warm reboot, chip should enter the standby state. It
will ensure in every boot the chip is enabled in same chip internal
logic state.

Add shutdown support for the sensor to disable pm and set the sensor
in standby state in system reboot.

Now this sensor relies on rpm resume suspend to make it enter active
mode and standby mode. When sensor in active mode, system start to
shutdown, because autosuspend_delay value is set 2 seconds, sometimes
this sensor doesn't enter rpm suspend in time when system finished
shutdown. So in next boot the sensor will keep in active mode. In this
case, more time need to be spent to finish the chip reset. According
to datasheet, this sensor need enough time to complete the reset,
otherwise any I2C operation will cause the sensor hang the bus.

Signed-off-by: Carlos Song <carlos.song@nxp.com>
Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
Tested-by: Ye Li <ye.li@nxp.com>
2024-07-18 11:00:16 +08:00

69 lines
1.7 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* NXP FXLS8962AF/FXLS8964AF Accelerometer I2C Driver
*
* Copyright 2021 Connected Cars A/S
*/
#include <linux/dev_printk.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include "fxls8962af.h"
static int fxls8962af_probe(struct i2c_client *client)
{
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &fxls8962af_i2c_regmap_conf);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Failed to initialize i2c regmap\n");
return PTR_ERR(regmap);
}
return fxls8962af_core_probe(&client->dev, regmap, client->irq);
}
static const struct i2c_device_id fxls8962af_id[] = {
{ "fxls8962af", fxls8962af },
{ "fxls8964af", fxls8964af },
{ "fxls8967af", fxls8967af },
{ "fxls8974cf", fxls8974cf },
{}
};
MODULE_DEVICE_TABLE(i2c, fxls8962af_id);
static const struct of_device_id fxls8962af_of_match[] = {
{ .compatible = "nxp,fxls8962af" },
{ .compatible = "nxp,fxls8964af" },
{ .compatible = "nxp,fxls8967af" },
{ .compatible = "nxp,fxls8974cf" },
{}
};
MODULE_DEVICE_TABLE(of, fxls8962af_of_match);
static void fxls8962af_shutdown(struct i2c_client *client)
{
fxls8962af_core_shutdown(&client->dev);
};
static struct i2c_driver fxls8962af_driver = {
.driver = {
.name = "fxls8962af_i2c",
.of_match_table = fxls8962af_of_match,
.pm = pm_ptr(&fxls8962af_pm_ops),
},
.probe = fxls8962af_probe,
.shutdown = fxls8962af_shutdown,
.id_table = fxls8962af_id,
};
module_i2c_driver(fxls8962af_driver);
MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.com>");
MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer i2c driver");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(IIO_FXLS8962AF);