Lines Matching +full:delta +full:- +full:sigma
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->master); 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->spi->irq); in ad_sd_calibrate()
226 timeout = 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->spi->irq); 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->master); 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->master); 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->spi->irq); 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->spi->irq); 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 sigma_delta->bus_locked = false; in ad_sigma_delta_single_conversion()
325 spi_bus_unlock(sigma_delta->spi->master); in ad_sigma_delta_single_conversion()
331 sample = raw_sample >> chan->scan_type.shift; in ad_sigma_delta_single_conversion()
332 sample &= (1 << chan->scan_type.realbits) - 1; in ad_sigma_delta_single_conversion()
351 if (sigma_delta->num_slots == 1) { in ad_sd_buffer_postenable()
352 channel = find_first_bit(indio_dev->active_scan_mask, in ad_sd_buffer_postenable()
353 indio_dev->masklength); in ad_sd_buffer_postenable()
355 indio_dev->channels[channel].address); in ad_sd_buffer_postenable()
362 * For sigma-delta sequencer drivers with multiple slots, an update_scan_mode in ad_sd_buffer_postenable()
366 for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->masklength) { in ad_sd_buffer_postenable()
367 sigma_delta->slots[slot] = indio_dev->channels[i].address; in ad_sd_buffer_postenable()
372 sigma_delta->active_slots = slot; in ad_sd_buffer_postenable()
373 sigma_delta->current_slot = 0; in ad_sd_buffer_postenable()
375 if (sigma_delta->active_slots > 1) { in ad_sd_buffer_postenable()
381 samples_buf_size = ALIGN(slot * indio_dev->channels[0].scan_type.storagebits, 8); in ad_sd_buffer_postenable()
383 samples_buf = devm_krealloc(&sigma_delta->spi->dev, sigma_delta->samples_buf, in ad_sd_buffer_postenable()
386 return -ENOMEM; in ad_sd_buffer_postenable()
388 sigma_delta->samples_buf = samples_buf; in ad_sd_buffer_postenable()
390 spi_bus_lock(sigma_delta->spi->master); in ad_sd_buffer_postenable()
391 sigma_delta->bus_locked = true; in ad_sd_buffer_postenable()
392 sigma_delta->keep_cs_asserted = true; in ad_sd_buffer_postenable()
398 sigma_delta->irq_dis = false; in ad_sd_buffer_postenable()
399 enable_irq(sigma_delta->spi->irq); in ad_sd_buffer_postenable()
404 spi_bus_unlock(sigma_delta->spi->master); in ad_sd_buffer_postenable()
413 reinit_completion(&sigma_delta->completion); in ad_sd_buffer_postdisable()
414 wait_for_completion_timeout(&sigma_delta->completion, HZ); in ad_sd_buffer_postdisable()
416 if (!sigma_delta->irq_dis) { in ad_sd_buffer_postdisable()
417 disable_irq_nosync(sigma_delta->spi->irq); in ad_sd_buffer_postdisable()
418 sigma_delta->irq_dis = true; in ad_sd_buffer_postdisable()
421 sigma_delta->keep_cs_asserted = false; in ad_sd_buffer_postdisable()
424 if (sigma_delta->status_appended) in ad_sd_buffer_postdisable()
428 sigma_delta->bus_locked = false; in ad_sd_buffer_postdisable()
429 return spi_bus_unlock(sigma_delta->spi->master); in ad_sd_buffer_postdisable()
435 struct iio_dev *indio_dev = pf->indio_dev; in ad_sd_trigger_handler()
437 uint8_t *data = sigma_delta->rx_buf; in ad_sd_trigger_handler()
445 reg_size = indio_dev->channels[0].scan_type.realbits + in ad_sd_trigger_handler()
446 indio_dev->channels[0].scan_type.shift; in ad_sd_trigger_handler()
449 if (sigma_delta->info->data_reg != 0) in ad_sd_trigger_handler()
450 data_reg = sigma_delta->info->data_reg; in ad_sd_trigger_handler()
455 if (sigma_delta->status_appended) in ad_sd_trigger_handler()
485 if (sigma_delta->active_slots == 1) { in ad_sd_trigger_handler()
486 iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp); in ad_sd_trigger_handler()
490 if (sigma_delta->status_appended) { in ad_sd_trigger_handler()
493 converted_channel = data[status_pos] & sigma_delta->info->status_ch_mask; in ad_sd_trigger_handler()
494 if (converted_channel != sigma_delta->slots[sigma_delta->current_slot]) { in ad_sd_trigger_handler()
500 sigma_delta->current_slot = 0; in ad_sd_trigger_handler()
505 sample_size = indio_dev->channels[0].scan_type.storagebits / 8; in ad_sd_trigger_handler()
506 sample_pos = sample_size * sigma_delta->current_slot; in ad_sd_trigger_handler()
507 memcpy(&sigma_delta->samples_buf[sample_pos], data, sample_size); in ad_sd_trigger_handler()
508 sigma_delta->current_slot++; in ad_sd_trigger_handler()
510 if (sigma_delta->current_slot == sigma_delta->active_slots) { in ad_sd_trigger_handler()
511 sigma_delta->current_slot = 0; in ad_sd_trigger_handler()
512 iio_push_to_buffers_with_timestamp(indio_dev, sigma_delta->samples_buf, in ad_sd_trigger_handler()
513 pf->timestamp); in ad_sd_trigger_handler()
517 iio_trigger_notify_done(indio_dev->trig); in ad_sd_trigger_handler()
518 sigma_delta->irq_dis = false; in ad_sd_trigger_handler()
519 enable_irq(sigma_delta->spi->irq); in ad_sd_trigger_handler()
528 return bitmap_weight(mask, indio_dev->masklength) <= sigma_delta->num_slots; in ad_sd_validate_scan_mask()
541 complete(&sigma_delta->completion); in ad_sd_data_rdy_trig_poll()
543 sigma_delta->irq_dis = true; in ad_sd_data_rdy_trig_poll()
544 iio_trigger_poll(sigma_delta->trig); in ad_sd_data_rdy_trig_poll()
550 * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
555 * device, -EINVAL otherwise.
561 if (sigma_delta->trig != trig) in ad_sd_validate_trigger()
562 return -EINVAL; in ad_sd_validate_trigger()
573 if (dev != &sigma_delta->spi->dev) { in devm_ad_sd_probe_trigger()
575 dev_name(dev), dev_name(&sigma_delta->spi->dev)); in devm_ad_sd_probe_trigger()
576 return -EFAULT; in devm_ad_sd_probe_trigger()
579 sigma_delta->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, in devm_ad_sd_probe_trigger()
581 if (sigma_delta->trig == NULL) in devm_ad_sd_probe_trigger()
582 return -ENOMEM; in devm_ad_sd_probe_trigger()
584 init_completion(&sigma_delta->completion); in devm_ad_sd_probe_trigger()
586 sigma_delta->irq_dis = true; in devm_ad_sd_probe_trigger()
589 irq_set_status_flags(sigma_delta->spi->irq, IRQ_DISABLE_UNLAZY); in devm_ad_sd_probe_trigger()
591 ret = devm_request_irq(dev, sigma_delta->spi->irq, in devm_ad_sd_probe_trigger()
593 sigma_delta->info->irq_flags | IRQF_NO_AUTOEN, in devm_ad_sd_probe_trigger()
594 indio_dev->name, in devm_ad_sd_probe_trigger()
599 iio_trigger_set_drvdata(sigma_delta->trig, sigma_delta); in devm_ad_sd_probe_trigger()
601 ret = devm_iio_trigger_register(dev, sigma_delta->trig); in devm_ad_sd_probe_trigger()
606 indio_dev->trig = iio_trigger_get(sigma_delta->trig); in devm_ad_sd_probe_trigger()
612 * devm_ad_sd_setup_buffer_and_trigger() - Device-managed buffer & trigger setup
613 * @dev: Device object to which to bind the life-time of the resources attached
621 sigma_delta->slots = devm_kcalloc(dev, sigma_delta->num_slots, in devm_ad_sd_setup_buffer_and_trigger()
622 sizeof(*sigma_delta->slots), GFP_KERNEL); in devm_ad_sd_setup_buffer_and_trigger()
623 if (!sigma_delta->slots) in devm_ad_sd_setup_buffer_and_trigger()
624 return -ENOMEM; in devm_ad_sd_setup_buffer_and_trigger()
638 * ad_sd_init() - Initializes a ad_sigma_delta struct
640 * @indio_dev: The IIO device which the Sigma Delta device is used for
650 sigma_delta->spi = spi; in ad_sd_init()
651 sigma_delta->info = info; in ad_sd_init()
654 if (!info->num_slots) in ad_sd_init()
655 sigma_delta->num_slots = 1; in ad_sd_init()
657 sigma_delta->num_slots = info->num_slots; in ad_sd_init()
659 if (sigma_delta->num_slots > 1) { in ad_sd_init()
660 if (!indio_dev->info->update_scan_mode) { in ad_sd_init()
661 dev_err(&spi->dev, "iio_dev lacks update_scan_mode().\n"); in ad_sd_init()
662 return -EINVAL; in ad_sd_init()
665 if (!info->disable_all) { in ad_sd_init()
666 dev_err(&spi->dev, "ad_sigma_delta_info lacks disable_all().\n"); in ad_sd_init()
667 return -EINVAL; in ad_sd_init()
677 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
678 MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");