Skip to content

Commit 7297ef1

Browse files
jmaneyrol-invnjic23
authored andcommitted
iio: imu: inv_icm42600: add I2C driver for inv_icm42600 driver
Add I2C driver for InvenSense ICM-426xxx devices. Configure bus signal slew rates as indicated in the datasheet. Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent 31c24c1 commit 7297ef1

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (C) 2020 InvenSense, Inc.
4+
*/
5+
6+
#include <linux/kernel.h>
7+
#include <linux/device.h>
8+
#include <linux/module.h>
9+
#include <linux/mod_devicetable.h>
10+
#include <linux/i2c.h>
11+
#include <linux/regmap.h>
12+
#include <linux/property.h>
13+
14+
#include "inv_icm42600.h"
15+
16+
static int inv_icm42600_i2c_bus_setup(struct inv_icm42600_state *st)
17+
{
18+
unsigned int mask, val;
19+
int ret;
20+
21+
/* setup interface registers */
22+
ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6,
23+
INV_ICM42600_INTF_CONFIG6_MASK,
24+
INV_ICM42600_INTF_CONFIG6_I3C_EN);
25+
if (ret)
26+
return ret;
27+
28+
ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4,
29+
INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY, 0);
30+
if (ret)
31+
return ret;
32+
33+
/* set slew rates for I2C and SPI */
34+
mask = INV_ICM42600_DRIVE_CONFIG_I2C_MASK |
35+
INV_ICM42600_DRIVE_CONFIG_SPI_MASK;
36+
val = INV_ICM42600_DRIVE_CONFIG_I2C(INV_ICM42600_SLEW_RATE_12_36NS) |
37+
INV_ICM42600_DRIVE_CONFIG_SPI(INV_ICM42600_SLEW_RATE_12_36NS);
38+
ret = regmap_update_bits(st->map, INV_ICM42600_REG_DRIVE_CONFIG,
39+
mask, val);
40+
if (ret)
41+
return ret;
42+
43+
/* disable SPI bus */
44+
return regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
45+
INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK,
46+
INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS);
47+
}
48+
49+
static int inv_icm42600_probe(struct i2c_client *client)
50+
{
51+
const void *match;
52+
enum inv_icm42600_chip chip;
53+
struct regmap *regmap;
54+
55+
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
56+
return -ENOTSUPP;
57+
58+
match = device_get_match_data(&client->dev);
59+
if (!match)
60+
return -EINVAL;
61+
chip = (enum inv_icm42600_chip)match;
62+
63+
regmap = devm_regmap_init_i2c(client, &inv_icm42600_regmap_config);
64+
if (IS_ERR(regmap))
65+
return PTR_ERR(regmap);
66+
67+
return inv_icm42600_core_probe(regmap, chip, inv_icm42600_i2c_bus_setup);
68+
}
69+
70+
static const struct of_device_id inv_icm42600_of_matches[] = {
71+
{
72+
.compatible = "invensense,icm42600",
73+
.data = (void *)INV_CHIP_ICM42600,
74+
}, {
75+
.compatible = "invensense,icm42602",
76+
.data = (void *)INV_CHIP_ICM42602,
77+
}, {
78+
.compatible = "invensense,icm42605",
79+
.data = (void *)INV_CHIP_ICM42605,
80+
}, {
81+
.compatible = "invensense,icm42622",
82+
.data = (void *)INV_CHIP_ICM42622,
83+
},
84+
{}
85+
};
86+
MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches);
87+
88+
static struct i2c_driver inv_icm42600_driver = {
89+
.driver = {
90+
.name = "inv-icm42600-i2c",
91+
.of_match_table = inv_icm42600_of_matches,
92+
.pm = &inv_icm42600_pm_ops,
93+
},
94+
.probe_new = inv_icm42600_probe,
95+
};
96+
module_i2c_driver(inv_icm42600_driver);
97+
98+
MODULE_AUTHOR("InvenSense, Inc.");
99+
MODULE_DESCRIPTION("InvenSense ICM-426xx I2C driver");
100+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)