File Index
Files and directories
Sign in
FILE

inv_icm42600_i2c.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c C
  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
 16static int inv_icm42600_i2c_bus_setup(struct inv_icm42600_state *st)
 17{
 18	unsigned int mask, val;
 19	int ret;
 20
 21	/*
 22	 * setup interface registers
 23	 * This register write to REG_INTF_CONFIG6 enables a spike filter that
 24	 * is impacting the line and can prevent the I2C ACK to be seen by the
 25	 * controller. So we don't test the return value.
 26	 */
 27	regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6,
 28			   INV_ICM42600_INTF_CONFIG6_MASK,
 29			   INV_ICM42600_INTF_CONFIG6_I3C_EN);
 30
 31	ret = regmap_clear_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4,
 32				INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY);
 33	if (ret)
 34		return ret;
 35
 36	/* set slew rates for I2C and SPI */
 37	mask = INV_ICM42600_DRIVE_CONFIG_I2C_MASK |
 38	       INV_ICM42600_DRIVE_CONFIG_SPI_MASK;
 39	val = INV_ICM42600_DRIVE_CONFIG_I2C(INV_ICM42600_SLEW_RATE_12_36NS) |
 40	      INV_ICM42600_DRIVE_CONFIG_SPI(INV_ICM42600_SLEW_RATE_12_36NS);
 41	ret = regmap_update_bits(st->map, INV_ICM42600_REG_DRIVE_CONFIG,
 42				 mask, val);
 43	if (ret)
 44		return ret;
 45
 46	/* disable SPI bus */
 47	return regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
 48				  INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK,
 49				  INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS);
 50}
 51
 52static int inv_icm42600_probe(struct i2c_client *client)
 53{
 54	const void *match;
 55	enum inv_icm42600_chip chip;
 56	struct regmap *regmap;
 57
 58	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
 59		return -ENOTSUPP;
 60
 61	match = device_get_match_data(&client->dev);
 62	if (!match)
 63		return -EINVAL;
 64	chip = (uintptr_t)match;
 65
 66	regmap = devm_regmap_init_i2c(client, &inv_icm42600_regmap_config);
 67	if (IS_ERR(regmap))
 68		return PTR_ERR(regmap);
 69
 70	return inv_icm42600_core_probe(regmap, chip, inv_icm42600_i2c_bus_setup);
 71}
 72
 73/*
 74 * device id table is used to identify what device can be
 75 * supported by this driver
 76 */
 77static const struct i2c_device_id inv_icm42600_id[] = {
 78	{ "icm42600", INV_CHIP_ICM42600 },
 79	{ "icm42602", INV_CHIP_ICM42602 },
 80	{ "icm42605", INV_CHIP_ICM42605 },
 81	{ "icm42686", INV_CHIP_ICM42686 },
 82	{ "icm42622", INV_CHIP_ICM42622 },
 83	{ "icm42688", INV_CHIP_ICM42688 },
 84	{ "icm42631", INV_CHIP_ICM42631 },
 85	{ }
 86};
 87MODULE_DEVICE_TABLE(i2c, inv_icm42600_id);
 88
 89static const struct of_device_id inv_icm42600_of_matches[] = {
 90	{
 91		.compatible = "invensense,icm42600",
 92		.data = (void *)INV_CHIP_ICM42600,
 93	}, {
 94		.compatible = "invensense,icm42602",
 95		.data = (void *)INV_CHIP_ICM42602,
 96	}, {
 97		.compatible = "invensense,icm42605",
 98		.data = (void *)INV_CHIP_ICM42605,
 99	}, {
100		.compatible = "invensense,icm42686",
101		.data = (void *)INV_CHIP_ICM42686,
102	}, {
103		.compatible = "invensense,icm42622",
104		.data = (void *)INV_CHIP_ICM42622,
105	}, {
106		.compatible = "invensense,icm42688",
107		.data = (void *)INV_CHIP_ICM42688,
108	}, {
109		.compatible = "invensense,icm42631",
110		.data = (void *)INV_CHIP_ICM42631,
111	},
112	{ }
113};
114MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches);
115
116static struct i2c_driver inv_icm42600_driver = {
117	.driver = {
118		.name = "inv-icm42600-i2c",
119		.of_match_table = inv_icm42600_of_matches,
120		.pm = pm_ptr(&inv_icm42600_pm_ops),
121	},
122	.id_table = inv_icm42600_id,
123	.probe = inv_icm42600_probe,
124};
125module_i2c_driver(inv_icm42600_driver);
126
127MODULE_AUTHOR("InvenSense, Inc.");
128MODULE_DESCRIPTION("InvenSense ICM-426xx I2C driver");
129MODULE_LICENSE("GPL");
130MODULE_IMPORT_NS("IIO_ICM42600");
~/ Read-only file preview.