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

st_sensors_spi.c (2865B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * STMicroelectronics sensors spi library driver
      4 *
      5 * Copyright 2012-2013 STMicroelectronics Inc.
      6 *
      7 * Denis Ciocca <denis.ciocca@st.com>
      8 */
      9
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/iio/iio.h>
     13#include <linux/property.h>
     14#include <linux/regmap.h>
     15#include <linux/spi/spi.h>
     16
     17#include <linux/iio/common/st_sensors_spi.h>
     18
     19#define ST_SENSORS_SPI_MULTIREAD	0xc0
     20
     21static const struct regmap_config st_sensors_spi_regmap_config = {
     22	.reg_bits = 8,
     23	.val_bits = 8,
     24};
     25
     26static const struct regmap_config st_sensors_spi_regmap_multiread_bit_config = {
     27	.reg_bits = 8,
     28	.val_bits = 8,
     29	.read_flag_mask = ST_SENSORS_SPI_MULTIREAD,
     30};
     31
     32/*
     33 * st_sensors_is_spi_3_wire() - check if SPI 3-wire mode has been selected
     34 * @spi: spi device reference.
     35 *
     36 * Return: true if SPI 3-wire mode is selected, false otherwise.
     37 */
     38static bool st_sensors_is_spi_3_wire(struct spi_device *spi)
     39{
     40	struct st_sensors_platform_data *pdata;
     41	struct device *dev = &spi->dev;
     42
     43	if (device_property_read_bool(dev, "spi-3wire"))
     44		return true;
     45
     46	pdata = dev_get_platdata(dev);
     47	if (pdata && pdata->spi_3wire)
     48		return true;
     49
     50	return false;
     51}
     52
     53/*
     54 * st_sensors_configure_spi_3_wire() - configure SPI 3-wire if needed
     55 * @spi: spi device reference.
     56 * @settings: sensor specific settings reference.
     57 *
     58 * Return: 0 on success, else a negative error code.
     59 */
     60static int st_sensors_configure_spi_3_wire(struct spi_device *spi,
     61					   struct st_sensor_settings *settings)
     62{
     63	if (settings->sim.addr) {
     64		u8 buffer[] = {
     65			settings->sim.addr,
     66			settings->sim.value
     67		};
     68
     69		return spi_write(spi, buffer, 2);
     70	}
     71
     72	return 0;
     73}
     74
     75/*
     76 * st_sensors_spi_configure() - configure SPI interface
     77 * @indio_dev: IIO device reference.
     78 * @spi: spi device reference.
     79 *
     80 * Return: 0 on success, else a negative error code.
     81 */
     82int st_sensors_spi_configure(struct iio_dev *indio_dev,
     83			     struct spi_device *spi)
     84{
     85	struct st_sensor_data *sdata = iio_priv(indio_dev);
     86	const struct regmap_config *config;
     87	int err;
     88
     89	if (st_sensors_is_spi_3_wire(spi)) {
     90		err = st_sensors_configure_spi_3_wire(spi,
     91						      sdata->sensor_settings);
     92		if (err < 0)
     93			return err;
     94	}
     95
     96	if (sdata->sensor_settings->multi_read_bit)
     97		config = &st_sensors_spi_regmap_multiread_bit_config;
     98	else
     99		config = &st_sensors_spi_regmap_config;
    100
    101	sdata->regmap = devm_regmap_init_spi(spi, config);
    102	if (IS_ERR(sdata->regmap)) {
    103		dev_err(&spi->dev, "Failed to register spi regmap (%ld)\n",
    104			PTR_ERR(sdata->regmap));
    105		return PTR_ERR(sdata->regmap);
    106	}
    107
    108	spi_set_drvdata(spi, indio_dev);
    109
    110	indio_dev->name = spi->modalias;
    111
    112	sdata->irq = spi->irq;
    113
    114	return 0;
    115}
    116EXPORT_SYMBOL_NS(st_sensors_spi_configure, IIO_ST_SENSORS);
    117
    118MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
    119MODULE_DESCRIPTION("STMicroelectronics ST-sensors spi driver");
    120MODULE_LICENSE("GPL v2");