19f9ff91bSJean-Baptiste Maneyrol // SPDX-License-Identifier: GPL-2.0-or-later
29f9ff91bSJean-Baptiste Maneyrol /*
39f9ff91bSJean-Baptiste Maneyrol  * Copyright (C) 2020 InvenSense, Inc.
49f9ff91bSJean-Baptiste Maneyrol  */
59f9ff91bSJean-Baptiste Maneyrol 
69f9ff91bSJean-Baptiste Maneyrol #include <linux/kernel.h>
79f9ff91bSJean-Baptiste Maneyrol #include <linux/device.h>
89f9ff91bSJean-Baptiste Maneyrol #include <linux/module.h>
99f9ff91bSJean-Baptiste Maneyrol #include <linux/mod_devicetable.h>
109f9ff91bSJean-Baptiste Maneyrol #include <linux/spi/spi.h>
119f9ff91bSJean-Baptiste Maneyrol #include <linux/regmap.h>
129f9ff91bSJean-Baptiste Maneyrol #include <linux/property.h>
139f9ff91bSJean-Baptiste Maneyrol 
149f9ff91bSJean-Baptiste Maneyrol #include "inv_icm42600.h"
159f9ff91bSJean-Baptiste Maneyrol 
inv_icm42600_spi_bus_setup(struct inv_icm42600_state * st)169f9ff91bSJean-Baptiste Maneyrol static int inv_icm42600_spi_bus_setup(struct inv_icm42600_state *st)
179f9ff91bSJean-Baptiste Maneyrol {
189f9ff91bSJean-Baptiste Maneyrol 	unsigned int mask, val;
199f9ff91bSJean-Baptiste Maneyrol 	int ret;
209f9ff91bSJean-Baptiste Maneyrol 
219f9ff91bSJean-Baptiste Maneyrol 	/* setup interface registers */
229f9ff91bSJean-Baptiste Maneyrol 	val = INV_ICM42600_INTF_CONFIG6_I3C_EN |
239f9ff91bSJean-Baptiste Maneyrol 	      INV_ICM42600_INTF_CONFIG6_I3C_SDR_EN |
249f9ff91bSJean-Baptiste Maneyrol 	      INV_ICM42600_INTF_CONFIG6_I3C_DDR_EN;
259f9ff91bSJean-Baptiste Maneyrol 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6,
269f9ff91bSJean-Baptiste Maneyrol 				 INV_ICM42600_INTF_CONFIG6_MASK, val);
279f9ff91bSJean-Baptiste Maneyrol 	if (ret)
289f9ff91bSJean-Baptiste Maneyrol 		return ret;
299f9ff91bSJean-Baptiste Maneyrol 
309f9ff91bSJean-Baptiste Maneyrol 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4,
319f9ff91bSJean-Baptiste Maneyrol 				 INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY, 0);
329f9ff91bSJean-Baptiste Maneyrol 	if (ret)
339f9ff91bSJean-Baptiste Maneyrol 		return ret;
349f9ff91bSJean-Baptiste Maneyrol 
359f9ff91bSJean-Baptiste Maneyrol 	/* set slew rates for I2C and SPI */
369f9ff91bSJean-Baptiste Maneyrol 	mask = INV_ICM42600_DRIVE_CONFIG_I2C_MASK |
379f9ff91bSJean-Baptiste Maneyrol 	       INV_ICM42600_DRIVE_CONFIG_SPI_MASK;
389f9ff91bSJean-Baptiste Maneyrol 	val = INV_ICM42600_DRIVE_CONFIG_I2C(INV_ICM42600_SLEW_RATE_20_60NS) |
399f9ff91bSJean-Baptiste Maneyrol 	      INV_ICM42600_DRIVE_CONFIG_SPI(INV_ICM42600_SLEW_RATE_INF_2NS);
409f9ff91bSJean-Baptiste Maneyrol 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_DRIVE_CONFIG,
419f9ff91bSJean-Baptiste Maneyrol 				 mask, val);
429f9ff91bSJean-Baptiste Maneyrol 	if (ret)
439f9ff91bSJean-Baptiste Maneyrol 		return ret;
449f9ff91bSJean-Baptiste Maneyrol 
459f9ff91bSJean-Baptiste Maneyrol 	/* disable i2c bus */
469f9ff91bSJean-Baptiste Maneyrol 	return regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
479f9ff91bSJean-Baptiste Maneyrol 				  INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK,
489f9ff91bSJean-Baptiste Maneyrol 				  INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_I2C_DIS);
499f9ff91bSJean-Baptiste Maneyrol }
509f9ff91bSJean-Baptiste Maneyrol 
inv_icm42600_probe(struct spi_device * spi)519f9ff91bSJean-Baptiste Maneyrol static int inv_icm42600_probe(struct spi_device *spi)
529f9ff91bSJean-Baptiste Maneyrol {
539f9ff91bSJean-Baptiste Maneyrol 	const void *match;
549f9ff91bSJean-Baptiste Maneyrol 	enum inv_icm42600_chip chip;
559f9ff91bSJean-Baptiste Maneyrol 	struct regmap *regmap;
569f9ff91bSJean-Baptiste Maneyrol 
579f9ff91bSJean-Baptiste Maneyrol 	match = device_get_match_data(&spi->dev);
589f9ff91bSJean-Baptiste Maneyrol 	if (!match)
599f9ff91bSJean-Baptiste Maneyrol 		return -EINVAL;
60072cc981SJonathan Cameron 	chip = (uintptr_t)match;
619f9ff91bSJean-Baptiste Maneyrol 
629f9ff91bSJean-Baptiste Maneyrol 	regmap = devm_regmap_init_spi(spi, &inv_icm42600_regmap_config);
639f9ff91bSJean-Baptiste Maneyrol 	if (IS_ERR(regmap))
649f9ff91bSJean-Baptiste Maneyrol 		return PTR_ERR(regmap);
659f9ff91bSJean-Baptiste Maneyrol 
66e5efa104SJean-Baptiste Maneyrol 	return inv_icm42600_core_probe(regmap, chip, spi->irq,
67e5efa104SJean-Baptiste Maneyrol 				       inv_icm42600_spi_bus_setup);
689f9ff91bSJean-Baptiste Maneyrol }
699f9ff91bSJean-Baptiste Maneyrol 
709f9ff91bSJean-Baptiste Maneyrol static const struct of_device_id inv_icm42600_of_matches[] = {
719f9ff91bSJean-Baptiste Maneyrol 	{
729f9ff91bSJean-Baptiste Maneyrol 		.compatible = "invensense,icm42600",
739f9ff91bSJean-Baptiste Maneyrol 		.data = (void *)INV_CHIP_ICM42600,
749f9ff91bSJean-Baptiste Maneyrol 	}, {
759f9ff91bSJean-Baptiste Maneyrol 		.compatible = "invensense,icm42602",
769f9ff91bSJean-Baptiste Maneyrol 		.data = (void *)INV_CHIP_ICM42602,
779f9ff91bSJean-Baptiste Maneyrol 	}, {
789f9ff91bSJean-Baptiste Maneyrol 		.compatible = "invensense,icm42605",
799f9ff91bSJean-Baptiste Maneyrol 		.data = (void *)INV_CHIP_ICM42605,
809f9ff91bSJean-Baptiste Maneyrol 	}, {
819f9ff91bSJean-Baptiste Maneyrol 		.compatible = "invensense,icm42622",
829f9ff91bSJean-Baptiste Maneyrol 		.data = (void *)INV_CHIP_ICM42622,
83*c896b9f0SJay Greco 	}, {
84*c896b9f0SJay Greco 		.compatible = "invensense,icm42631",
85*c896b9f0SJay Greco 		.data = (void *)INV_CHIP_ICM42631,
869f9ff91bSJean-Baptiste Maneyrol 	},
879f9ff91bSJean-Baptiste Maneyrol 	{}
889f9ff91bSJean-Baptiste Maneyrol };
899f9ff91bSJean-Baptiste Maneyrol MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches);
909f9ff91bSJean-Baptiste Maneyrol 
919f9ff91bSJean-Baptiste Maneyrol static struct spi_driver inv_icm42600_driver = {
929f9ff91bSJean-Baptiste Maneyrol 	.driver = {
939f9ff91bSJean-Baptiste Maneyrol 		.name = "inv-icm42600-spi",
949f9ff91bSJean-Baptiste Maneyrol 		.of_match_table = inv_icm42600_of_matches,
95ef5a5ef2SJonathan Cameron 		.pm = pm_ptr(&inv_icm42600_pm_ops),
969f9ff91bSJean-Baptiste Maneyrol 	},
979f9ff91bSJean-Baptiste Maneyrol 	.probe = inv_icm42600_probe,
989f9ff91bSJean-Baptiste Maneyrol };
999f9ff91bSJean-Baptiste Maneyrol module_spi_driver(inv_icm42600_driver);
1009f9ff91bSJean-Baptiste Maneyrol 
1019f9ff91bSJean-Baptiste Maneyrol MODULE_AUTHOR("InvenSense, Inc.");
1029f9ff91bSJean-Baptiste Maneyrol MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver");
1039f9ff91bSJean-Baptiste Maneyrol MODULE_LICENSE("GPL");
104ef5a5ef2SJonathan Cameron MODULE_IMPORT_NS(IIO_ICM42600);
105