1 // SPDX-License-Identifier: GPL-2.0-only
3 * max5487.c - Support for MAX5487, MAX5488, MAX5489 digital potentiometers
5 * Copyright (C) 2016 Cristina-Gabriela Moraru <cristina.moraru09@gmail.com>
7 #include <linux/module.h>
8 #include <linux/spi/spi.h>
9 #include <linux/acpi.h>
11 #include <linux/iio/sysfs.h>
12 #include <linux/iio/iio.h>
14 #define MAX5487_WRITE_WIPER_A (0x01 << 8)
15 #define MAX5487_WRITE_WIPER_B (0x02 << 8)
17 /* copy both wiper regs to NV regs */
18 #define MAX5487_COPY_AB_TO_NV (0x23 << 8)
19 /* copy both NV regs to wiper regs */
20 #define MAX5487_COPY_NV_TO_AB (0x33 << 8)
22 #define MAX5487_MAX_POS 255
25 struct spi_device
*spi
;
29 #define MAX5487_CHANNEL(ch, addr) { \
30 .type = IIO_RESISTANCE, \
35 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
36 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
39 static const struct iio_chan_spec max5487_channels
[] = {
40 MAX5487_CHANNEL(0, MAX5487_WRITE_WIPER_A
),
41 MAX5487_CHANNEL(1, MAX5487_WRITE_WIPER_B
),
44 static int max5487_write_cmd(struct spi_device
*spi
, u16 cmd
)
46 return spi_write(spi
, (const void *) &cmd
, sizeof(u16
));
49 static int max5487_read_raw(struct iio_dev
*indio_dev
,
50 struct iio_chan_spec
const *chan
,
51 int *val
, int *val2
, long mask
)
53 struct max5487_data
*data
= iio_priv(indio_dev
);
55 if (mask
!= IIO_CHAN_INFO_SCALE
)
58 *val
= 1000 * data
->kohms
;
59 *val2
= MAX5487_MAX_POS
;
61 return IIO_VAL_FRACTIONAL
;
64 static int max5487_write_raw(struct iio_dev
*indio_dev
,
65 struct iio_chan_spec
const *chan
,
66 int val
, int val2
, long mask
)
68 struct max5487_data
*data
= iio_priv(indio_dev
);
70 if (mask
!= IIO_CHAN_INFO_RAW
)
73 if (val
< 0 || val
> MAX5487_MAX_POS
)
76 return max5487_write_cmd(data
->spi
, chan
->address
| val
);
79 static const struct iio_info max5487_info
= {
80 .read_raw
= max5487_read_raw
,
81 .write_raw
= max5487_write_raw
,
84 static int max5487_spi_probe(struct spi_device
*spi
)
86 struct iio_dev
*indio_dev
;
87 struct max5487_data
*data
;
88 const struct spi_device_id
*id
= spi_get_device_id(spi
);
91 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*data
));
95 dev_set_drvdata(&spi
->dev
, indio_dev
);
96 data
= iio_priv(indio_dev
);
99 data
->kohms
= id
->driver_data
;
101 indio_dev
->info
= &max5487_info
;
102 indio_dev
->name
= id
->name
;
103 indio_dev
->modes
= INDIO_DIRECT_MODE
;
104 indio_dev
->channels
= max5487_channels
;
105 indio_dev
->num_channels
= ARRAY_SIZE(max5487_channels
);
107 /* restore both wiper regs from NV regs */
108 ret
= max5487_write_cmd(data
->spi
, MAX5487_COPY_NV_TO_AB
);
112 return iio_device_register(indio_dev
);
115 static int max5487_spi_remove(struct spi_device
*spi
)
117 struct iio_dev
*indio_dev
= dev_get_drvdata(&spi
->dev
);
119 iio_device_unregister(indio_dev
);
121 /* save both wiper regs to NV regs */
122 return max5487_write_cmd(spi
, MAX5487_COPY_AB_TO_NV
);
125 static const struct spi_device_id max5487_id
[] = {
131 MODULE_DEVICE_TABLE(spi
, max5487_id
);
133 static const struct acpi_device_id max5487_acpi_match
[] = {
139 MODULE_DEVICE_TABLE(acpi
, max5487_acpi_match
);
141 static struct spi_driver max5487_driver
= {
144 .acpi_match_table
= ACPI_PTR(max5487_acpi_match
),
146 .id_table
= max5487_id
,
147 .probe
= max5487_spi_probe
,
148 .remove
= max5487_spi_remove
150 module_spi_driver(max5487_driver
);
152 MODULE_AUTHOR("Cristina-Gabriela Moraru <cristina.moraru09@gmail.com>");
153 MODULE_DESCRIPTION("max5487 SPI driver");
154 MODULE_LICENSE("GPL v2");