Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * STMicroelectronics sensors spi library driver
0004  *
0005  * Copyright 2012-2013 STMicroelectronics Inc.
0006  *
0007  * Denis Ciocca <denis.ciocca@st.com>
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/iio/iio.h>
0013 #include <linux/property.h>
0014 #include <linux/regmap.h>
0015 #include <linux/spi/spi.h>
0016 
0017 #include <linux/iio/common/st_sensors_spi.h>
0018 
0019 #define ST_SENSORS_SPI_MULTIREAD    0xc0
0020 
0021 static const struct regmap_config st_sensors_spi_regmap_config = {
0022     .reg_bits = 8,
0023     .val_bits = 8,
0024 };
0025 
0026 static const struct regmap_config st_sensors_spi_regmap_multiread_bit_config = {
0027     .reg_bits = 8,
0028     .val_bits = 8,
0029     .read_flag_mask = ST_SENSORS_SPI_MULTIREAD,
0030 };
0031 
0032 /*
0033  * st_sensors_is_spi_3_wire() - check if SPI 3-wire mode has been selected
0034  * @spi: spi device reference.
0035  *
0036  * Return: true if SPI 3-wire mode is selected, false otherwise.
0037  */
0038 static bool st_sensors_is_spi_3_wire(struct spi_device *spi)
0039 {
0040     struct st_sensors_platform_data *pdata;
0041     struct device *dev = &spi->dev;
0042 
0043     if (device_property_read_bool(dev, "spi-3wire"))
0044         return true;
0045 
0046     pdata = dev_get_platdata(dev);
0047     if (pdata && pdata->spi_3wire)
0048         return true;
0049 
0050     return false;
0051 }
0052 
0053 /*
0054  * st_sensors_configure_spi_3_wire() - configure SPI 3-wire if needed
0055  * @spi: spi device reference.
0056  * @settings: sensor specific settings reference.
0057  *
0058  * Return: 0 on success, else a negative error code.
0059  */
0060 static int st_sensors_configure_spi_3_wire(struct spi_device *spi,
0061                        struct st_sensor_settings *settings)
0062 {
0063     if (settings->sim.addr) {
0064         u8 buffer[] = {
0065             settings->sim.addr,
0066             settings->sim.value
0067         };
0068 
0069         return spi_write(spi, buffer, 2);
0070     }
0071 
0072     return 0;
0073 }
0074 
0075 /*
0076  * st_sensors_spi_configure() - configure SPI interface
0077  * @indio_dev: IIO device reference.
0078  * @spi: spi device reference.
0079  *
0080  * Return: 0 on success, else a negative error code.
0081  */
0082 int st_sensors_spi_configure(struct iio_dev *indio_dev,
0083                  struct spi_device *spi)
0084 {
0085     struct st_sensor_data *sdata = iio_priv(indio_dev);
0086     const struct regmap_config *config;
0087     int err;
0088 
0089     if (st_sensors_is_spi_3_wire(spi)) {
0090         err = st_sensors_configure_spi_3_wire(spi,
0091                               sdata->sensor_settings);
0092         if (err < 0)
0093             return err;
0094     }
0095 
0096     if (sdata->sensor_settings->multi_read_bit)
0097         config = &st_sensors_spi_regmap_multiread_bit_config;
0098     else
0099         config = &st_sensors_spi_regmap_config;
0100 
0101     sdata->regmap = devm_regmap_init_spi(spi, config);
0102     if (IS_ERR(sdata->regmap)) {
0103         dev_err(&spi->dev, "Failed to register spi regmap (%ld)\n",
0104             PTR_ERR(sdata->regmap));
0105         return PTR_ERR(sdata->regmap);
0106     }
0107 
0108     spi_set_drvdata(spi, indio_dev);
0109 
0110     indio_dev->name = spi->modalias;
0111 
0112     sdata->irq = spi->irq;
0113 
0114     return 0;
0115 }
0116 EXPORT_SYMBOL_NS(st_sensors_spi_configure, IIO_ST_SENSORS);
0117 
0118 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
0119 MODULE_DESCRIPTION("STMicroelectronics ST-sensors spi driver");
0120 MODULE_LICENSE("GPL v2");