xref: /linux/drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
12871c45dSChris Morgan // SPDX-License-Identifier: GPL-2.0-or-later
22871c45dSChris Morgan /*
32871c45dSChris Morgan  * Copyright (C) 2026 InvenSense, Inc.
42871c45dSChris Morgan  */
52871c45dSChris Morgan 
62871c45dSChris Morgan #include <linux/bitfield.h>
72871c45dSChris Morgan #include <linux/dev_printk.h>
82871c45dSChris Morgan #include <linux/err.h>
92871c45dSChris Morgan #include <linux/i2c.h>
102871c45dSChris Morgan #include <linux/module.h>
112871c45dSChris Morgan #include <linux/regmap.h>
122871c45dSChris Morgan 
132871c45dSChris Morgan #include "inv_icm42607.h"
142871c45dSChris Morgan 
152871c45dSChris Morgan static int inv_icm42607_i2c_bus_setup(struct inv_icm42607_state *st)
162871c45dSChris Morgan {
172871c45dSChris Morgan 	unsigned int val;
182871c45dSChris Morgan 	int ret;
192871c45dSChris Morgan 
202871c45dSChris Morgan 	ret = regmap_clear_bits(st->map, INV_ICM42607_REG_INTF_CONFIG1,
212871c45dSChris Morgan 				INV_ICM42607_INTF_CONFIG1_I3C_DDR_EN |
222871c45dSChris Morgan 				INV_ICM42607_INTF_CONFIG1_I3C_SDR_EN);
232871c45dSChris Morgan 	if (ret)
242871c45dSChris Morgan 		return ret;
252871c45dSChris Morgan 
262871c45dSChris Morgan 	val = FIELD_PREP(INV_ICM42607_DRIVE_CONFIG2_I2C_MASK,
272871c45dSChris Morgan 			 INV_ICM42607_SLEW_RATE_12_36NS);
282871c45dSChris Morgan 	ret = regmap_update_bits(st->map, INV_ICM42607_REG_DRIVE_CONFIG2,
292871c45dSChris Morgan 				 INV_ICM42607_DRIVE_CONFIG2_I2C_MASK, val);
302871c45dSChris Morgan 	if (ret)
312871c45dSChris Morgan 		return ret;
322871c45dSChris Morgan 
332871c45dSChris Morgan 	val = FIELD_PREP(INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK,
342871c45dSChris Morgan 			 INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS);
352871c45dSChris Morgan 
362871c45dSChris Morgan 	return regmap_update_bits(st->map, INV_ICM42607_REG_INTF_CONFIG0,
372871c45dSChris Morgan 				  INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK,
382871c45dSChris Morgan 				  val);
392871c45dSChris Morgan }
402871c45dSChris Morgan 
412871c45dSChris Morgan static int inv_icm42607_probe(struct i2c_client *client)
422871c45dSChris Morgan {
432871c45dSChris Morgan 	struct device *dev = &client->dev;
442871c45dSChris Morgan 	const struct inv_icm42607_hw *hw;
452871c45dSChris Morgan 	struct regmap *regmap;
462871c45dSChris Morgan 
472871c45dSChris Morgan 	hw = i2c_get_match_data(client);
482871c45dSChris Morgan 	if (!hw)
492871c45dSChris Morgan 		return dev_err_probe(dev, -ENODEV, "Failed to get i2c data\n");
502871c45dSChris Morgan 
512871c45dSChris Morgan 	regmap = devm_regmap_init_i2c(client, &inv_icm42607_regmap_config);
522871c45dSChris Morgan 	if (IS_ERR(regmap))
532871c45dSChris Morgan 		return dev_err_probe(dev, PTR_ERR(regmap),
542871c45dSChris Morgan 				     "Failed to register i2c regmap\n");
552871c45dSChris Morgan 
562871c45dSChris Morgan 	return inv_icm42607_core_probe(regmap, hw, inv_icm42607_i2c_bus_setup);
572871c45dSChris Morgan }
582871c45dSChris Morgan 
592871c45dSChris Morgan static const struct i2c_device_id inv_icm42607_id[] = {
602871c45dSChris Morgan 	{
612871c45dSChris Morgan 		.name = "icm42607",
622871c45dSChris Morgan 		.driver_data = (kernel_ulong_t)&inv_icm42607_hw_data,
632871c45dSChris Morgan 	}, {
642871c45dSChris Morgan 		.name = "icm42607p",
652871c45dSChris Morgan 		.driver_data = (kernel_ulong_t)&inv_icm42607p_hw_data,
662871c45dSChris Morgan 	},
672871c45dSChris Morgan 	{ }
682871c45dSChris Morgan };
692871c45dSChris Morgan MODULE_DEVICE_TABLE(i2c, inv_icm42607_id);
702871c45dSChris Morgan 
712871c45dSChris Morgan static const struct of_device_id inv_icm42607_of_matches[] = {
722871c45dSChris Morgan 	{
732871c45dSChris Morgan 		.compatible = "invensense,icm42607",
742871c45dSChris Morgan 		.data = &inv_icm42607_hw_data,
752871c45dSChris Morgan 	}, {
762871c45dSChris Morgan 		.compatible = "invensense,icm42607p",
772871c45dSChris Morgan 		.data = &inv_icm42607p_hw_data,
782871c45dSChris Morgan 	},
792871c45dSChris Morgan 	{ }
802871c45dSChris Morgan };
812871c45dSChris Morgan MODULE_DEVICE_TABLE(of, inv_icm42607_of_matches);
822871c45dSChris Morgan 
832871c45dSChris Morgan static struct i2c_driver inv_icm42607_driver = {
842871c45dSChris Morgan 	.driver = {
852871c45dSChris Morgan 		.name = "inv-icm42607-i2c",
862871c45dSChris Morgan 		.of_match_table = inv_icm42607_of_matches,
87*3007c153SChris Morgan 		.pm = pm_ptr(&inv_icm42607_pm_ops),
882871c45dSChris Morgan 	},
892871c45dSChris Morgan 	.id_table = inv_icm42607_id,
902871c45dSChris Morgan 	.probe = inv_icm42607_probe,
912871c45dSChris Morgan };
922871c45dSChris Morgan module_i2c_driver(inv_icm42607_driver);
932871c45dSChris Morgan 
942871c45dSChris Morgan MODULE_AUTHOR("InvenSense, Inc.");
952871c45dSChris Morgan MODULE_DESCRIPTION("InvenSense ICM-42607 I2C driver");
962871c45dSChris Morgan MODULE_LICENSE("GPL");
972871c45dSChris Morgan MODULE_IMPORT_NS("IIO_ICM42607");
98