cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inv_icm42600_spi.c (2687B)


      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/spi/spi.h>
     11#include <linux/regmap.h>
     12#include <linux/property.h>
     13
     14#include "inv_icm42600.h"
     15
     16static int inv_icm42600_spi_bus_setup(struct inv_icm42600_state *st)
     17{
     18	unsigned int mask, val;
     19	int ret;
     20
     21	/* setup interface registers */
     22	val = INV_ICM42600_INTF_CONFIG6_I3C_EN |
     23	      INV_ICM42600_INTF_CONFIG6_I3C_SDR_EN |
     24	      INV_ICM42600_INTF_CONFIG6_I3C_DDR_EN;
     25	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6,
     26				 INV_ICM42600_INTF_CONFIG6_MASK, val);
     27	if (ret)
     28		return ret;
     29
     30	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4,
     31				 INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY, 0);
     32	if (ret)
     33		return ret;
     34
     35	/* set slew rates for I2C and SPI */
     36	mask = INV_ICM42600_DRIVE_CONFIG_I2C_MASK |
     37	       INV_ICM42600_DRIVE_CONFIG_SPI_MASK;
     38	val = INV_ICM42600_DRIVE_CONFIG_I2C(INV_ICM42600_SLEW_RATE_20_60NS) |
     39	      INV_ICM42600_DRIVE_CONFIG_SPI(INV_ICM42600_SLEW_RATE_INF_2NS);
     40	ret = regmap_update_bits(st->map, INV_ICM42600_REG_DRIVE_CONFIG,
     41				 mask, val);
     42	if (ret)
     43		return ret;
     44
     45	/* disable i2c bus */
     46	return regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
     47				  INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK,
     48				  INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_I2C_DIS);
     49}
     50
     51static int inv_icm42600_probe(struct spi_device *spi)
     52{
     53	const void *match;
     54	enum inv_icm42600_chip chip;
     55	struct regmap *regmap;
     56
     57	match = device_get_match_data(&spi->dev);
     58	if (!match)
     59		return -EINVAL;
     60	chip = (uintptr_t)match;
     61
     62	regmap = devm_regmap_init_spi(spi, &inv_icm42600_regmap_config);
     63	if (IS_ERR(regmap))
     64		return PTR_ERR(regmap);
     65
     66	return inv_icm42600_core_probe(regmap, chip, spi->irq,
     67				       inv_icm42600_spi_bus_setup);
     68}
     69
     70static 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};
     86MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches);
     87
     88static struct spi_driver inv_icm42600_driver = {
     89	.driver = {
     90		.name = "inv-icm42600-spi",
     91		.of_match_table = inv_icm42600_of_matches,
     92		.pm = &inv_icm42600_pm_ops,
     93	},
     94	.probe = inv_icm42600_probe,
     95};
     96module_spi_driver(inv_icm42600_driver);
     97
     98MODULE_AUTHOR("InvenSense, Inc.");
     99MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver");
    100MODULE_LICENSE("GPL");