xref: /linux/drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2026 InvenSense, Inc.
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/dev_printk.h>
8 #include <linux/err.h>
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <linux/regmap.h>
12 
13 #include "inv_icm42607.h"
14 
15 static int inv_icm42607_i2c_bus_setup(struct inv_icm42607_state *st)
16 {
17 	unsigned int val;
18 	int ret;
19 
20 	ret = regmap_clear_bits(st->map, INV_ICM42607_REG_INTF_CONFIG1,
21 				INV_ICM42607_INTF_CONFIG1_I3C_DDR_EN |
22 				INV_ICM42607_INTF_CONFIG1_I3C_SDR_EN);
23 	if (ret)
24 		return ret;
25 
26 	val = FIELD_PREP(INV_ICM42607_DRIVE_CONFIG2_I2C_MASK,
27 			 INV_ICM42607_SLEW_RATE_12_36NS);
28 	ret = regmap_update_bits(st->map, INV_ICM42607_REG_DRIVE_CONFIG2,
29 				 INV_ICM42607_DRIVE_CONFIG2_I2C_MASK, val);
30 	if (ret)
31 		return ret;
32 
33 	val = FIELD_PREP(INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK,
34 			 INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS);
35 
36 	return regmap_update_bits(st->map, INV_ICM42607_REG_INTF_CONFIG0,
37 				  INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK,
38 				  val);
39 }
40 
41 static int inv_icm42607_probe(struct i2c_client *client)
42 {
43 	struct device *dev = &client->dev;
44 	const struct inv_icm42607_hw *hw;
45 	struct regmap *regmap;
46 
47 	hw = i2c_get_match_data(client);
48 	if (!hw)
49 		return dev_err_probe(dev, -ENODEV, "Failed to get i2c data\n");
50 
51 	regmap = devm_regmap_init_i2c(client, &inv_icm42607_regmap_config);
52 	if (IS_ERR(regmap))
53 		return dev_err_probe(dev, PTR_ERR(regmap),
54 				     "Failed to register i2c regmap\n");
55 
56 	return inv_icm42607_core_probe(regmap, hw, inv_icm42607_i2c_bus_setup);
57 }
58 
59 static const struct i2c_device_id inv_icm42607_id[] = {
60 	{
61 		.name = "icm42607",
62 		.driver_data = (kernel_ulong_t)&inv_icm42607_hw_data,
63 	}, {
64 		.name = "icm42607p",
65 		.driver_data = (kernel_ulong_t)&inv_icm42607p_hw_data,
66 	},
67 	{ }
68 };
69 MODULE_DEVICE_TABLE(i2c, inv_icm42607_id);
70 
71 static const struct of_device_id inv_icm42607_of_matches[] = {
72 	{
73 		.compatible = "invensense,icm42607",
74 		.data = &inv_icm42607_hw_data,
75 	}, {
76 		.compatible = "invensense,icm42607p",
77 		.data = &inv_icm42607p_hw_data,
78 	},
79 	{ }
80 };
81 MODULE_DEVICE_TABLE(of, inv_icm42607_of_matches);
82 
83 static struct i2c_driver inv_icm42607_driver = {
84 	.driver = {
85 		.name = "inv-icm42607-i2c",
86 		.of_match_table = inv_icm42607_of_matches,
87 		.pm = pm_ptr(&inv_icm42607_pm_ops),
88 	},
89 	.id_table = inv_icm42607_id,
90 	.probe = inv_icm42607_probe,
91 };
92 module_i2c_driver(inv_icm42607_driver);
93 
94 MODULE_AUTHOR("InvenSense, Inc.");
95 MODULE_DESCRIPTION("InvenSense ICM-42607 I2C driver");
96 MODULE_LICENSE("GPL");
97 MODULE_IMPORT_NS("IIO_ICM42607");
98