Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * mcp4922.c
0004  *
0005  * Driver for Microchip Digital to Analog Converters.
0006  * Supports MCP4902, MCP4912, and MCP4922.
0007  *
0008  * Copyright (c) 2014 EMAC Inc.
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/spi/spi.h>
0014 #include <linux/iio/iio.h>
0015 #include <linux/iio/sysfs.h>
0016 #include <linux/regulator/consumer.h>
0017 #include <linux/bitops.h>
0018 
0019 #define MCP4922_NUM_CHANNELS    2
0020 #define MCP4921_NUM_CHANNELS    1
0021 
0022 enum mcp4922_supported_device_ids {
0023     ID_MCP4902,
0024     ID_MCP4912,
0025     ID_MCP4921,
0026     ID_MCP4922,
0027 };
0028 
0029 struct mcp4922_state {
0030     struct spi_device *spi;
0031     unsigned int value[MCP4922_NUM_CHANNELS];
0032     unsigned int vref_mv;
0033     struct regulator *vref_reg;
0034     u8 mosi[2] __aligned(IIO_DMA_MINALIGN);
0035 };
0036 
0037 #define MCP4922_CHAN(chan, bits) {          \
0038     .type = IIO_VOLTAGE,                \
0039     .output = 1,                    \
0040     .indexed = 1,                   \
0041     .channel = chan,                \
0042     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
0043     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
0044     .scan_type = {                  \
0045         .sign = 'u',                \
0046         .realbits = (bits),         \
0047         .storagebits = 16,          \
0048         .shift = 12 - (bits),           \
0049     },                      \
0050 }
0051 
0052 static int mcp4922_spi_write(struct mcp4922_state *state, u8 addr, u32 val)
0053 {
0054     state->mosi[1] = val & 0xff;
0055     state->mosi[0] = (addr == 0) ? 0x00 : 0x80;
0056     state->mosi[0] |= 0x30 | ((val >> 8) & 0x0f);
0057 
0058     return spi_write(state->spi, state->mosi, 2);
0059 }
0060 
0061 static int mcp4922_read_raw(struct iio_dev *indio_dev,
0062         struct iio_chan_spec const *chan,
0063         int *val,
0064         int *val2,
0065         long mask)
0066 {
0067     struct mcp4922_state *state = iio_priv(indio_dev);
0068 
0069     switch (mask) {
0070     case IIO_CHAN_INFO_RAW:
0071         *val = state->value[chan->channel];
0072         return IIO_VAL_INT;
0073     case IIO_CHAN_INFO_SCALE:
0074         *val = state->vref_mv;
0075         *val2 = chan->scan_type.realbits;
0076         return IIO_VAL_FRACTIONAL_LOG2;
0077     default:
0078         return -EINVAL;
0079     }
0080 }
0081 
0082 static int mcp4922_write_raw(struct iio_dev *indio_dev,
0083         struct iio_chan_spec const *chan,
0084         int val,
0085         int val2,
0086         long mask)
0087 {
0088     struct mcp4922_state *state = iio_priv(indio_dev);
0089     int ret;
0090 
0091     if (val2 != 0)
0092         return -EINVAL;
0093 
0094     switch (mask) {
0095     case IIO_CHAN_INFO_RAW:
0096         if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
0097             return -EINVAL;
0098         val <<= chan->scan_type.shift;
0099 
0100         ret = mcp4922_spi_write(state, chan->channel, val);
0101         if (!ret)
0102             state->value[chan->channel] = val;
0103         return ret;
0104 
0105     default:
0106         return -EINVAL;
0107     }
0108 }
0109 
0110 static const struct iio_chan_spec mcp4922_channels[4][MCP4922_NUM_CHANNELS] = {
0111     [ID_MCP4902] = { MCP4922_CHAN(0, 8),    MCP4922_CHAN(1, 8) },
0112     [ID_MCP4912] = { MCP4922_CHAN(0, 10),   MCP4922_CHAN(1, 10) },
0113     [ID_MCP4921] = { MCP4922_CHAN(0, 12),   {} },
0114     [ID_MCP4922] = { MCP4922_CHAN(0, 12),   MCP4922_CHAN(1, 12) },
0115 };
0116 
0117 static const struct iio_info mcp4922_info = {
0118     .read_raw = &mcp4922_read_raw,
0119     .write_raw = &mcp4922_write_raw,
0120 };
0121 
0122 static int mcp4922_probe(struct spi_device *spi)
0123 {
0124     struct iio_dev *indio_dev;
0125     struct mcp4922_state *state;
0126     const struct spi_device_id *id;
0127     int ret;
0128 
0129     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
0130     if (indio_dev == NULL)
0131         return -ENOMEM;
0132 
0133     state = iio_priv(indio_dev);
0134     state->spi = spi;
0135     state->vref_reg = devm_regulator_get(&spi->dev, "vref");
0136     if (IS_ERR(state->vref_reg))
0137         return dev_err_probe(&spi->dev, PTR_ERR(state->vref_reg),
0138                      "Vref regulator not specified\n");
0139 
0140     ret = regulator_enable(state->vref_reg);
0141     if (ret) {
0142         dev_err(&spi->dev, "Failed to enable vref regulator: %d\n",
0143                 ret);
0144         return ret;
0145     }
0146 
0147     ret = regulator_get_voltage(state->vref_reg);
0148     if (ret < 0) {
0149         dev_err(&spi->dev, "Failed to read vref regulator: %d\n",
0150                 ret);
0151         goto error_disable_reg;
0152     }
0153     state->vref_mv = ret / 1000;
0154 
0155     spi_set_drvdata(spi, indio_dev);
0156     id = spi_get_device_id(spi);
0157     indio_dev->info = &mcp4922_info;
0158     indio_dev->modes = INDIO_DIRECT_MODE;
0159     indio_dev->channels = mcp4922_channels[id->driver_data];
0160     if (id->driver_data == ID_MCP4921)
0161         indio_dev->num_channels = MCP4921_NUM_CHANNELS;
0162     else
0163         indio_dev->num_channels = MCP4922_NUM_CHANNELS;
0164     indio_dev->name = id->name;
0165 
0166     ret = iio_device_register(indio_dev);
0167     if (ret) {
0168         dev_err(&spi->dev, "Failed to register iio device: %d\n",
0169                 ret);
0170         goto error_disable_reg;
0171     }
0172 
0173     return 0;
0174 
0175 error_disable_reg:
0176     regulator_disable(state->vref_reg);
0177 
0178     return ret;
0179 }
0180 
0181 static void mcp4922_remove(struct spi_device *spi)
0182 {
0183     struct iio_dev *indio_dev = spi_get_drvdata(spi);
0184     struct mcp4922_state *state;
0185 
0186     iio_device_unregister(indio_dev);
0187     state = iio_priv(indio_dev);
0188     regulator_disable(state->vref_reg);
0189 }
0190 
0191 static const struct spi_device_id mcp4922_id[] = {
0192     {"mcp4902", ID_MCP4902},
0193     {"mcp4912", ID_MCP4912},
0194     {"mcp4921", ID_MCP4921},
0195     {"mcp4922", ID_MCP4922},
0196     {}
0197 };
0198 MODULE_DEVICE_TABLE(spi, mcp4922_id);
0199 
0200 static struct spi_driver mcp4922_driver = {
0201     .driver = {
0202            .name = "mcp4922",
0203            },
0204     .probe = mcp4922_probe,
0205     .remove = mcp4922_remove,
0206     .id_table = mcp4922_id,
0207 };
0208 module_spi_driver(mcp4922_driver);
0209 
0210 MODULE_AUTHOR("Michael Welling <mwelling@ieee.org>");
0211 MODULE_DESCRIPTION("Microchip MCP4902, MCP4912, MCP4922 DAC");
0212 MODULE_LICENSE("GPL v2");