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
30*0e59dc9eSTrevor Gamblin ret = regmap_clear_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4,
31*0e59dc9eSTrevor Gamblin INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY);
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 }, {
81a1432b5bSJean-Baptiste Maneyrol .compatible = "invensense,icm42686",
82a1432b5bSJean-Baptiste Maneyrol .data = (void *)INV_CHIP_ICM42686,
83a1432b5bSJean-Baptiste Maneyrol }, {
849f9ff91bSJean-Baptiste Maneyrol .compatible = "invensense,icm42622",
859f9ff91bSJean-Baptiste Maneyrol .data = (void *)INV_CHIP_ICM42622,
86c896b9f0SJay Greco }, {
8788b49449SJean-Baptiste Maneyrol .compatible = "invensense,icm42688",
8888b49449SJean-Baptiste Maneyrol .data = (void *)INV_CHIP_ICM42688,
8988b49449SJean-Baptiste Maneyrol }, {
90c896b9f0SJay Greco .compatible = "invensense,icm42631",
91c896b9f0SJay Greco .data = (void *)INV_CHIP_ICM42631,
929f9ff91bSJean-Baptiste Maneyrol },
939f9ff91bSJean-Baptiste Maneyrol {}
949f9ff91bSJean-Baptiste Maneyrol };
959f9ff91bSJean-Baptiste Maneyrol MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches);
969f9ff91bSJean-Baptiste Maneyrol
979f9ff91bSJean-Baptiste Maneyrol static struct spi_driver inv_icm42600_driver = {
989f9ff91bSJean-Baptiste Maneyrol .driver = {
999f9ff91bSJean-Baptiste Maneyrol .name = "inv-icm42600-spi",
1009f9ff91bSJean-Baptiste Maneyrol .of_match_table = inv_icm42600_of_matches,
101ef5a5ef2SJonathan Cameron .pm = pm_ptr(&inv_icm42600_pm_ops),
1029f9ff91bSJean-Baptiste Maneyrol },
1039f9ff91bSJean-Baptiste Maneyrol .probe = inv_icm42600_probe,
1049f9ff91bSJean-Baptiste Maneyrol };
1059f9ff91bSJean-Baptiste Maneyrol module_spi_driver(inv_icm42600_driver);
1069f9ff91bSJean-Baptiste Maneyrol
1079f9ff91bSJean-Baptiste Maneyrol MODULE_AUTHOR("InvenSense, Inc.");
1089f9ff91bSJean-Baptiste Maneyrol MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver");
1099f9ff91bSJean-Baptiste Maneyrol MODULE_LICENSE("GPL");
110ef5a5ef2SJonathan Cameron MODULE_IMPORT_NS(IIO_ICM42600);
111