Lines Matching +full:sigma +full:- +full:delta

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Support code for Analog Devices Sigma-Delta ADCs
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
35 * ad_sd_set_comm() - Set communications register
37 * @sigma_delta: The sigma delta device
44 sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK; in ad_sd_set_comm()
49 * ad_sd_write_reg() - Write a register
51 * @sigma_delta: The sigma delta device
53 * @size: Size of the register (0-3)
61 uint8_t *data = sigma_delta->tx_buf; in ad_sd_write_reg()
65 .cs_change = sigma_delta->keep_cs_asserted, in ad_sd_write_reg()
70 data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm; in ad_sd_write_reg()
85 return -EINVAL; in ad_sd_write_reg()
91 if (sigma_delta->bus_locked) in ad_sd_write_reg()
92 ret = spi_sync_locked(sigma_delta->spi, &m); in ad_sd_write_reg()
94 ret = spi_sync(sigma_delta->spi, &m); in ad_sd_write_reg()
103 uint8_t *data = sigma_delta->tx_buf; in ad_sd_read_reg_raw()
112 .cs_change = sigma_delta->bus_locked, in ad_sd_read_reg_raw()
119 if (sigma_delta->info->has_registers) { in ad_sd_read_reg_raw()
120 data[0] = reg << sigma_delta->info->addr_shift; in ad_sd_read_reg_raw()
121 data[0] |= sigma_delta->info->read_mask; in ad_sd_read_reg_raw()
122 data[0] |= sigma_delta->comm; in ad_sd_read_reg_raw()
127 if (sigma_delta->bus_locked) in ad_sd_read_reg_raw()
128 ret = spi_sync_locked(sigma_delta->spi, &m); in ad_sd_read_reg_raw()
130 ret = spi_sync(sigma_delta->spi, &m); in ad_sd_read_reg_raw()
136 * ad_sd_read_reg() - Read a register
138 * @sigma_delta: The sigma delta device
140 * @size: Size of the register (1-4)
150 ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->rx_buf); in ad_sd_read_reg()
156 *val = get_unaligned_be32(sigma_delta->rx_buf); in ad_sd_read_reg()
159 *val = get_unaligned_be24(sigma_delta->rx_buf); in ad_sd_read_reg()
162 *val = get_unaligned_be16(sigma_delta->rx_buf); in ad_sd_read_reg()
165 *val = sigma_delta->rx_buf[0]; in ad_sd_read_reg()
168 ret = -EINVAL; in ad_sd_read_reg()
178 * ad_sd_reset() - Reset the serial interface
180 * @sigma_delta: The sigma delta device
195 return -ENOMEM; in ad_sd_reset()
198 ret = spi_write(sigma_delta->spi, buf, size); in ad_sd_reset()
215 spi_bus_lock(sigma_delta->spi->controller); in ad_sd_calibrate()
216 sigma_delta->bus_locked = true; in ad_sd_calibrate()
217 sigma_delta->keep_cs_asserted = true; in ad_sd_calibrate()
218 reinit_completion(&sigma_delta->completion); in ad_sd_calibrate()
224 sigma_delta->irq_dis = false; in ad_sd_calibrate()
225 enable_irq(sigma_delta->irq_line); in ad_sd_calibrate()
226 time_left = wait_for_completion_timeout(&sigma_delta->completion, 2 * HZ); in ad_sd_calibrate()
228 sigma_delta->irq_dis = true; in ad_sd_calibrate()
229 disable_irq_nosync(sigma_delta->irq_line); in ad_sd_calibrate()
230 ret = -EIO; in ad_sd_calibrate()
235 sigma_delta->keep_cs_asserted = false; in ad_sd_calibrate()
237 sigma_delta->bus_locked = false; in ad_sd_calibrate()
238 spi_bus_unlock(sigma_delta->spi->controller); in ad_sd_calibrate()
245 * ad_sd_calibrate_all() - Performs channel calibration
246 * @sigma_delta: The sigma delta device
269 * ad_sigma_delta_single_conversion() - Performs a single data conversion
288 ad_sigma_delta_set_channel(sigma_delta, chan->address); in ad_sigma_delta_single_conversion()
290 spi_bus_lock(sigma_delta->spi->controller); in ad_sigma_delta_single_conversion()
291 sigma_delta->bus_locked = true; in ad_sigma_delta_single_conversion()
292 sigma_delta->keep_cs_asserted = true; in ad_sigma_delta_single_conversion()
293 reinit_completion(&sigma_delta->completion); in ad_sigma_delta_single_conversion()
297 sigma_delta->irq_dis = false; in ad_sigma_delta_single_conversion()
298 enable_irq(sigma_delta->irq_line); in ad_sigma_delta_single_conversion()
300 &sigma_delta->completion, HZ); in ad_sigma_delta_single_conversion()
303 ret = -EIO; in ad_sigma_delta_single_conversion()
307 if (sigma_delta->info->data_reg != 0) in ad_sigma_delta_single_conversion()
308 data_reg = sigma_delta->info->data_reg; in ad_sigma_delta_single_conversion()
313 DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8), in ad_sigma_delta_single_conversion()
317 if (!sigma_delta->irq_dis) { in ad_sigma_delta_single_conversion()
318 disable_irq_nosync(sigma_delta->irq_line); in ad_sigma_delta_single_conversion()
319 sigma_delta->irq_dis = true; in ad_sigma_delta_single_conversion()
322 sigma_delta->keep_cs_asserted = false; in ad_sigma_delta_single_conversion()
324 ad_sigma_delta_disable_one(sigma_delta, chan->address); in ad_sigma_delta_single_conversion()
325 sigma_delta->bus_locked = false; in ad_sigma_delta_single_conversion()
326 spi_bus_unlock(sigma_delta->spi->controller); in ad_sigma_delta_single_conversion()
332 sample = raw_sample >> chan->scan_type.shift; in ad_sigma_delta_single_conversion()
333 sample &= (1 << chan->scan_type.realbits) - 1; in ad_sigma_delta_single_conversion()
352 if (sigma_delta->num_slots == 1) { in ad_sd_buffer_postenable()
353 channel = find_first_bit(indio_dev->active_scan_mask, in ad_sd_buffer_postenable()
356 indio_dev->channels[channel].address); in ad_sd_buffer_postenable()
363 * For sigma-delta sequencer drivers with multiple slots, an update_scan_mode in ad_sd_buffer_postenable()
368 sigma_delta->slots[slot] = indio_dev->channels[i].address; in ad_sd_buffer_postenable()
373 sigma_delta->active_slots = slot; in ad_sd_buffer_postenable()
374 sigma_delta->current_slot = 0; in ad_sd_buffer_postenable()
376 if (sigma_delta->active_slots > 1) { in ad_sd_buffer_postenable()
382 samples_buf_size = ALIGN(slot * indio_dev->channels[0].scan_type.storagebits, 8); in ad_sd_buffer_postenable()
384 samples_buf = devm_krealloc(&sigma_delta->spi->dev, sigma_delta->samples_buf, in ad_sd_buffer_postenable()
387 return -ENOMEM; in ad_sd_buffer_postenable()
389 sigma_delta->samples_buf = samples_buf; in ad_sd_buffer_postenable()
391 spi_bus_lock(sigma_delta->spi->controller); in ad_sd_buffer_postenable()
392 sigma_delta->bus_locked = true; in ad_sd_buffer_postenable()
393 sigma_delta->keep_cs_asserted = true; in ad_sd_buffer_postenable()
399 sigma_delta->irq_dis = false; in ad_sd_buffer_postenable()
400 enable_irq(sigma_delta->irq_line); in ad_sd_buffer_postenable()
405 spi_bus_unlock(sigma_delta->spi->controller); in ad_sd_buffer_postenable()
414 reinit_completion(&sigma_delta->completion); in ad_sd_buffer_postdisable()
415 wait_for_completion_timeout(&sigma_delta->completion, HZ); in ad_sd_buffer_postdisable()
417 if (!sigma_delta->irq_dis) { in ad_sd_buffer_postdisable()
418 disable_irq_nosync(sigma_delta->irq_line); in ad_sd_buffer_postdisable()
419 sigma_delta->irq_dis = true; in ad_sd_buffer_postdisable()
422 sigma_delta->keep_cs_asserted = false; in ad_sd_buffer_postdisable()
425 if (sigma_delta->status_appended) in ad_sd_buffer_postdisable()
429 sigma_delta->bus_locked = false; in ad_sd_buffer_postdisable()
430 return spi_bus_unlock(sigma_delta->spi->controller); in ad_sd_buffer_postdisable()
436 struct iio_dev *indio_dev = pf->indio_dev; in ad_sd_trigger_handler()
438 uint8_t *data = sigma_delta->rx_buf; in ad_sd_trigger_handler()
446 reg_size = indio_dev->channels[0].scan_type.realbits + in ad_sd_trigger_handler()
447 indio_dev->channels[0].scan_type.shift; in ad_sd_trigger_handler()
450 if (sigma_delta->info->data_reg != 0) in ad_sd_trigger_handler()
451 data_reg = sigma_delta->info->data_reg; in ad_sd_trigger_handler()
456 if (sigma_delta->status_appended) in ad_sd_trigger_handler()
486 if (sigma_delta->active_slots == 1) { in ad_sd_trigger_handler()
487 iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp); in ad_sd_trigger_handler()
491 if (sigma_delta->status_appended) { in ad_sd_trigger_handler()
494 converted_channel = data[status_pos] & sigma_delta->info->status_ch_mask; in ad_sd_trigger_handler()
495 if (converted_channel != sigma_delta->slots[sigma_delta->current_slot]) { in ad_sd_trigger_handler()
501 sigma_delta->current_slot = 0; in ad_sd_trigger_handler()
506 sample_size = indio_dev->channels[0].scan_type.storagebits / 8; in ad_sd_trigger_handler()
507 sample_pos = sample_size * sigma_delta->current_slot; in ad_sd_trigger_handler()
508 memcpy(&sigma_delta->samples_buf[sample_pos], data, sample_size); in ad_sd_trigger_handler()
509 sigma_delta->current_slot++; in ad_sd_trigger_handler()
511 if (sigma_delta->current_slot == sigma_delta->active_slots) { in ad_sd_trigger_handler()
512 sigma_delta->current_slot = 0; in ad_sd_trigger_handler()
513 iio_push_to_buffers_with_timestamp(indio_dev, sigma_delta->samples_buf, in ad_sd_trigger_handler()
514 pf->timestamp); in ad_sd_trigger_handler()
518 iio_trigger_notify_done(indio_dev->trig); in ad_sd_trigger_handler()
519 sigma_delta->irq_dis = false; in ad_sd_trigger_handler()
520 enable_irq(sigma_delta->irq_line); in ad_sd_trigger_handler()
529 return bitmap_weight(mask, iio_get_masklength(indio_dev)) <= sigma_delta->num_slots; in ad_sd_validate_scan_mask()
542 complete(&sigma_delta->completion); in ad_sd_data_rdy_trig_poll()
544 sigma_delta->irq_dis = true; in ad_sd_data_rdy_trig_poll()
545 iio_trigger_poll(sigma_delta->trig); in ad_sd_data_rdy_trig_poll()
551 * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
556 * device, -EINVAL otherwise.
562 if (sigma_delta->trig != trig) in ad_sd_validate_trigger()
563 return -EINVAL; in ad_sd_validate_trigger()
572 unsigned long irq_flags = irq_get_trigger_type(sigma_delta->irq_line); in devm_ad_sd_probe_trigger()
575 if (dev != &sigma_delta->spi->dev) { in devm_ad_sd_probe_trigger()
577 dev_name(dev), dev_name(&sigma_delta->spi->dev)); in devm_ad_sd_probe_trigger()
578 return -EFAULT; in devm_ad_sd_probe_trigger()
581 sigma_delta->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, in devm_ad_sd_probe_trigger()
583 if (sigma_delta->trig == NULL) in devm_ad_sd_probe_trigger()
584 return -ENOMEM; in devm_ad_sd_probe_trigger()
586 init_completion(&sigma_delta->completion); in devm_ad_sd_probe_trigger()
588 sigma_delta->irq_dis = true; in devm_ad_sd_probe_trigger()
591 irq_set_status_flags(sigma_delta->irq_line, IRQ_DISABLE_UNLAZY); in devm_ad_sd_probe_trigger()
595 irq_flags = sigma_delta->info->irq_flags; in devm_ad_sd_probe_trigger()
597 ret = devm_request_irq(dev, sigma_delta->irq_line, in devm_ad_sd_probe_trigger()
600 indio_dev->name, in devm_ad_sd_probe_trigger()
605 iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta); in devm_ad_sd_probe_trigger()
607 ret = devm_iio_trigger_register(dev, sigma_delta->trig); in devm_ad_sd_probe_trigger()
612 indio_dev->trig = iio_trigger_get(sigma_delta->trig); in devm_ad_sd_probe_trigger()
618 * devm_ad_sd_setup_buffer_and_trigger() - Device-managed buffer & trigger setup
619 * @dev: Device object to which to bind the life-time of the resources attached
627 sigma_delta->slots = devm_kcalloc(dev, sigma_delta->num_slots, in devm_ad_sd_setup_buffer_and_trigger()
628 sizeof(*sigma_delta->slots), GFP_KERNEL); in devm_ad_sd_setup_buffer_and_trigger()
629 if (!sigma_delta->slots) in devm_ad_sd_setup_buffer_and_trigger()
630 return -ENOMEM; in devm_ad_sd_setup_buffer_and_trigger()
644 * ad_sd_init() - Initializes a ad_sigma_delta struct
646 * @indio_dev: The IIO device which the Sigma Delta device is used for
656 sigma_delta->spi = spi; in ad_sd_init()
657 sigma_delta->info = info; in ad_sd_init()
660 if (!info->num_slots) in ad_sd_init()
661 sigma_delta->num_slots = 1; in ad_sd_init()
663 sigma_delta->num_slots = info->num_slots; in ad_sd_init()
665 if (sigma_delta->num_slots > 1) { in ad_sd_init()
666 if (!indio_dev->info->update_scan_mode) { in ad_sd_init()
667 dev_err(&spi->dev, "iio_dev lacks update_scan_mode().\n"); in ad_sd_init()
668 return -EINVAL; in ad_sd_init()
671 if (!info->disable_all) { in ad_sd_init()
672 dev_err(&spi->dev, "ad_sigma_delta_info lacks disable_all().\n"); in ad_sd_init()
673 return -EINVAL; in ad_sd_init()
677 if (info->irq_line) in ad_sd_init()
678 sigma_delta->irq_line = info->irq_line; in ad_sd_init()
680 sigma_delta->irq_line = spi->irq; in ad_sd_init()
688 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
689 MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");