102b829f9SMaxime Roussin-Belanger /* 202b829f9SMaxime Roussin-Belanger * LTC2632 Digital to analog convertors spi driver 302b829f9SMaxime Roussin-Belanger * 402b829f9SMaxime Roussin-Belanger * Copyright 2017 Maxime Roussin-B�langer 5*9ff1d500SSilvan Murer * expanded by Silvan Murer <silvan.murer@gmail.com> 602b829f9SMaxime Roussin-Belanger * 702b829f9SMaxime Roussin-Belanger * Licensed under the GPL-2. 802b829f9SMaxime Roussin-Belanger */ 902b829f9SMaxime Roussin-Belanger 1002b829f9SMaxime Roussin-Belanger #include <linux/device.h> 1102b829f9SMaxime Roussin-Belanger #include <linux/spi/spi.h> 1202b829f9SMaxime Roussin-Belanger #include <linux/module.h> 1302b829f9SMaxime Roussin-Belanger #include <linux/iio/iio.h> 14*9ff1d500SSilvan Murer #include <linux/regulator/consumer.h> 1502b829f9SMaxime Roussin-Belanger 1602b829f9SMaxime Roussin-Belanger #define LTC2632_DAC_CHANNELS 2 1702b829f9SMaxime Roussin-Belanger 1802b829f9SMaxime Roussin-Belanger #define LTC2632_ADDR_DAC0 0x0 1902b829f9SMaxime Roussin-Belanger #define LTC2632_ADDR_DAC1 0x1 2002b829f9SMaxime Roussin-Belanger 2102b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_WRITE_INPUT_N 0x0 2202b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_UPDATE_DAC_N 0x1 2302b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 2402b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_WRITE_INPUT_N_UPDATE_N 0x3 2502b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_POWERDOWN_DAC_N 0x4 2602b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_POWERDOWN_CHIP 0x5 2702b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_INTERNAL_REFER 0x6 2802b829f9SMaxime Roussin-Belanger #define LTC2632_CMD_EXTERNAL_REFER 0x7 2902b829f9SMaxime Roussin-Belanger 3002b829f9SMaxime Roussin-Belanger /** 3102b829f9SMaxime Roussin-Belanger * struct ltc2632_chip_info - chip specific information 3202b829f9SMaxime Roussin-Belanger * @channels: channel spec for the DAC 33*9ff1d500SSilvan Murer * @vref_mv: internal reference voltage 3402b829f9SMaxime Roussin-Belanger */ 3502b829f9SMaxime Roussin-Belanger struct ltc2632_chip_info { 3602b829f9SMaxime Roussin-Belanger const struct iio_chan_spec *channels; 3702b829f9SMaxime Roussin-Belanger const int vref_mv; 3802b829f9SMaxime Roussin-Belanger }; 3902b829f9SMaxime Roussin-Belanger 4002b829f9SMaxime Roussin-Belanger /** 4102b829f9SMaxime Roussin-Belanger * struct ltc2632_state - driver instance specific data 4202b829f9SMaxime Roussin-Belanger * @spi_dev: pointer to the spi_device struct 4302b829f9SMaxime Roussin-Belanger * @powerdown_cache_mask used to show current channel powerdown state 44*9ff1d500SSilvan Murer * @vref_mv used reference voltage (internal or external) 45*9ff1d500SSilvan Murer * @vref_reg regulator for the reference voltage 4602b829f9SMaxime Roussin-Belanger */ 4702b829f9SMaxime Roussin-Belanger struct ltc2632_state { 4802b829f9SMaxime Roussin-Belanger struct spi_device *spi_dev; 4902b829f9SMaxime Roussin-Belanger unsigned int powerdown_cache_mask; 50*9ff1d500SSilvan Murer int vref_mv; 51*9ff1d500SSilvan Murer struct regulator *vref_reg; 5202b829f9SMaxime Roussin-Belanger }; 5302b829f9SMaxime Roussin-Belanger 5402b829f9SMaxime Roussin-Belanger enum ltc2632_supported_device_ids { 5502b829f9SMaxime Roussin-Belanger ID_LTC2632L12, 5602b829f9SMaxime Roussin-Belanger ID_LTC2632L10, 5702b829f9SMaxime Roussin-Belanger ID_LTC2632L8, 5802b829f9SMaxime Roussin-Belanger ID_LTC2632H12, 5902b829f9SMaxime Roussin-Belanger ID_LTC2632H10, 6002b829f9SMaxime Roussin-Belanger ID_LTC2632H8, 6102b829f9SMaxime Roussin-Belanger }; 6202b829f9SMaxime Roussin-Belanger 6302b829f9SMaxime Roussin-Belanger static int ltc2632_spi_write(struct spi_device *spi, 6402b829f9SMaxime Roussin-Belanger u8 cmd, u8 addr, u16 val, u8 shift) 6502b829f9SMaxime Roussin-Belanger { 6602b829f9SMaxime Roussin-Belanger u32 data; 6702b829f9SMaxime Roussin-Belanger u8 msg[3]; 6802b829f9SMaxime Roussin-Belanger 6902b829f9SMaxime Roussin-Belanger /* 7002b829f9SMaxime Roussin-Belanger * The input shift register is 24 bits wide. 7102b829f9SMaxime Roussin-Belanger * The next four are the command bits, C3 to C0, 7202b829f9SMaxime Roussin-Belanger * followed by the 4-bit DAC address, A3 to A0, and then the 7302b829f9SMaxime Roussin-Belanger * 12-, 10-, 8-bit data-word. The data-word comprises the 12-, 7402b829f9SMaxime Roussin-Belanger * 10-, 8-bit input code followed by 4, 6, or 8 don't care bits. 7502b829f9SMaxime Roussin-Belanger */ 7602b829f9SMaxime Roussin-Belanger data = (cmd << 20) | (addr << 16) | (val << shift); 7702b829f9SMaxime Roussin-Belanger msg[0] = data >> 16; 7802b829f9SMaxime Roussin-Belanger msg[1] = data >> 8; 7902b829f9SMaxime Roussin-Belanger msg[2] = data; 8002b829f9SMaxime Roussin-Belanger 8102b829f9SMaxime Roussin-Belanger return spi_write(spi, msg, sizeof(msg)); 8202b829f9SMaxime Roussin-Belanger } 8302b829f9SMaxime Roussin-Belanger 8402b829f9SMaxime Roussin-Belanger static int ltc2632_read_raw(struct iio_dev *indio_dev, 8502b829f9SMaxime Roussin-Belanger struct iio_chan_spec const *chan, 8602b829f9SMaxime Roussin-Belanger int *val, 8702b829f9SMaxime Roussin-Belanger int *val2, 8802b829f9SMaxime Roussin-Belanger long m) 8902b829f9SMaxime Roussin-Belanger { 9002b829f9SMaxime Roussin-Belanger struct ltc2632_chip_info *chip_info; 9102b829f9SMaxime Roussin-Belanger 9202b829f9SMaxime Roussin-Belanger const struct ltc2632_state *st = iio_priv(indio_dev); 9302b829f9SMaxime Roussin-Belanger const struct spi_device_id *spi_dev_id = spi_get_device_id(st->spi_dev); 9402b829f9SMaxime Roussin-Belanger 9502b829f9SMaxime Roussin-Belanger chip_info = (struct ltc2632_chip_info *)spi_dev_id->driver_data; 9602b829f9SMaxime Roussin-Belanger 9702b829f9SMaxime Roussin-Belanger switch (m) { 9802b829f9SMaxime Roussin-Belanger case IIO_CHAN_INFO_SCALE: 99*9ff1d500SSilvan Murer *val = st->vref_mv; 10002b829f9SMaxime Roussin-Belanger *val2 = chan->scan_type.realbits; 10102b829f9SMaxime Roussin-Belanger return IIO_VAL_FRACTIONAL_LOG2; 10202b829f9SMaxime Roussin-Belanger } 10302b829f9SMaxime Roussin-Belanger return -EINVAL; 10402b829f9SMaxime Roussin-Belanger } 10502b829f9SMaxime Roussin-Belanger 10602b829f9SMaxime Roussin-Belanger static int ltc2632_write_raw(struct iio_dev *indio_dev, 10702b829f9SMaxime Roussin-Belanger struct iio_chan_spec const *chan, 10802b829f9SMaxime Roussin-Belanger int val, 10902b829f9SMaxime Roussin-Belanger int val2, 11002b829f9SMaxime Roussin-Belanger long mask) 11102b829f9SMaxime Roussin-Belanger { 11202b829f9SMaxime Roussin-Belanger struct ltc2632_state *st = iio_priv(indio_dev); 11302b829f9SMaxime Roussin-Belanger 11402b829f9SMaxime Roussin-Belanger switch (mask) { 11502b829f9SMaxime Roussin-Belanger case IIO_CHAN_INFO_RAW: 11602b829f9SMaxime Roussin-Belanger if (val >= (1 << chan->scan_type.realbits) || val < 0) 11702b829f9SMaxime Roussin-Belanger return -EINVAL; 11802b829f9SMaxime Roussin-Belanger 11902b829f9SMaxime Roussin-Belanger return ltc2632_spi_write(st->spi_dev, 12002b829f9SMaxime Roussin-Belanger LTC2632_CMD_WRITE_INPUT_N_UPDATE_N, 12102b829f9SMaxime Roussin-Belanger chan->address, val, 12202b829f9SMaxime Roussin-Belanger chan->scan_type.shift); 12302b829f9SMaxime Roussin-Belanger default: 12402b829f9SMaxime Roussin-Belanger return -EINVAL; 12502b829f9SMaxime Roussin-Belanger } 12602b829f9SMaxime Roussin-Belanger } 12702b829f9SMaxime Roussin-Belanger 12802b829f9SMaxime Roussin-Belanger static ssize_t ltc2632_read_dac_powerdown(struct iio_dev *indio_dev, 12902b829f9SMaxime Roussin-Belanger uintptr_t private, 13002b829f9SMaxime Roussin-Belanger const struct iio_chan_spec *chan, 13102b829f9SMaxime Roussin-Belanger char *buf) 13202b829f9SMaxime Roussin-Belanger { 13302b829f9SMaxime Roussin-Belanger struct ltc2632_state *st = iio_priv(indio_dev); 13402b829f9SMaxime Roussin-Belanger 13502b829f9SMaxime Roussin-Belanger return sprintf(buf, "%d\n", 13602b829f9SMaxime Roussin-Belanger !!(st->powerdown_cache_mask & (1 << chan->channel))); 13702b829f9SMaxime Roussin-Belanger } 13802b829f9SMaxime Roussin-Belanger 13902b829f9SMaxime Roussin-Belanger static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev, 14002b829f9SMaxime Roussin-Belanger uintptr_t private, 14102b829f9SMaxime Roussin-Belanger const struct iio_chan_spec *chan, 14202b829f9SMaxime Roussin-Belanger const char *buf, 14302b829f9SMaxime Roussin-Belanger size_t len) 14402b829f9SMaxime Roussin-Belanger { 14502b829f9SMaxime Roussin-Belanger bool pwr_down; 14602b829f9SMaxime Roussin-Belanger int ret; 14702b829f9SMaxime Roussin-Belanger struct ltc2632_state *st = iio_priv(indio_dev); 14802b829f9SMaxime Roussin-Belanger 14902b829f9SMaxime Roussin-Belanger ret = strtobool(buf, &pwr_down); 15002b829f9SMaxime Roussin-Belanger if (ret) 15102b829f9SMaxime Roussin-Belanger return ret; 15202b829f9SMaxime Roussin-Belanger 15302b829f9SMaxime Roussin-Belanger if (pwr_down) 15402b829f9SMaxime Roussin-Belanger st->powerdown_cache_mask |= (1 << chan->channel); 15502b829f9SMaxime Roussin-Belanger else 15602b829f9SMaxime Roussin-Belanger st->powerdown_cache_mask &= ~(1 << chan->channel); 15702b829f9SMaxime Roussin-Belanger 15802b829f9SMaxime Roussin-Belanger ret = ltc2632_spi_write(st->spi_dev, 15902b829f9SMaxime Roussin-Belanger LTC2632_CMD_POWERDOWN_DAC_N, 16002b829f9SMaxime Roussin-Belanger chan->channel, 0, 0); 16102b829f9SMaxime Roussin-Belanger 16202b829f9SMaxime Roussin-Belanger return ret ? ret : len; 16302b829f9SMaxime Roussin-Belanger } 16402b829f9SMaxime Roussin-Belanger 16502b829f9SMaxime Roussin-Belanger static const struct iio_info ltc2632_info = { 16602b829f9SMaxime Roussin-Belanger .write_raw = ltc2632_write_raw, 16702b829f9SMaxime Roussin-Belanger .read_raw = ltc2632_read_raw, 16802b829f9SMaxime Roussin-Belanger }; 16902b829f9SMaxime Roussin-Belanger 17002b829f9SMaxime Roussin-Belanger static const struct iio_chan_spec_ext_info ltc2632_ext_info[] = { 17102b829f9SMaxime Roussin-Belanger { 17202b829f9SMaxime Roussin-Belanger .name = "powerdown", 17302b829f9SMaxime Roussin-Belanger .read = ltc2632_read_dac_powerdown, 17402b829f9SMaxime Roussin-Belanger .write = ltc2632_write_dac_powerdown, 17502b829f9SMaxime Roussin-Belanger .shared = IIO_SEPARATE, 17602b829f9SMaxime Roussin-Belanger }, 17702b829f9SMaxime Roussin-Belanger { }, 17802b829f9SMaxime Roussin-Belanger }; 17902b829f9SMaxime Roussin-Belanger 18002b829f9SMaxime Roussin-Belanger #define LTC2632_CHANNEL(_chan, _bits) { \ 18102b829f9SMaxime Roussin-Belanger .type = IIO_VOLTAGE, \ 18202b829f9SMaxime Roussin-Belanger .indexed = 1, \ 18302b829f9SMaxime Roussin-Belanger .output = 1, \ 18402b829f9SMaxime Roussin-Belanger .channel = (_chan), \ 18502b829f9SMaxime Roussin-Belanger .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 18602b829f9SMaxime Roussin-Belanger .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 18702b829f9SMaxime Roussin-Belanger .address = (_chan), \ 18802b829f9SMaxime Roussin-Belanger .scan_type = { \ 18902b829f9SMaxime Roussin-Belanger .realbits = (_bits), \ 19002b829f9SMaxime Roussin-Belanger .shift = 16 - (_bits), \ 19102b829f9SMaxime Roussin-Belanger }, \ 19202b829f9SMaxime Roussin-Belanger .ext_info = ltc2632_ext_info, \ 19302b829f9SMaxime Roussin-Belanger } 19402b829f9SMaxime Roussin-Belanger 19502b829f9SMaxime Roussin-Belanger #define DECLARE_LTC2632_CHANNELS(_name, _bits) \ 19602b829f9SMaxime Roussin-Belanger const struct iio_chan_spec _name ## _channels[] = { \ 19702b829f9SMaxime Roussin-Belanger LTC2632_CHANNEL(0, _bits), \ 19802b829f9SMaxime Roussin-Belanger LTC2632_CHANNEL(1, _bits), \ 19902b829f9SMaxime Roussin-Belanger } 20002b829f9SMaxime Roussin-Belanger 20102b829f9SMaxime Roussin-Belanger static DECLARE_LTC2632_CHANNELS(ltc2632l12, 12); 20202b829f9SMaxime Roussin-Belanger static DECLARE_LTC2632_CHANNELS(ltc2632l10, 10); 20302b829f9SMaxime Roussin-Belanger static DECLARE_LTC2632_CHANNELS(ltc2632l8, 8); 20402b829f9SMaxime Roussin-Belanger 20502b829f9SMaxime Roussin-Belanger static DECLARE_LTC2632_CHANNELS(ltc2632h12, 12); 20602b829f9SMaxime Roussin-Belanger static DECLARE_LTC2632_CHANNELS(ltc2632h10, 10); 20702b829f9SMaxime Roussin-Belanger static DECLARE_LTC2632_CHANNELS(ltc2632h8, 8); 20802b829f9SMaxime Roussin-Belanger 20902b829f9SMaxime Roussin-Belanger static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = { 21002b829f9SMaxime Roussin-Belanger [ID_LTC2632L12] = { 21102b829f9SMaxime Roussin-Belanger .channels = ltc2632l12_channels, 21202b829f9SMaxime Roussin-Belanger .vref_mv = 2500, 21302b829f9SMaxime Roussin-Belanger }, 21402b829f9SMaxime Roussin-Belanger [ID_LTC2632L10] = { 21502b829f9SMaxime Roussin-Belanger .channels = ltc2632l10_channels, 21602b829f9SMaxime Roussin-Belanger .vref_mv = 2500, 21702b829f9SMaxime Roussin-Belanger }, 21802b829f9SMaxime Roussin-Belanger [ID_LTC2632L8] = { 21902b829f9SMaxime Roussin-Belanger .channels = ltc2632l8_channels, 22002b829f9SMaxime Roussin-Belanger .vref_mv = 2500, 22102b829f9SMaxime Roussin-Belanger }, 22202b829f9SMaxime Roussin-Belanger [ID_LTC2632H12] = { 22302b829f9SMaxime Roussin-Belanger .channels = ltc2632h12_channels, 22402b829f9SMaxime Roussin-Belanger .vref_mv = 4096, 22502b829f9SMaxime Roussin-Belanger }, 22602b829f9SMaxime Roussin-Belanger [ID_LTC2632H10] = { 22702b829f9SMaxime Roussin-Belanger .channels = ltc2632h10_channels, 22802b829f9SMaxime Roussin-Belanger .vref_mv = 4096, 22902b829f9SMaxime Roussin-Belanger }, 23002b829f9SMaxime Roussin-Belanger [ID_LTC2632H8] = { 23102b829f9SMaxime Roussin-Belanger .channels = ltc2632h8_channels, 23202b829f9SMaxime Roussin-Belanger .vref_mv = 4096, 23302b829f9SMaxime Roussin-Belanger }, 23402b829f9SMaxime Roussin-Belanger }; 23502b829f9SMaxime Roussin-Belanger 23602b829f9SMaxime Roussin-Belanger static int ltc2632_probe(struct spi_device *spi) 23702b829f9SMaxime Roussin-Belanger { 23802b829f9SMaxime Roussin-Belanger struct ltc2632_state *st; 23902b829f9SMaxime Roussin-Belanger struct iio_dev *indio_dev; 24002b829f9SMaxime Roussin-Belanger struct ltc2632_chip_info *chip_info; 24102b829f9SMaxime Roussin-Belanger int ret; 24202b829f9SMaxime Roussin-Belanger 24302b829f9SMaxime Roussin-Belanger indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 24402b829f9SMaxime Roussin-Belanger if (!indio_dev) 24502b829f9SMaxime Roussin-Belanger return -ENOMEM; 24602b829f9SMaxime Roussin-Belanger 24702b829f9SMaxime Roussin-Belanger st = iio_priv(indio_dev); 24802b829f9SMaxime Roussin-Belanger 24902b829f9SMaxime Roussin-Belanger spi_set_drvdata(spi, indio_dev); 25002b829f9SMaxime Roussin-Belanger st->spi_dev = spi; 25102b829f9SMaxime Roussin-Belanger 25202b829f9SMaxime Roussin-Belanger chip_info = (struct ltc2632_chip_info *) 25302b829f9SMaxime Roussin-Belanger spi_get_device_id(spi)->driver_data; 25402b829f9SMaxime Roussin-Belanger 255*9ff1d500SSilvan Murer st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref"); 256*9ff1d500SSilvan Murer if (PTR_ERR(st->vref_reg) == -ENODEV) { 257*9ff1d500SSilvan Murer /* use internal reference voltage */ 258*9ff1d500SSilvan Murer st->vref_reg = NULL; 259*9ff1d500SSilvan Murer st->vref_mv = chip_info->vref_mv; 260*9ff1d500SSilvan Murer 261*9ff1d500SSilvan Murer ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER, 262*9ff1d500SSilvan Murer 0, 0, 0); 263*9ff1d500SSilvan Murer if (ret) { 264*9ff1d500SSilvan Murer dev_err(&spi->dev, 265*9ff1d500SSilvan Murer "Set internal reference command failed, %d\n", 266*9ff1d500SSilvan Murer ret); 267*9ff1d500SSilvan Murer return ret; 268*9ff1d500SSilvan Murer } 269*9ff1d500SSilvan Murer } else if (IS_ERR(st->vref_reg)) { 270*9ff1d500SSilvan Murer dev_err(&spi->dev, 271*9ff1d500SSilvan Murer "Error getting voltage reference regulator\n"); 272*9ff1d500SSilvan Murer return PTR_ERR(st->vref_reg); 273*9ff1d500SSilvan Murer } else { 274*9ff1d500SSilvan Murer /* use external reference voltage */ 275*9ff1d500SSilvan Murer ret = regulator_enable(st->vref_reg); 276*9ff1d500SSilvan Murer if (ret) { 277*9ff1d500SSilvan Murer dev_err(&spi->dev, 278*9ff1d500SSilvan Murer "enable reference regulator failed, %d\n", 279*9ff1d500SSilvan Murer ret); 280*9ff1d500SSilvan Murer return ret; 281*9ff1d500SSilvan Murer } 282*9ff1d500SSilvan Murer st->vref_mv = regulator_get_voltage(st->vref_reg) / 1000; 283*9ff1d500SSilvan Murer 284*9ff1d500SSilvan Murer ret = ltc2632_spi_write(spi, LTC2632_CMD_EXTERNAL_REFER, 285*9ff1d500SSilvan Murer 0, 0, 0); 286*9ff1d500SSilvan Murer if (ret) { 287*9ff1d500SSilvan Murer dev_err(&spi->dev, 288*9ff1d500SSilvan Murer "Set external reference command failed, %d\n", 289*9ff1d500SSilvan Murer ret); 290*9ff1d500SSilvan Murer return ret; 291*9ff1d500SSilvan Murer } 292*9ff1d500SSilvan Murer } 293*9ff1d500SSilvan Murer 29402b829f9SMaxime Roussin-Belanger indio_dev->dev.parent = &spi->dev; 29502b829f9SMaxime Roussin-Belanger indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name 29602b829f9SMaxime Roussin-Belanger : spi_get_device_id(spi)->name; 29702b829f9SMaxime Roussin-Belanger indio_dev->info = <c2632_info; 29802b829f9SMaxime Roussin-Belanger indio_dev->modes = INDIO_DIRECT_MODE; 29902b829f9SMaxime Roussin-Belanger indio_dev->channels = chip_info->channels; 30002b829f9SMaxime Roussin-Belanger indio_dev->num_channels = LTC2632_DAC_CHANNELS; 30102b829f9SMaxime Roussin-Belanger 302*9ff1d500SSilvan Murer return iio_device_register(indio_dev); 30302b829f9SMaxime Roussin-Belanger } 30402b829f9SMaxime Roussin-Belanger 305*9ff1d500SSilvan Murer static int ltc2632_remove(struct spi_device *spi) 306*9ff1d500SSilvan Murer { 307*9ff1d500SSilvan Murer struct iio_dev *indio_dev = spi_get_drvdata(spi); 308*9ff1d500SSilvan Murer struct ltc2632_state *st = iio_priv(indio_dev); 309*9ff1d500SSilvan Murer 310*9ff1d500SSilvan Murer iio_device_unregister(indio_dev); 311*9ff1d500SSilvan Murer 312*9ff1d500SSilvan Murer if (st->vref_reg) 313*9ff1d500SSilvan Murer regulator_disable(st->vref_reg); 314*9ff1d500SSilvan Murer 315*9ff1d500SSilvan Murer return 0; 31602b829f9SMaxime Roussin-Belanger } 31702b829f9SMaxime Roussin-Belanger 31802b829f9SMaxime Roussin-Belanger static const struct spi_device_id ltc2632_id[] = { 31902b829f9SMaxime Roussin-Belanger { "ltc2632-l12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L12] }, 32002b829f9SMaxime Roussin-Belanger { "ltc2632-l10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L10] }, 32102b829f9SMaxime Roussin-Belanger { "ltc2632-l8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L8] }, 32202b829f9SMaxime Roussin-Belanger { "ltc2632-h12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H12] }, 32302b829f9SMaxime Roussin-Belanger { "ltc2632-h10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H10] }, 32402b829f9SMaxime Roussin-Belanger { "ltc2632-h8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H8] }, 32502b829f9SMaxime Roussin-Belanger {} 32602b829f9SMaxime Roussin-Belanger }; 32702b829f9SMaxime Roussin-Belanger MODULE_DEVICE_TABLE(spi, ltc2632_id); 32802b829f9SMaxime Roussin-Belanger 32902b829f9SMaxime Roussin-Belanger static const struct of_device_id ltc2632_of_match[] = { 33002b829f9SMaxime Roussin-Belanger { 33102b829f9SMaxime Roussin-Belanger .compatible = "lltc,ltc2632-l12", 33202b829f9SMaxime Roussin-Belanger .data = <c2632_chip_info_tbl[ID_LTC2632L12] 33302b829f9SMaxime Roussin-Belanger }, { 33402b829f9SMaxime Roussin-Belanger .compatible = "lltc,ltc2632-l10", 33502b829f9SMaxime Roussin-Belanger .data = <c2632_chip_info_tbl[ID_LTC2632L10] 33602b829f9SMaxime Roussin-Belanger }, { 33702b829f9SMaxime Roussin-Belanger .compatible = "lltc,ltc2632-l8", 33802b829f9SMaxime Roussin-Belanger .data = <c2632_chip_info_tbl[ID_LTC2632L8] 33902b829f9SMaxime Roussin-Belanger }, { 34002b829f9SMaxime Roussin-Belanger .compatible = "lltc,ltc2632-h12", 34102b829f9SMaxime Roussin-Belanger .data = <c2632_chip_info_tbl[ID_LTC2632H12] 34202b829f9SMaxime Roussin-Belanger }, { 34302b829f9SMaxime Roussin-Belanger .compatible = "lltc,ltc2632-h10", 34402b829f9SMaxime Roussin-Belanger .data = <c2632_chip_info_tbl[ID_LTC2632H10] 34502b829f9SMaxime Roussin-Belanger }, { 34602b829f9SMaxime Roussin-Belanger .compatible = "lltc,ltc2632-h8", 34702b829f9SMaxime Roussin-Belanger .data = <c2632_chip_info_tbl[ID_LTC2632H8] 34802b829f9SMaxime Roussin-Belanger }, 34902b829f9SMaxime Roussin-Belanger {} 35002b829f9SMaxime Roussin-Belanger }; 35102b829f9SMaxime Roussin-Belanger MODULE_DEVICE_TABLE(of, ltc2632_of_match); 35202b829f9SMaxime Roussin-Belanger 3530f6a2165SSilvan Murer static struct spi_driver ltc2632_driver = { 3540f6a2165SSilvan Murer .driver = { 3550f6a2165SSilvan Murer .name = "ltc2632", 3560f6a2165SSilvan Murer .of_match_table = of_match_ptr(ltc2632_of_match), 3570f6a2165SSilvan Murer }, 3580f6a2165SSilvan Murer .probe = ltc2632_probe, 359*9ff1d500SSilvan Murer .remove = ltc2632_remove, 3600f6a2165SSilvan Murer .id_table = ltc2632_id, 3610f6a2165SSilvan Murer }; 3620f6a2165SSilvan Murer module_spi_driver(ltc2632_driver); 3630f6a2165SSilvan Murer 36402b829f9SMaxime Roussin-Belanger MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>"); 36502b829f9SMaxime Roussin-Belanger MODULE_DESCRIPTION("LTC2632 DAC SPI driver"); 36602b829f9SMaxime Roussin-Belanger MODULE_LICENSE("GPL v2"); 367