1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * IIO driver for the Measurement Computing CIO-DAC |
4 | * Copyright (C) 2016 William Breathitt Gray |
5 | * |
6 | * This driver supports the following Measurement Computing devices: CIO-DAC16, |
7 | * CIO-DAC08, and PC104-DAC06. |
8 | */ |
9 | #include <linux/bits.h> |
10 | #include <linux/device.h> |
11 | #include <linux/err.h> |
12 | #include <linux/iio/iio.h> |
13 | #include <linux/iio/types.h> |
14 | #include <linux/isa.h> |
15 | #include <linux/module.h> |
16 | #include <linux/moduleparam.h> |
17 | #include <linux/regmap.h> |
18 | #include <linux/types.h> |
19 | |
20 | #define CIO_DAC_NUM_CHAN 16 |
21 | |
22 | #define CIO_DAC_CHAN(chan) { \ |
23 | .type = IIO_VOLTAGE, \ |
24 | .channel = chan, \ |
25 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
26 | .indexed = 1, \ |
27 | .output = 1 \ |
28 | } |
29 | |
30 | #define CIO_DAC_EXTENT 32 |
31 | |
32 | static unsigned int base[max_num_isa_dev(CIO_DAC_EXTENT)]; |
33 | static unsigned int num_cio_dac; |
34 | module_param_hw_array(base, uint, ioport, &num_cio_dac, 0); |
35 | MODULE_PARM_DESC(base, "Measurement Computing CIO-DAC base addresses" ); |
36 | |
37 | #define CIO_DAC_BASE 0x00 |
38 | #define CIO_DAC_CHANNEL_STRIDE 2 |
39 | |
40 | static bool cio_dac_precious_reg(struct device *dev, unsigned int reg) |
41 | { |
42 | /* |
43 | * All registers are considered precious; if the XFER jumper is set on |
44 | * the device, then no update occurs until a DAC register is read. |
45 | */ |
46 | return true; |
47 | } |
48 | |
49 | static const struct regmap_config cio_dac_regmap_config = { |
50 | .reg_bits = 16, |
51 | .reg_stride = 2, |
52 | .val_bits = 16, |
53 | .io_port = true, |
54 | .max_register = 0x1F, |
55 | .precious_reg = cio_dac_precious_reg, |
56 | }; |
57 | |
58 | /** |
59 | * struct cio_dac_iio - IIO device private data structure |
60 | * @map: Regmap for the device |
61 | */ |
62 | struct cio_dac_iio { |
63 | struct regmap *map; |
64 | }; |
65 | |
66 | static int cio_dac_read_raw(struct iio_dev *indio_dev, |
67 | struct iio_chan_spec const *chan, int *val, int *val2, long mask) |
68 | { |
69 | struct cio_dac_iio *const priv = iio_priv(indio_dev); |
70 | const unsigned int offset = chan->channel * CIO_DAC_CHANNEL_STRIDE; |
71 | int err; |
72 | unsigned int dac_val; |
73 | |
74 | if (mask != IIO_CHAN_INFO_RAW) |
75 | return -EINVAL; |
76 | |
77 | err = regmap_read(map: priv->map, CIO_DAC_BASE + offset, val: &dac_val); |
78 | if (err) |
79 | return err; |
80 | |
81 | *val = dac_val; |
82 | |
83 | return IIO_VAL_INT; |
84 | } |
85 | |
86 | static int cio_dac_write_raw(struct iio_dev *indio_dev, |
87 | struct iio_chan_spec const *chan, int val, int val2, long mask) |
88 | { |
89 | struct cio_dac_iio *const priv = iio_priv(indio_dev); |
90 | const unsigned int offset = chan->channel * CIO_DAC_CHANNEL_STRIDE; |
91 | |
92 | if (mask != IIO_CHAN_INFO_RAW) |
93 | return -EINVAL; |
94 | |
95 | /* DAC can only accept up to a 12-bit value */ |
96 | if ((unsigned int)val > 4095) |
97 | return -EINVAL; |
98 | |
99 | return regmap_write(map: priv->map, CIO_DAC_BASE + offset, val); |
100 | } |
101 | |
102 | static const struct iio_info cio_dac_info = { |
103 | .read_raw = cio_dac_read_raw, |
104 | .write_raw = cio_dac_write_raw |
105 | }; |
106 | |
107 | static const struct iio_chan_spec cio_dac_channels[CIO_DAC_NUM_CHAN] = { |
108 | CIO_DAC_CHAN(0), CIO_DAC_CHAN(1), CIO_DAC_CHAN(2), CIO_DAC_CHAN(3), |
109 | CIO_DAC_CHAN(4), CIO_DAC_CHAN(5), CIO_DAC_CHAN(6), CIO_DAC_CHAN(7), |
110 | CIO_DAC_CHAN(8), CIO_DAC_CHAN(9), CIO_DAC_CHAN(10), CIO_DAC_CHAN(11), |
111 | CIO_DAC_CHAN(12), CIO_DAC_CHAN(13), CIO_DAC_CHAN(14), CIO_DAC_CHAN(15) |
112 | }; |
113 | |
114 | static int cio_dac_probe(struct device *dev, unsigned int id) |
115 | { |
116 | struct iio_dev *indio_dev; |
117 | struct cio_dac_iio *priv; |
118 | void __iomem *regs; |
119 | |
120 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*priv)); |
121 | if (!indio_dev) |
122 | return -ENOMEM; |
123 | |
124 | if (!devm_request_region(dev, base[id], CIO_DAC_EXTENT, |
125 | dev_name(dev))) { |
126 | dev_err(dev, "Unable to request port addresses (0x%X-0x%X)\n" , |
127 | base[id], base[id] + CIO_DAC_EXTENT); |
128 | return -EBUSY; |
129 | } |
130 | |
131 | regs = devm_ioport_map(dev, port: base[id], CIO_DAC_EXTENT); |
132 | if (!regs) |
133 | return -ENOMEM; |
134 | |
135 | priv = iio_priv(indio_dev); |
136 | priv->map = devm_regmap_init_mmio(dev, regs, &cio_dac_regmap_config); |
137 | if (IS_ERR(ptr: priv->map)) |
138 | return dev_err_probe(dev, err: PTR_ERR(ptr: priv->map), |
139 | fmt: "Unable to initialize register map\n" ); |
140 | |
141 | indio_dev->info = &cio_dac_info; |
142 | indio_dev->modes = INDIO_DIRECT_MODE; |
143 | indio_dev->channels = cio_dac_channels; |
144 | indio_dev->num_channels = CIO_DAC_NUM_CHAN; |
145 | indio_dev->name = dev_name(dev); |
146 | |
147 | return devm_iio_device_register(dev, indio_dev); |
148 | } |
149 | |
150 | static struct isa_driver cio_dac_driver = { |
151 | .probe = cio_dac_probe, |
152 | .driver = { |
153 | .name = "cio-dac" |
154 | } |
155 | }; |
156 | |
157 | module_isa_driver(cio_dac_driver, num_cio_dac); |
158 | |
159 | MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>" ); |
160 | MODULE_DESCRIPTION("Measurement Computing CIO-DAC IIO driver" ); |
161 | MODULE_LICENSE("GPL v2" ); |
162 | |