1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * IIO driver for the Apex Embedded Systems STX104 4 * Copyright (C) 2016 William Breathitt Gray 5 */ 6#include <linux/bitops.h> 7#include <linux/device.h> 8#include <linux/errno.h> 9#include <linux/gpio/driver.h> 10#include <linux/iio/iio.h> 11#include <linux/iio/types.h> 12#include <linux/io.h> 13#include <linux/ioport.h> 14#include <linux/isa.h> 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/moduleparam.h> 18#include <linux/mutex.h> 19#include <linux/spinlock.h> 20#include <linux/types.h> 21 22#define STX104_OUT_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#define STX104_IN_CHAN(chan, diff) { \ 30 .type = IIO_VOLTAGE, \ 31 .channel = chan, \ 32 .channel2 = chan, \ 33 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ 34 BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), \ 35 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 36 .indexed = 1, \ 37 .differential = diff \ 38} 39 40#define STX104_NUM_OUT_CHAN 2 41 42#define STX104_EXTENT 16 43 44static unsigned int base[max_num_isa_dev(STX104_EXTENT)]; 45static unsigned int num_stx104; 46module_param_hw_array(base, uint, ioport, &num_stx104, 0); 47MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses"); 48 49/** 50 * struct stx104_reg - device register structure 51 * @ssr_ad: Software Strobe Register and ADC Data 52 * @achan: ADC Channel 53 * @dio: Digital I/O 54 * @dac: DAC Channels 55 * @cir_asr: Clear Interrupts and ADC Status 56 * @acr: ADC Control 57 * @pccr_fsh: Pacer Clock Control and FIFO Status MSB 58 * @acfg: ADC Configuration 59 */ 60struct stx104_reg { 61 u16 ssr_ad; 62 u8 achan; 63 u8 dio; 64 u16 dac[2]; 65 u8 cir_asr; 66 u8 acr; 67 u8 pccr_fsh; 68 u8 acfg; 69}; 70 71/** 72 * struct stx104_iio - IIO device private data structure 73 * @lock: synchronization lock to prevent I/O race conditions 74 * @chan_out_states: channels' output states 75 * @reg: I/O address offset for the device registers 76 */ 77struct stx104_iio { 78 struct mutex lock; 79 unsigned int chan_out_states[STX104_NUM_OUT_CHAN]; 80 struct stx104_reg __iomem *reg; 81}; 82 83/** 84 * struct stx104_gpio - GPIO device private data structure 85 * @chip: instance of the gpio_chip 86 * @lock: synchronization lock to prevent I/O race conditions 87 * @base: base port address of the GPIO device 88 * @out_state: output bits state 89 */ 90struct stx104_gpio { 91 struct gpio_chip chip; 92 spinlock_t lock; 93 u8 __iomem *base; 94 unsigned int out_state; 95}; 96 97static int stx104_read_raw(struct iio_dev *indio_dev, 98 struct iio_chan_spec const *chan, int *val, int *val2, long mask) 99{ 100 struct stx104_iio *const priv = iio_priv(indio_dev); 101 struct stx104_reg __iomem *const reg = priv->reg; 102 unsigned int adc_config; 103 int adbu; 104 int gain; 105 106 switch (mask) { 107 case IIO_CHAN_INFO_HARDWAREGAIN: 108 /* get gain configuration */ 109 adc_config = ioread8(®->acfg); 110 gain = adc_config & 0x3; 111 112 *val = 1 << gain; 113 return IIO_VAL_INT; 114 case IIO_CHAN_INFO_RAW: 115 if (chan->output) { 116 *val = priv->chan_out_states[chan->channel]; 117 return IIO_VAL_INT; 118 } 119 120 mutex_lock(&priv->lock); 121 122 /* select ADC channel */ 123 iowrite8(chan->channel | (chan->channel << 4), ®->achan); 124 125 /* trigger ADC sample capture by writing to the 8-bit 126 * Software Strobe Register and wait for completion 127 */ 128 iowrite8(0, ®->ssr_ad); 129 while (ioread8(®->cir_asr) & BIT(7)); 130 131 *val = ioread16(®->ssr_ad); 132 133 mutex_unlock(&priv->lock); 134 return IIO_VAL_INT; 135 case IIO_CHAN_INFO_OFFSET: 136 /* get ADC bipolar/unipolar configuration */ 137 adc_config = ioread8(®->acfg); 138 adbu = !(adc_config & BIT(2)); 139 140 *val = -32768 * adbu; 141 return IIO_VAL_INT; 142 case IIO_CHAN_INFO_SCALE: 143 /* get ADC bipolar/unipolar and gain configuration */ 144 adc_config = ioread8(®->acfg); 145 adbu = !(adc_config & BIT(2)); 146 gain = adc_config & 0x3; 147 148 *val = 5; 149 *val2 = 15 - adbu + gain; 150 return IIO_VAL_FRACTIONAL_LOG2; 151 } 152 153 return -EINVAL; 154} 155 156static int stx104_write_raw(struct iio_dev *indio_dev, 157 struct iio_chan_spec const *chan, int val, int val2, long mask) 158{ 159 struct stx104_iio *const priv = iio_priv(indio_dev); 160 161 switch (mask) { 162 case IIO_CHAN_INFO_HARDWAREGAIN: 163 /* Only four gain states (x1, x2, x4, x8) */ 164 switch (val) { 165 case 1: 166 iowrite8(0, &priv->reg->acfg); 167 break; 168 case 2: 169 iowrite8(1, &priv->reg->acfg); 170 break; 171 case 4: 172 iowrite8(2, &priv->reg->acfg); 173 break; 174 case 8: 175 iowrite8(3, &priv->reg->acfg); 176 break; 177 default: 178 return -EINVAL; 179 } 180 181 return 0; 182 case IIO_CHAN_INFO_RAW: 183 if (chan->output) { 184 /* DAC can only accept up to a 16-bit value */ 185 if ((unsigned int)val > 65535) 186 return -EINVAL; 187 188 mutex_lock(&priv->lock); 189 190 priv->chan_out_states[chan->channel] = val; 191 iowrite16(val, &priv->reg->dac[chan->channel]); 192 193 mutex_unlock(&priv->lock); 194 return 0; 195 } 196 return -EINVAL; 197 } 198 199 return -EINVAL; 200} 201 202static const struct iio_info stx104_info = { 203 .read_raw = stx104_read_raw, 204 .write_raw = stx104_write_raw 205}; 206 207/* single-ended input channels configuration */ 208static const struct iio_chan_spec stx104_channels_sing[] = { 209 STX104_OUT_CHAN(0), STX104_OUT_CHAN(1), 210 STX104_IN_CHAN(0, 0), STX104_IN_CHAN(1, 0), STX104_IN_CHAN(2, 0), 211 STX104_IN_CHAN(3, 0), STX104_IN_CHAN(4, 0), STX104_IN_CHAN(5, 0), 212 STX104_IN_CHAN(6, 0), STX104_IN_CHAN(7, 0), STX104_IN_CHAN(8, 0), 213 STX104_IN_CHAN(9, 0), STX104_IN_CHAN(10, 0), STX104_IN_CHAN(11, 0), 214 STX104_IN_CHAN(12, 0), STX104_IN_CHAN(13, 0), STX104_IN_CHAN(14, 0), 215 STX104_IN_CHAN(15, 0) 216}; 217/* differential input channels configuration */ 218static const struct iio_chan_spec stx104_channels_diff[] = { 219 STX104_OUT_CHAN(0), STX104_OUT_CHAN(1), 220 STX104_IN_CHAN(0, 1), STX104_IN_CHAN(1, 1), STX104_IN_CHAN(2, 1), 221 STX104_IN_CHAN(3, 1), STX104_IN_CHAN(4, 1), STX104_IN_CHAN(5, 1), 222 STX104_IN_CHAN(6, 1), STX104_IN_CHAN(7, 1) 223}; 224 225static int stx104_gpio_get_direction(struct gpio_chip *chip, 226 unsigned int offset) 227{ 228 /* GPIO 0-3 are input only, while the rest are output only */ 229 if (offset < 4) 230 return 1; 231 232 return 0; 233} 234 235static int stx104_gpio_direction_input(struct gpio_chip *chip, 236 unsigned int offset) 237{ 238 if (offset >= 4) 239 return -EINVAL; 240 241 return 0; 242} 243 244static int stx104_gpio_direction_output(struct gpio_chip *chip, 245 unsigned int offset, int value) 246{ 247 if (offset < 4) 248 return -EINVAL; 249 250 chip->set(chip, offset, value); 251 return 0; 252} 253 254static int stx104_gpio_get(struct gpio_chip *chip, unsigned int offset) 255{ 256 struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); 257 258 if (offset >= 4) 259 return -EINVAL; 260 261 return !!(ioread8(stx104gpio->base) & BIT(offset)); 262} 263 264static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, 265 unsigned long *bits) 266{ 267 struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); 268 269 *bits = ioread8(stx104gpio->base); 270 271 return 0; 272} 273 274static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset, 275 int value) 276{ 277 struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); 278 const unsigned int mask = BIT(offset) >> 4; 279 unsigned long flags; 280 281 if (offset < 4) 282 return; 283 284 spin_lock_irqsave(&stx104gpio->lock, flags); 285 286 if (value) 287 stx104gpio->out_state |= mask; 288 else 289 stx104gpio->out_state &= ~mask; 290 291 iowrite8(stx104gpio->out_state, stx104gpio->base); 292 293 spin_unlock_irqrestore(&stx104gpio->lock, flags); 294} 295 296#define STX104_NGPIO 8 297static const char *stx104_names[STX104_NGPIO] = { 298 "DIN0", "DIN1", "DIN2", "DIN3", "DOUT0", "DOUT1", "DOUT2", "DOUT3" 299}; 300 301static void stx104_gpio_set_multiple(struct gpio_chip *chip, 302 unsigned long *mask, unsigned long *bits) 303{ 304 struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); 305 unsigned long flags; 306 307 /* verify masked GPIO are output */ 308 if (!(*mask & 0xF0)) 309 return; 310 311 *mask >>= 4; 312 *bits >>= 4; 313 314 spin_lock_irqsave(&stx104gpio->lock, flags); 315 316 stx104gpio->out_state &= ~*mask; 317 stx104gpio->out_state |= *mask & *bits; 318 iowrite8(stx104gpio->out_state, stx104gpio->base); 319 320 spin_unlock_irqrestore(&stx104gpio->lock, flags); 321} 322 323static int stx104_probe(struct device *dev, unsigned int id) 324{ 325 struct iio_dev *indio_dev; 326 struct stx104_iio *priv; 327 struct stx104_gpio *stx104gpio; 328 int err; 329 330 indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); 331 if (!indio_dev) 332 return -ENOMEM; 333 334 stx104gpio = devm_kzalloc(dev, sizeof(*stx104gpio), GFP_KERNEL); 335 if (!stx104gpio) 336 return -ENOMEM; 337 338 if (!devm_request_region(dev, base[id], STX104_EXTENT, 339 dev_name(dev))) { 340 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", 341 base[id], base[id] + STX104_EXTENT); 342 return -EBUSY; 343 } 344 345 priv = iio_priv(indio_dev); 346 priv->reg = devm_ioport_map(dev, base[id], STX104_EXTENT); 347 if (!priv->reg) 348 return -ENOMEM; 349 350 indio_dev->info = &stx104_info; 351 indio_dev->modes = INDIO_DIRECT_MODE; 352 353 /* determine if differential inputs */ 354 if (ioread8(&priv->reg->cir_asr) & BIT(5)) { 355 indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff); 356 indio_dev->channels = stx104_channels_diff; 357 } else { 358 indio_dev->num_channels = ARRAY_SIZE(stx104_channels_sing); 359 indio_dev->channels = stx104_channels_sing; 360 } 361 362 indio_dev->name = dev_name(dev); 363 364 mutex_init(&priv->lock); 365 366 /* configure device for software trigger operation */ 367 iowrite8(0, &priv->reg->acr); 368 369 /* initialize gain setting to x1 */ 370 iowrite8(0, &priv->reg->acfg); 371 372 /* initialize DAC output to 0V */ 373 iowrite16(0, &priv->reg->dac[0]); 374 iowrite16(0, &priv->reg->dac[1]); 375 376 stx104gpio->chip.label = dev_name(dev); 377 stx104gpio->chip.parent = dev; 378 stx104gpio->chip.owner = THIS_MODULE; 379 stx104gpio->chip.base = -1; 380 stx104gpio->chip.ngpio = STX104_NGPIO; 381 stx104gpio->chip.names = stx104_names; 382 stx104gpio->chip.get_direction = stx104_gpio_get_direction; 383 stx104gpio->chip.direction_input = stx104_gpio_direction_input; 384 stx104gpio->chip.direction_output = stx104_gpio_direction_output; 385 stx104gpio->chip.get = stx104_gpio_get; 386 stx104gpio->chip.get_multiple = stx104_gpio_get_multiple; 387 stx104gpio->chip.set = stx104_gpio_set; 388 stx104gpio->chip.set_multiple = stx104_gpio_set_multiple; 389 stx104gpio->base = &priv->reg->dio; 390 stx104gpio->out_state = 0x0; 391 392 spin_lock_init(&stx104gpio->lock); 393 394 err = devm_gpiochip_add_data(dev, &stx104gpio->chip, stx104gpio); 395 if (err) { 396 dev_err(dev, "GPIO registering failed (%d)\n", err); 397 return err; 398 } 399 400 return devm_iio_device_register(dev, indio_dev); 401} 402 403static struct isa_driver stx104_driver = { 404 .probe = stx104_probe, 405 .driver = { 406 .name = "stx104" 407 }, 408}; 409 410module_isa_driver(stx104_driver, num_stx104); 411 412MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 413MODULE_DESCRIPTION("Apex Embedded Systems STX104 IIO driver"); 414MODULE_LICENSE("GPL v2"); 415