Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IIO: ADC: add stm32 DFSDM support for PDM microphone

This code offers a way to handle PDM audio microphones in
ASOC framework. Audio driver should use consumer API.
A specific management is implemented for DMA, with a
callback, to allows to handle audio buffers efficiently.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Arnaud Pouliquen and committed by
Mark Brown
eca94980 e2e6771c

+529 -7
+16
Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32
··· 1 + What: /sys/bus/iio/devices/iio:deviceX/in_voltage_spi_clk_freq 2 + KernelVersion: 4.14 3 + Contact: arnaud.pouliquen@st.com 4 + Description: 5 + For audio purpose only. 6 + Used by audio driver to set/get the spi input frequency. 7 + This is mandatory if DFSDM is slave on SPI bus, to 8 + provide information on the SPI clock frequency during runtime 9 + Notice that the SPI frequency should be a multiple of sample 10 + frequency to ensure the precision. 11 + if DFSDM input is SPI master 12 + Reading SPI clkout frequency, 13 + error on writing 14 + If DFSDM input is SPI Slave: 15 + Reading returns value previously set. 16 + Writing value before starting conversions.
+495 -7
drivers/iio/adc/stm32-dfsdm-adc.c
··· 6 6 * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>. 7 7 */ 8 8 9 + #include <linux/dmaengine.h> 10 + #include <linux/dma-mapping.h> 9 11 #include <linux/interrupt.h> 10 12 #include <linux/iio/buffer.h> 11 13 #include <linux/iio/hw-consumer.h> 12 14 #include <linux/iio/iio.h> 13 15 #include <linux/iio/sysfs.h> 14 16 #include <linux/module.h> 15 - #include <linux/of.h> 17 + #include <linux/of_device.h> 16 18 #include <linux/platform_device.h> 17 19 #include <linux/regmap.h> 18 20 #include <linux/slab.h> 19 21 20 22 #include "stm32-dfsdm.h" 23 + 24 + #define DFSDM_DMA_BUFFER_SIZE (4 * PAGE_SIZE) 21 25 22 26 /* Conversion timeout */ 23 27 #define DFSDM_TIMEOUT_US 100000 ··· 62 58 struct completion completion; 63 59 u32 *buffer; 64 60 61 + /* Audio specific */ 62 + unsigned int spi_freq; /* SPI bus clock frequency */ 63 + unsigned int sample_freq; /* Sample frequency after filter decimation */ 64 + int (*cb)(const void *data, size_t size, void *cb_priv); 65 + void *cb_priv; 66 + 67 + /* DMA */ 68 + u8 *rx_buf; 69 + unsigned int bufi; /* Buffer current position */ 70 + unsigned int buf_sz; /* Buffer size */ 71 + struct dma_chan *dma_chan; 72 + dma_addr_t dma_buf; 65 73 }; 66 74 67 75 struct stm32_dfsdm_str2field { ··· 367 351 return 0; 368 352 } 369 353 354 + static ssize_t dfsdm_adc_audio_get_spiclk(struct iio_dev *indio_dev, 355 + uintptr_t priv, 356 + const struct iio_chan_spec *chan, 357 + char *buf) 358 + { 359 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 360 + 361 + return snprintf(buf, PAGE_SIZE, "%d\n", adc->spi_freq); 362 + } 363 + 364 + static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev, 365 + uintptr_t priv, 366 + const struct iio_chan_spec *chan, 367 + const char *buf, size_t len) 368 + { 369 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 370 + struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; 371 + struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; 372 + unsigned int sample_freq = adc->sample_freq; 373 + unsigned int spi_freq; 374 + int ret; 375 + 376 + dev_err(&indio_dev->dev, "enter %s\n", __func__); 377 + /* If DFSDM is master on SPI, SPI freq can not be updated */ 378 + if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) 379 + return -EPERM; 380 + 381 + ret = kstrtoint(buf, 0, &spi_freq); 382 + if (ret) 383 + return ret; 384 + 385 + if (!spi_freq) 386 + return -EINVAL; 387 + 388 + if (sample_freq) { 389 + if (spi_freq % sample_freq) 390 + dev_warn(&indio_dev->dev, 391 + "Sampling rate not accurate (%d)\n", 392 + spi_freq / (spi_freq / sample_freq)); 393 + 394 + ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / sample_freq)); 395 + if (ret < 0) { 396 + dev_err(&indio_dev->dev, 397 + "No filter parameters that match!\n"); 398 + return ret; 399 + } 400 + } 401 + adc->spi_freq = spi_freq; 402 + 403 + return len; 404 + } 405 + 370 406 static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma) 371 407 { 372 408 struct regmap *regmap = adc->dfsdm->regmap; 373 409 int ret; 410 + unsigned int dma_en = 0, cont_en = 0; 374 411 375 412 ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id); 376 413 if (ret < 0) ··· 431 362 432 363 ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id, 433 364 adc->ch_id); 365 + if (ret < 0) 366 + goto stop_channels; 367 + 368 + if (dma) { 369 + /* Enable DMA transfer*/ 370 + dma_en = DFSDM_CR1_RDMAEN(1); 371 + /* Enable conversion triggered by SPI clock*/ 372 + cont_en = DFSDM_CR1_RCONT(1); 373 + } 374 + /* Enable DMA transfer*/ 375 + ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), 376 + DFSDM_CR1_RDMAEN_MASK, dma_en); 377 + if (ret < 0) 378 + goto stop_channels; 379 + 380 + /* Enable conversion triggered by SPI clock*/ 381 + ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), 382 + DFSDM_CR1_RCONT_MASK, cont_en); 434 383 if (ret < 0) 435 384 goto stop_channels; 436 385 ··· 484 397 485 398 stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id); 486 399 } 400 + 401 + static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev, 402 + unsigned int val) 403 + { 404 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 405 + unsigned int watermark = DFSDM_DMA_BUFFER_SIZE / 2; 406 + 407 + /* 408 + * DMA cyclic transfers are used, buffer is split into two periods. 409 + * There should be : 410 + * - always one buffer (period) DMA is working on 411 + * - one buffer (period) driver pushed to ASoC side. 412 + */ 413 + watermark = min(watermark, val * (unsigned int)(sizeof(u32))); 414 + adc->buf_sz = watermark * 2; 415 + 416 + return 0; 417 + } 418 + 419 + static unsigned int stm32_dfsdm_adc_dma_residue(struct stm32_dfsdm_adc *adc) 420 + { 421 + struct dma_tx_state state; 422 + enum dma_status status; 423 + 424 + status = dmaengine_tx_status(adc->dma_chan, 425 + adc->dma_chan->cookie, 426 + &state); 427 + if (status == DMA_IN_PROGRESS) { 428 + /* Residue is size in bytes from end of buffer */ 429 + unsigned int i = adc->buf_sz - state.residue; 430 + unsigned int size; 431 + 432 + /* Return available bytes */ 433 + if (i >= adc->bufi) 434 + size = i - adc->bufi; 435 + else 436 + size = adc->buf_sz + i - adc->bufi; 437 + 438 + return size; 439 + } 440 + 441 + return 0; 442 + } 443 + 444 + static void stm32_dfsdm_audio_dma_buffer_done(void *data) 445 + { 446 + struct iio_dev *indio_dev = data; 447 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 448 + int available = stm32_dfsdm_adc_dma_residue(adc); 449 + size_t old_pos; 450 + 451 + /* 452 + * FIXME: In Kernel interface does not support cyclic DMA buffer,and 453 + * offers only an interface to push data samples per samples. 454 + * For this reason IIO buffer interface is not used and interface is 455 + * bypassed using a private callback registered by ASoC. 456 + * This should be a temporary solution waiting a cyclic DMA engine 457 + * support in IIO. 458 + */ 459 + 460 + dev_dbg(&indio_dev->dev, "%s: pos = %d, available = %d\n", __func__, 461 + adc->bufi, available); 462 + old_pos = adc->bufi; 463 + 464 + while (available >= indio_dev->scan_bytes) { 465 + u32 *buffer = (u32 *)&adc->rx_buf[adc->bufi]; 466 + 467 + /* Mask 8 LSB that contains the channel ID */ 468 + *buffer = (*buffer & 0xFFFFFF00) << 8; 469 + available -= indio_dev->scan_bytes; 470 + adc->bufi += indio_dev->scan_bytes; 471 + if (adc->bufi >= adc->buf_sz) { 472 + if (adc->cb) 473 + adc->cb(&adc->rx_buf[old_pos], 474 + adc->buf_sz - old_pos, adc->cb_priv); 475 + adc->bufi = 0; 476 + old_pos = 0; 477 + } 478 + } 479 + if (adc->cb) 480 + adc->cb(&adc->rx_buf[old_pos], adc->bufi - old_pos, 481 + adc->cb_priv); 482 + } 483 + 484 + static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev) 485 + { 486 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 487 + struct dma_async_tx_descriptor *desc; 488 + dma_cookie_t cookie; 489 + int ret; 490 + 491 + if (!adc->dma_chan) 492 + return -EINVAL; 493 + 494 + dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__, 495 + adc->buf_sz, adc->buf_sz / 2); 496 + 497 + /* Prepare a DMA cyclic transaction */ 498 + desc = dmaengine_prep_dma_cyclic(adc->dma_chan, 499 + adc->dma_buf, 500 + adc->buf_sz, adc->buf_sz / 2, 501 + DMA_DEV_TO_MEM, 502 + DMA_PREP_INTERRUPT); 503 + if (!desc) 504 + return -EBUSY; 505 + 506 + desc->callback = stm32_dfsdm_audio_dma_buffer_done; 507 + desc->callback_param = indio_dev; 508 + 509 + cookie = dmaengine_submit(desc); 510 + ret = dma_submit_error(cookie); 511 + if (ret) { 512 + dmaengine_terminate_all(adc->dma_chan); 513 + return ret; 514 + } 515 + 516 + /* Issue pending DMA requests */ 517 + dma_async_issue_pending(adc->dma_chan); 518 + 519 + return 0; 520 + } 521 + 522 + static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) 523 + { 524 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 525 + int ret; 526 + 527 + /* Reset adc buffer index */ 528 + adc->bufi = 0; 529 + 530 + ret = stm32_dfsdm_start_dfsdm(adc->dfsdm); 531 + if (ret < 0) 532 + return ret; 533 + 534 + ret = stm32_dfsdm_start_conv(adc, true); 535 + if (ret) { 536 + dev_err(&indio_dev->dev, "Can't start conversion\n"); 537 + goto stop_dfsdm; 538 + } 539 + 540 + if (adc->dma_chan) { 541 + ret = stm32_dfsdm_adc_dma_start(indio_dev); 542 + if (ret) { 543 + dev_err(&indio_dev->dev, "Can't start DMA\n"); 544 + goto err_stop_conv; 545 + } 546 + } 547 + 548 + return 0; 549 + 550 + err_stop_conv: 551 + stm32_dfsdm_stop_conv(adc); 552 + stop_dfsdm: 553 + stm32_dfsdm_stop_dfsdm(adc->dfsdm); 554 + 555 + return ret; 556 + } 557 + 558 + static int stm32_dfsdm_predisable(struct iio_dev *indio_dev) 559 + { 560 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 561 + 562 + if (adc->dma_chan) 563 + dmaengine_terminate_all(adc->dma_chan); 564 + 565 + stm32_dfsdm_stop_conv(adc); 566 + 567 + stm32_dfsdm_stop_dfsdm(adc->dfsdm); 568 + 569 + return 0; 570 + } 571 + 572 + static const struct iio_buffer_setup_ops stm32_dfsdm_buffer_setup_ops = { 573 + .postenable = &stm32_dfsdm_postenable, 574 + .predisable = &stm32_dfsdm_predisable, 575 + }; 576 + 577 + /** 578 + * stm32_dfsdm_get_buff_cb() - register a callback that will be called when 579 + * DMA transfer period is achieved. 580 + * 581 + * @iio_dev: Handle to IIO device. 582 + * @cb: Pointer to callback function: 583 + * - data: pointer to data buffer 584 + * - size: size in byte of the data buffer 585 + * - private: pointer to consumer private structure. 586 + * @private: Pointer to consumer private structure. 587 + */ 588 + int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev, 589 + int (*cb)(const void *data, size_t size, 590 + void *private), 591 + void *private) 592 + { 593 + struct stm32_dfsdm_adc *adc; 594 + 595 + if (!iio_dev) 596 + return -EINVAL; 597 + adc = iio_priv(iio_dev); 598 + 599 + adc->cb = cb; 600 + adc->cb_priv = private; 601 + 602 + return 0; 603 + } 604 + EXPORT_SYMBOL_GPL(stm32_dfsdm_get_buff_cb); 605 + 606 + /** 607 + * stm32_dfsdm_release_buff_cb - unregister buffer callback 608 + * 609 + * @iio_dev: Handle to IIO device. 610 + */ 611 + int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev) 612 + { 613 + struct stm32_dfsdm_adc *adc; 614 + 615 + if (!iio_dev) 616 + return -EINVAL; 617 + adc = iio_priv(iio_dev); 618 + 619 + adc->cb = NULL; 620 + adc->cb_priv = NULL; 621 + 622 + return 0; 623 + } 624 + EXPORT_SYMBOL_GPL(stm32_dfsdm_release_buff_cb); 487 625 488 626 static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev, 489 627 const struct iio_chan_spec *chan, int *res) ··· 765 453 { 766 454 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 767 455 struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; 456 + struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; 457 + unsigned int spi_freq = adc->spi_freq; 768 458 int ret = -EINVAL; 769 459 770 - if (mask == IIO_CHAN_INFO_OVERSAMPLING_RATIO) { 460 + switch (mask) { 461 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 771 462 ret = stm32_dfsdm_set_osrs(fl, 0, val); 772 463 if (!ret) 773 464 adc->oversamp = val; 465 + 466 + return ret; 467 + 468 + case IIO_CHAN_INFO_SAMP_FREQ: 469 + if (!val) 470 + return -EINVAL; 471 + if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) 472 + spi_freq = adc->dfsdm->spi_master_freq; 473 + 474 + if (spi_freq % val) 475 + dev_warn(&indio_dev->dev, 476 + "Sampling rate not accurate (%d)\n", 477 + spi_freq / (spi_freq / val)); 478 + 479 + ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / val)); 480 + if (ret < 0) { 481 + dev_err(&indio_dev->dev, 482 + "Not able to find parameter that match!\n"); 483 + return ret; 484 + } 485 + adc->sample_freq = val; 486 + 487 + return 0; 774 488 } 775 489 776 - return ret; 490 + return -EINVAL; 777 491 } 778 492 779 493 static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev, ··· 832 494 *val = adc->oversamp; 833 495 834 496 return IIO_VAL_INT; 497 + 498 + case IIO_CHAN_INFO_SAMP_FREQ: 499 + *val = adc->sample_freq; 500 + 501 + return IIO_VAL_INT; 835 502 } 836 503 837 504 return -EINVAL; 838 505 } 506 + 507 + static const struct iio_info stm32_dfsdm_info_audio = { 508 + .hwfifo_set_watermark = stm32_dfsdm_set_watermark, 509 + .read_raw = stm32_dfsdm_read_raw, 510 + .write_raw = stm32_dfsdm_write_raw, 511 + }; 839 512 840 513 static const struct iio_info stm32_dfsdm_info_adc = { 841 514 .read_raw = stm32_dfsdm_read_raw, ··· 880 531 return IRQ_HANDLED; 881 532 } 882 533 534 + /* 535 + * Define external info for SPI Frequency and audio sampling rate that can be 536 + * configured by ASoC driver through consumer.h API 537 + */ 538 + static const struct iio_chan_spec_ext_info dfsdm_adc_audio_ext_info[] = { 539 + /* spi_clk_freq : clock freq on SPI/manchester bus used by channel */ 540 + { 541 + .name = "spi_clk_freq", 542 + .shared = IIO_SHARED_BY_TYPE, 543 + .read = dfsdm_adc_audio_get_spiclk, 544 + .write = dfsdm_adc_audio_set_spiclk, 545 + }, 546 + {}, 547 + }; 548 + 549 + static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev) 550 + { 551 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 552 + 553 + if (adc->dma_chan) { 554 + dma_free_coherent(adc->dma_chan->device->dev, 555 + DFSDM_DMA_BUFFER_SIZE, 556 + adc->rx_buf, adc->dma_buf); 557 + dma_release_channel(adc->dma_chan); 558 + } 559 + } 560 + 561 + static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev) 562 + { 563 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 564 + struct dma_slave_config config = { 565 + .src_addr = (dma_addr_t)adc->dfsdm->phys_base + 566 + DFSDM_RDATAR(adc->fl_id), 567 + .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 568 + }; 569 + int ret; 570 + 571 + adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx"); 572 + if (!adc->dma_chan) 573 + return -EINVAL; 574 + 575 + adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev, 576 + DFSDM_DMA_BUFFER_SIZE, 577 + &adc->dma_buf, GFP_KERNEL); 578 + if (!adc->rx_buf) { 579 + ret = -ENOMEM; 580 + goto err_release; 581 + } 582 + 583 + ret = dmaengine_slave_config(adc->dma_chan, &config); 584 + if (ret) 585 + goto err_free; 586 + 587 + return 0; 588 + 589 + err_free: 590 + dma_free_coherent(adc->dma_chan->device->dev, DFSDM_DMA_BUFFER_SIZE, 591 + adc->rx_buf, adc->dma_buf); 592 + err_release: 593 + dma_release_channel(adc->dma_chan); 594 + 595 + return ret; 596 + } 597 + 883 598 static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, 884 599 struct iio_chan_spec *ch) 885 600 { ··· 964 551 ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 965 552 ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); 966 553 967 - ch->scan_type.sign = 'u'; 554 + if (adc->dev_data->type == DFSDM_AUDIO) { 555 + ch->scan_type.sign = 's'; 556 + ch->ext_info = dfsdm_adc_audio_ext_info; 557 + } else { 558 + ch->scan_type.sign = 'u'; 559 + } 968 560 ch->scan_type.realbits = 24; 969 561 ch->scan_type.storagebits = 32; 970 562 adc->ch_id = ch->channel; 971 563 972 564 return stm32_dfsdm_chan_configure(adc->dfsdm, 973 565 &adc->dfsdm->ch_list[ch->channel]); 566 + } 567 + 568 + static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev) 569 + { 570 + struct iio_chan_spec *ch; 571 + struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 572 + struct stm32_dfsdm_channel *d_ch; 573 + int ret; 574 + 575 + indio_dev->modes |= INDIO_BUFFER_SOFTWARE; 576 + indio_dev->setup_ops = &stm32_dfsdm_buffer_setup_ops; 577 + 578 + ch = devm_kzalloc(&indio_dev->dev, sizeof(*ch), GFP_KERNEL); 579 + if (!ch) 580 + return -ENOMEM; 581 + 582 + ch->scan_index = 0; 583 + 584 + ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch); 585 + if (ret < 0) { 586 + dev_err(&indio_dev->dev, "Channels init failed\n"); 587 + return ret; 588 + } 589 + ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ); 590 + 591 + d_ch = &adc->dfsdm->ch_list[adc->ch_id]; 592 + if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) 593 + adc->spi_freq = adc->dfsdm->spi_master_freq; 594 + 595 + indio_dev->num_channels = 1; 596 + indio_dev->channels = ch; 597 + 598 + return stm32_dfsdm_dma_request(indio_dev); 974 599 } 975 600 976 601 static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) ··· 1063 612 .init = stm32_dfsdm_adc_init, 1064 613 }; 1065 614 615 + static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_audio_data = { 616 + .type = DFSDM_AUDIO, 617 + .init = stm32_dfsdm_audio_init, 618 + }; 619 + 1066 620 static const struct of_device_id stm32_dfsdm_adc_match[] = { 1067 621 { 1068 622 .compatible = "st,stm32-dfsdm-adc", 1069 623 .data = &stm32h7_dfsdm_adc_data, 624 + }, 625 + { 626 + .compatible = "st,stm32-dfsdm-dmic", 627 + .data = &stm32h7_dfsdm_audio_data, 1070 628 }, 1071 629 {} 1072 630 }; ··· 1127 667 name = devm_kzalloc(dev, sizeof("dfsdm-adc0"), GFP_KERNEL); 1128 668 if (!name) 1129 669 return -ENOMEM; 1130 - iio->info = &stm32_dfsdm_info_adc; 1131 - snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id); 670 + if (dev_data->type == DFSDM_AUDIO) { 671 + iio->info = &stm32_dfsdm_info_audio; 672 + snprintf(name, sizeof("dfsdm-pdm0"), "dfsdm-pdm%d", adc->fl_id); 673 + } else { 674 + iio->info = &stm32_dfsdm_info_adc; 675 + snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id); 676 + } 1132 677 iio->name = name; 1133 678 1134 679 /* ··· 1165 700 if (ret < 0) 1166 701 return ret; 1167 702 1168 - return iio_device_register(iio); 703 + ret = iio_device_register(iio); 704 + if (ret < 0) 705 + goto err_cleanup; 706 + 707 + dev_err(dev, "of_platform_populate\n"); 708 + if (dev_data->type == DFSDM_AUDIO) { 709 + ret = of_platform_populate(np, NULL, NULL, dev); 710 + if (ret < 0) { 711 + dev_err(dev, "Failed to find an audio DAI\n"); 712 + goto err_unregister; 713 + } 714 + } 715 + 716 + return 0; 717 + 718 + err_unregister: 719 + iio_device_unregister(iio); 720 + err_cleanup: 721 + stm32_dfsdm_dma_release(iio); 722 + 723 + return ret; 1169 724 } 1170 725 1171 726 static int stm32_dfsdm_adc_remove(struct platform_device *pdev) ··· 1193 708 struct stm32_dfsdm_adc *adc = platform_get_drvdata(pdev); 1194 709 struct iio_dev *indio_dev = iio_priv_to_dev(adc); 1195 710 711 + if (adc->dev_data->type == DFSDM_AUDIO) 712 + of_platform_depopulate(&pdev->dev); 1196 713 iio_device_unregister(indio_dev); 714 + stm32_dfsdm_dma_release(indio_dev); 1197 715 1198 716 return 0; 1199 717 }
+18
include/linux/iio/adc/stm32-dfsdm-adc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * This file discribe the STM32 DFSDM IIO driver API for audio part 4 + * 5 + * Copyright (C) 2017, STMicroelectronics - All Rights Reserved 6 + * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>. 7 + */ 8 + 9 + #ifndef STM32_DFSDM_ADC_H 10 + #define STM32_DFSDM_ADC_H 11 + 12 + int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev, 13 + int (*cb)(const void *data, size_t size, 14 + void *private), 15 + void *private); 16 + int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev); 17 + 18 + #endif