| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * STM32 ALSA SoC Digital Audio Interface (I2S) driver. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved |
|---|
| 5 | 6 | * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics. |
|---|
| 6 | | - * |
|---|
| 7 | | - * License terms: GPL V2.0. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 10 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 11 | | - * the Free Software Foundation. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 14 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 15 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
|---|
| 16 | | - * details. |
|---|
| 17 | 7 | */ |
|---|
| 18 | 8 | |
|---|
| 9 | +#include <linux/bitfield.h> |
|---|
| 19 | 10 | #include <linux/clk.h> |
|---|
| 20 | 11 | #include <linux/delay.h> |
|---|
| 21 | 12 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 37 | 28 | #define STM32_I2S_TXDR_REG 0X20 |
|---|
| 38 | 29 | #define STM32_I2S_RXDR_REG 0x30 |
|---|
| 39 | 30 | #define STM32_I2S_CGFR_REG 0X50 |
|---|
| 31 | +#define STM32_I2S_HWCFGR_REG 0x3F0 |
|---|
| 32 | +#define STM32_I2S_VERR_REG 0x3F4 |
|---|
| 33 | +#define STM32_I2S_IPIDR_REG 0x3F8 |
|---|
| 34 | +#define STM32_I2S_SIDR_REG 0x3FC |
|---|
| 40 | 35 | |
|---|
| 41 | 36 | /* Bit definition for SPI2S_CR1 register */ |
|---|
| 42 | 37 | #define I2S_CR1_SPE BIT(0) |
|---|
| .. | .. |
|---|
| 143 | 138 | #define I2S_CGFR_ODD BIT(I2S_CGFR_ODD_SHIFT) |
|---|
| 144 | 139 | #define I2S_CGFR_MCKOE BIT(25) |
|---|
| 145 | 140 | |
|---|
| 141 | +/* Registers below apply to I2S version 1.1 and more */ |
|---|
| 142 | + |
|---|
| 143 | +/* Bit definition for SPI_HWCFGR register */ |
|---|
| 144 | +#define I2S_HWCFGR_I2S_SUPPORT_MASK GENMASK(15, 12) |
|---|
| 145 | + |
|---|
| 146 | +/* Bit definition for SPI_VERR register */ |
|---|
| 147 | +#define I2S_VERR_MIN_MASK GENMASK(3, 0) |
|---|
| 148 | +#define I2S_VERR_MAJ_MASK GENMASK(7, 4) |
|---|
| 149 | + |
|---|
| 150 | +/* Bit definition for SPI_IPIDR register */ |
|---|
| 151 | +#define I2S_IPIDR_ID_MASK GENMASK(31, 0) |
|---|
| 152 | + |
|---|
| 153 | +/* Bit definition for SPI_SIDR register */ |
|---|
| 154 | +#define I2S_SIDR_ID_MASK GENMASK(31, 0) |
|---|
| 155 | + |
|---|
| 156 | +#define I2S_IPIDR_NUMBER 0x00130022 |
|---|
| 157 | + |
|---|
| 146 | 158 | enum i2s_master_mode { |
|---|
| 147 | 159 | I2S_MS_NOT_SET, |
|---|
| 148 | 160 | I2S_MS_MASTER, |
|---|
| .. | .. |
|---|
| 179 | 191 | I2S_I2SMOD_DATLEN_32, |
|---|
| 180 | 192 | }; |
|---|
| 181 | 193 | |
|---|
| 182 | | -#define STM32_I2S_DAI_NAME_SIZE 20 |
|---|
| 183 | 194 | #define STM32_I2S_FIFO_SIZE 16 |
|---|
| 184 | 195 | |
|---|
| 185 | 196 | #define STM32_I2S_IS_MASTER(x) ((x)->ms_flg == I2S_MS_MASTER) |
|---|
| 186 | 197 | #define STM32_I2S_IS_SLAVE(x) ((x)->ms_flg == I2S_MS_SLAVE) |
|---|
| 187 | 198 | |
|---|
| 188 | 199 | /** |
|---|
| 200 | + * struct stm32_i2s_data - private data of I2S |
|---|
| 189 | 201 | * @regmap_conf: I2S register map configuration pointer |
|---|
| 190 | | - * @egmap: I2S register map pointer |
|---|
| 202 | + * @regmap: I2S register map pointer |
|---|
| 191 | 203 | * @pdev: device data pointer |
|---|
| 192 | 204 | * @dai_drv: DAI driver pointer |
|---|
| 193 | 205 | * @dma_data_tx: dma configuration data for tx channel |
|---|
| .. | .. |
|---|
| 200 | 212 | * @base: mmio register base virtual address |
|---|
| 201 | 213 | * @phys_addr: I2S registers physical base address |
|---|
| 202 | 214 | * @lock_fd: lock to manage race conditions in full duplex mode |
|---|
| 203 | | - * @dais_name: DAI name |
|---|
| 215 | + * @irq_lock: prevent race condition with IRQ |
|---|
| 204 | 216 | * @mclk_rate: master clock frequency (Hz) |
|---|
| 205 | 217 | * @fmt: DAI protocol |
|---|
| 206 | 218 | * @refcount: keep count of opened streams on I2S |
|---|
| .. | .. |
|---|
| 221 | 233 | void __iomem *base; |
|---|
| 222 | 234 | dma_addr_t phys_addr; |
|---|
| 223 | 235 | spinlock_t lock_fd; /* Manage race conditions for full duplex */ |
|---|
| 224 | | - char dais_name[STM32_I2S_DAI_NAME_SIZE]; |
|---|
| 236 | + spinlock_t irq_lock; /* used to prevent race condition with IRQ */ |
|---|
| 225 | 237 | unsigned int mclk_rate; |
|---|
| 226 | 238 | unsigned int fmt; |
|---|
| 227 | 239 | int refcount; |
|---|
| .. | .. |
|---|
| 262 | 274 | if (flags & I2S_SR_TIFRE) |
|---|
| 263 | 275 | dev_dbg(&pdev->dev, "Frame error\n"); |
|---|
| 264 | 276 | |
|---|
| 265 | | - if (err) |
|---|
| 277 | + spin_lock(&i2s->irq_lock); |
|---|
| 278 | + if (err && i2s->substream) |
|---|
| 266 | 279 | snd_pcm_stop_xrun(i2s->substream); |
|---|
| 280 | + spin_unlock(&i2s->irq_lock); |
|---|
| 267 | 281 | |
|---|
| 268 | 282 | return IRQ_HANDLED; |
|---|
| 269 | 283 | } |
|---|
| .. | .. |
|---|
| 276 | 290 | case STM32_I2S_CFG2_REG: |
|---|
| 277 | 291 | case STM32_I2S_IER_REG: |
|---|
| 278 | 292 | case STM32_I2S_SR_REG: |
|---|
| 279 | | - case STM32_I2S_TXDR_REG: |
|---|
| 280 | 293 | case STM32_I2S_RXDR_REG: |
|---|
| 281 | 294 | case STM32_I2S_CGFR_REG: |
|---|
| 295 | + case STM32_I2S_HWCFGR_REG: |
|---|
| 296 | + case STM32_I2S_VERR_REG: |
|---|
| 297 | + case STM32_I2S_IPIDR_REG: |
|---|
| 298 | + case STM32_I2S_SIDR_REG: |
|---|
| 282 | 299 | return true; |
|---|
| 283 | 300 | default: |
|---|
| 284 | 301 | return false; |
|---|
| .. | .. |
|---|
| 288 | 305 | static bool stm32_i2s_volatile_reg(struct device *dev, unsigned int reg) |
|---|
| 289 | 306 | { |
|---|
| 290 | 307 | switch (reg) { |
|---|
| 291 | | - case STM32_I2S_TXDR_REG: |
|---|
| 308 | + case STM32_I2S_SR_REG: |
|---|
| 292 | 309 | case STM32_I2S_RXDR_REG: |
|---|
| 293 | 310 | return true; |
|---|
| 294 | 311 | default: |
|---|
| .. | .. |
|---|
| 491 | 508 | unsigned int fthlv; |
|---|
| 492 | 509 | int ret; |
|---|
| 493 | 510 | |
|---|
| 494 | | - if ((params_channels(params) == 1) && |
|---|
| 495 | | - ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A)) { |
|---|
| 496 | | - dev_err(cpu_dai->dev, "Mono mode supported only by DSP_A\n"); |
|---|
| 497 | | - return -EINVAL; |
|---|
| 498 | | - } |
|---|
| 499 | | - |
|---|
| 500 | 511 | switch (format) { |
|---|
| 501 | 512 | case 16: |
|---|
| 502 | 513 | cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_16); |
|---|
| .. | .. |
|---|
| 539 | 550 | struct snd_soc_dai *cpu_dai) |
|---|
| 540 | 551 | { |
|---|
| 541 | 552 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
|---|
| 553 | + unsigned long flags; |
|---|
| 554 | + int ret; |
|---|
| 542 | 555 | |
|---|
| 556 | + spin_lock_irqsave(&i2s->irq_lock, flags); |
|---|
| 543 | 557 | i2s->substream = substream; |
|---|
| 558 | + spin_unlock_irqrestore(&i2s->irq_lock, flags); |
|---|
| 544 | 559 | |
|---|
| 545 | | - spin_lock(&i2s->lock_fd); |
|---|
| 546 | | - i2s->refcount++; |
|---|
| 547 | | - spin_unlock(&i2s->lock_fd); |
|---|
| 560 | + if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A) |
|---|
| 561 | + snd_pcm_hw_constraint_single(substream->runtime, |
|---|
| 562 | + SNDRV_PCM_HW_PARAM_CHANNELS, 2); |
|---|
| 563 | + |
|---|
| 564 | + ret = clk_prepare_enable(i2s->i2sclk); |
|---|
| 565 | + if (ret < 0) { |
|---|
| 566 | + dev_err(cpu_dai->dev, "Failed to enable clock: %d\n", ret); |
|---|
| 567 | + return ret; |
|---|
| 568 | + } |
|---|
| 548 | 569 | |
|---|
| 549 | 570 | return regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, |
|---|
| 550 | 571 | I2S_IFCR_MASK, I2S_IFCR_MASK); |
|---|
| .. | .. |
|---|
| 582 | 603 | case SNDRV_PCM_TRIGGER_RESUME: |
|---|
| 583 | 604 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
|---|
| 584 | 605 | /* Enable i2s */ |
|---|
| 585 | | - dev_dbg(cpu_dai->dev, "start I2S\n"); |
|---|
| 606 | + dev_dbg(cpu_dai->dev, "start I2S %s\n", |
|---|
| 607 | + playback_flg ? "playback" : "capture"); |
|---|
| 586 | 608 | |
|---|
| 587 | 609 | cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; |
|---|
| 588 | 610 | regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, |
|---|
| .. | .. |
|---|
| 595 | 617 | return ret; |
|---|
| 596 | 618 | } |
|---|
| 597 | 619 | |
|---|
| 598 | | - ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, |
|---|
| 599 | | - I2S_CR1_CSTART, I2S_CR1_CSTART); |
|---|
| 620 | + ret = regmap_write_bits(i2s->regmap, STM32_I2S_CR1_REG, |
|---|
| 621 | + I2S_CR1_CSTART, I2S_CR1_CSTART); |
|---|
| 600 | 622 | if (ret < 0) { |
|---|
| 601 | 623 | dev_err(cpu_dai->dev, "Error %d starting I2S\n", ret); |
|---|
| 602 | 624 | return ret; |
|---|
| .. | .. |
|---|
| 605 | 627 | regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, |
|---|
| 606 | 628 | I2S_IFCR_MASK, I2S_IFCR_MASK); |
|---|
| 607 | 629 | |
|---|
| 630 | + spin_lock(&i2s->lock_fd); |
|---|
| 631 | + i2s->refcount++; |
|---|
| 608 | 632 | if (playback_flg) { |
|---|
| 609 | 633 | ier = I2S_IER_UDRIE; |
|---|
| 610 | 634 | } else { |
|---|
| 611 | 635 | ier = I2S_IER_OVRIE; |
|---|
| 612 | 636 | |
|---|
| 613 | | - spin_lock(&i2s->lock_fd); |
|---|
| 614 | | - if (i2s->refcount == 1) |
|---|
| 615 | | - /* dummy write to trigger capture */ |
|---|
| 637 | + if (STM32_I2S_IS_MASTER(i2s) && i2s->refcount == 1) |
|---|
| 638 | + /* dummy write to gate bus clocks */ |
|---|
| 616 | 639 | regmap_write(i2s->regmap, |
|---|
| 617 | 640 | STM32_I2S_TXDR_REG, 0); |
|---|
| 618 | | - spin_unlock(&i2s->lock_fd); |
|---|
| 619 | 641 | } |
|---|
| 642 | + spin_unlock(&i2s->lock_fd); |
|---|
| 620 | 643 | |
|---|
| 621 | 644 | if (STM32_I2S_IS_SLAVE(i2s)) |
|---|
| 622 | 645 | ier |= I2S_IER_TIFREIE; |
|---|
| .. | .. |
|---|
| 626 | 649 | case SNDRV_PCM_TRIGGER_STOP: |
|---|
| 627 | 650 | case SNDRV_PCM_TRIGGER_SUSPEND: |
|---|
| 628 | 651 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
|---|
| 652 | + dev_dbg(cpu_dai->dev, "stop I2S %s\n", |
|---|
| 653 | + playback_flg ? "playback" : "capture"); |
|---|
| 654 | + |
|---|
| 629 | 655 | if (playback_flg) |
|---|
| 630 | 656 | regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, |
|---|
| 631 | 657 | I2S_IER_UDRIE, |
|---|
| .. | .. |
|---|
| 641 | 667 | spin_unlock(&i2s->lock_fd); |
|---|
| 642 | 668 | break; |
|---|
| 643 | 669 | } |
|---|
| 644 | | - spin_unlock(&i2s->lock_fd); |
|---|
| 645 | | - |
|---|
| 646 | | - dev_dbg(cpu_dai->dev, "stop I2S\n"); |
|---|
| 647 | 670 | |
|---|
| 648 | 671 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, |
|---|
| 649 | 672 | I2S_CR1_SPE, 0); |
|---|
| 650 | 673 | if (ret < 0) { |
|---|
| 651 | 674 | dev_err(cpu_dai->dev, "Error %d disabling I2S\n", ret); |
|---|
| 675 | + spin_unlock(&i2s->lock_fd); |
|---|
| 652 | 676 | return ret; |
|---|
| 653 | 677 | } |
|---|
| 678 | + spin_unlock(&i2s->lock_fd); |
|---|
| 654 | 679 | |
|---|
| 655 | 680 | cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; |
|---|
| 656 | 681 | regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, |
|---|
| .. | .. |
|---|
| 667 | 692 | struct snd_soc_dai *cpu_dai) |
|---|
| 668 | 693 | { |
|---|
| 669 | 694 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
|---|
| 670 | | - |
|---|
| 671 | | - i2s->substream = NULL; |
|---|
| 695 | + unsigned long flags; |
|---|
| 672 | 696 | |
|---|
| 673 | 697 | regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
|---|
| 674 | 698 | I2S_CGFR_MCKOE, (unsigned int)~I2S_CGFR_MCKOE); |
|---|
| 699 | + |
|---|
| 700 | + clk_disable_unprepare(i2s->i2sclk); |
|---|
| 701 | + |
|---|
| 702 | + spin_lock_irqsave(&i2s->irq_lock, flags); |
|---|
| 703 | + i2s->substream = NULL; |
|---|
| 704 | + spin_unlock_irqrestore(&i2s->irq_lock, flags); |
|---|
| 675 | 705 | } |
|---|
| 676 | 706 | |
|---|
| 677 | 707 | static int stm32_i2s_dai_probe(struct snd_soc_dai *cpu_dai) |
|---|
| .. | .. |
|---|
| 697 | 727 | .reg_bits = 32, |
|---|
| 698 | 728 | .reg_stride = 4, |
|---|
| 699 | 729 | .val_bits = 32, |
|---|
| 700 | | - .max_register = STM32_I2S_CGFR_REG, |
|---|
| 730 | + .max_register = STM32_I2S_SIDR_REG, |
|---|
| 701 | 731 | .readable_reg = stm32_i2s_readable_reg, |
|---|
| 702 | 732 | .volatile_reg = stm32_i2s_volatile_reg, |
|---|
| 703 | 733 | .writeable_reg = stm32_i2s_writeable_reg, |
|---|
| 734 | + .num_reg_defaults_raw = STM32_I2S_SIDR_REG / sizeof(u32) + 1, |
|---|
| 704 | 735 | .fast_io = true, |
|---|
| 736 | + .cache_type = REGCACHE_FLAT, |
|---|
| 705 | 737 | }; |
|---|
| 706 | 738 | |
|---|
| 707 | 739 | static const struct snd_soc_dai_ops stm32_i2s_pcm_dai_ops = { |
|---|
| .. | .. |
|---|
| 716 | 748 | static const struct snd_pcm_hardware stm32_i2s_pcm_hw = { |
|---|
| 717 | 749 | .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP, |
|---|
| 718 | 750 | .buffer_bytes_max = 8 * PAGE_SIZE, |
|---|
| 719 | | - .period_bytes_max = 2048, |
|---|
| 751 | + .period_bytes_min = 1024, |
|---|
| 752 | + .period_bytes_max = 4 * PAGE_SIZE, |
|---|
| 720 | 753 | .periods_min = 2, |
|---|
| 721 | 754 | .periods_max = 8, |
|---|
| 722 | 755 | }; |
|---|
| .. | .. |
|---|
| 752 | 785 | if (!dai_ptr) |
|---|
| 753 | 786 | return -ENOMEM; |
|---|
| 754 | 787 | |
|---|
| 755 | | - snprintf(i2s->dais_name, STM32_I2S_DAI_NAME_SIZE, |
|---|
| 756 | | - "%s", dev_name(&pdev->dev)); |
|---|
| 757 | | - |
|---|
| 758 | 788 | dai_ptr->probe = stm32_i2s_dai_probe; |
|---|
| 759 | 789 | dai_ptr->ops = &stm32_i2s_pcm_dai_ops; |
|---|
| 760 | | - dai_ptr->name = i2s->dais_name; |
|---|
| 761 | 790 | dai_ptr->id = 1; |
|---|
| 762 | 791 | stm32_i2s_dai_init(&dai_ptr->playback, "playback"); |
|---|
| 763 | 792 | stm32_i2s_dai_init(&dai_ptr->capture, "capture"); |
|---|
| .. | .. |
|---|
| 802 | 831 | /* Get clocks */ |
|---|
| 803 | 832 | i2s->pclk = devm_clk_get(&pdev->dev, "pclk"); |
|---|
| 804 | 833 | if (IS_ERR(i2s->pclk)) { |
|---|
| 805 | | - dev_err(&pdev->dev, "Could not get pclk\n"); |
|---|
| 834 | + if (PTR_ERR(i2s->pclk) != -EPROBE_DEFER) |
|---|
| 835 | + dev_err(&pdev->dev, "Could not get pclk: %ld\n", |
|---|
| 836 | + PTR_ERR(i2s->pclk)); |
|---|
| 806 | 837 | return PTR_ERR(i2s->pclk); |
|---|
| 807 | 838 | } |
|---|
| 808 | 839 | |
|---|
| 809 | 840 | i2s->i2sclk = devm_clk_get(&pdev->dev, "i2sclk"); |
|---|
| 810 | 841 | if (IS_ERR(i2s->i2sclk)) { |
|---|
| 811 | | - dev_err(&pdev->dev, "Could not get i2sclk\n"); |
|---|
| 842 | + if (PTR_ERR(i2s->i2sclk) != -EPROBE_DEFER) |
|---|
| 843 | + dev_err(&pdev->dev, "Could not get i2sclk: %ld\n", |
|---|
| 844 | + PTR_ERR(i2s->i2sclk)); |
|---|
| 812 | 845 | return PTR_ERR(i2s->i2sclk); |
|---|
| 813 | 846 | } |
|---|
| 814 | 847 | |
|---|
| 815 | 848 | i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k"); |
|---|
| 816 | 849 | if (IS_ERR(i2s->x8kclk)) { |
|---|
| 817 | | - dev_err(&pdev->dev, "missing x8k parent clock\n"); |
|---|
| 850 | + if (PTR_ERR(i2s->x8kclk) != -EPROBE_DEFER) |
|---|
| 851 | + dev_err(&pdev->dev, "Could not get x8k parent clock: %ld\n", |
|---|
| 852 | + PTR_ERR(i2s->x8kclk)); |
|---|
| 818 | 853 | return PTR_ERR(i2s->x8kclk); |
|---|
| 819 | 854 | } |
|---|
| 820 | 855 | |
|---|
| 821 | 856 | i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k"); |
|---|
| 822 | 857 | if (IS_ERR(i2s->x11kclk)) { |
|---|
| 823 | | - dev_err(&pdev->dev, "missing x11k parent clock\n"); |
|---|
| 858 | + if (PTR_ERR(i2s->x11kclk) != -EPROBE_DEFER) |
|---|
| 859 | + dev_err(&pdev->dev, "Could not get x11k parent clock: %ld\n", |
|---|
| 860 | + PTR_ERR(i2s->x11kclk)); |
|---|
| 824 | 861 | return PTR_ERR(i2s->x11kclk); |
|---|
| 825 | 862 | } |
|---|
| 826 | 863 | |
|---|
| 827 | 864 | /* Get irqs */ |
|---|
| 828 | 865 | irq = platform_get_irq(pdev, 0); |
|---|
| 829 | | - if (irq < 0) { |
|---|
| 830 | | - dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
|---|
| 831 | | - return -ENOENT; |
|---|
| 832 | | - } |
|---|
| 866 | + if (irq < 0) |
|---|
| 867 | + return irq; |
|---|
| 833 | 868 | |
|---|
| 834 | 869 | ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, |
|---|
| 835 | 870 | dev_name(&pdev->dev), i2s); |
|---|
| .. | .. |
|---|
| 839 | 874 | } |
|---|
| 840 | 875 | |
|---|
| 841 | 876 | /* Reset */ |
|---|
| 842 | | - rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
|---|
| 843 | | - if (!IS_ERR(rst)) { |
|---|
| 844 | | - reset_control_assert(rst); |
|---|
| 845 | | - udelay(2); |
|---|
| 846 | | - reset_control_deassert(rst); |
|---|
| 877 | + rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); |
|---|
| 878 | + if (IS_ERR(rst)) { |
|---|
| 879 | + if (PTR_ERR(rst) != -EPROBE_DEFER) |
|---|
| 880 | + dev_err(&pdev->dev, "Reset controller error %ld\n", |
|---|
| 881 | + PTR_ERR(rst)); |
|---|
| 882 | + return PTR_ERR(rst); |
|---|
| 847 | 883 | } |
|---|
| 884 | + reset_control_assert(rst); |
|---|
| 885 | + udelay(2); |
|---|
| 886 | + reset_control_deassert(rst); |
|---|
| 887 | + |
|---|
| 888 | + return 0; |
|---|
| 889 | +} |
|---|
| 890 | + |
|---|
| 891 | +static int stm32_i2s_remove(struct platform_device *pdev) |
|---|
| 892 | +{ |
|---|
| 893 | + snd_dmaengine_pcm_unregister(&pdev->dev); |
|---|
| 894 | + snd_soc_unregister_component(&pdev->dev); |
|---|
| 848 | 895 | |
|---|
| 849 | 896 | return 0; |
|---|
| 850 | 897 | } |
|---|
| .. | .. |
|---|
| 852 | 899 | static int stm32_i2s_probe(struct platform_device *pdev) |
|---|
| 853 | 900 | { |
|---|
| 854 | 901 | struct stm32_i2s_data *i2s; |
|---|
| 902 | + u32 val; |
|---|
| 855 | 903 | int ret; |
|---|
| 856 | 904 | |
|---|
| 857 | 905 | i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 865 | 913 | i2s->pdev = pdev; |
|---|
| 866 | 914 | i2s->ms_flg = I2S_MS_NOT_SET; |
|---|
| 867 | 915 | spin_lock_init(&i2s->lock_fd); |
|---|
| 916 | + spin_lock_init(&i2s->irq_lock); |
|---|
| 868 | 917 | platform_set_drvdata(pdev, i2s); |
|---|
| 869 | 918 | |
|---|
| 870 | 919 | ret = stm32_i2s_dais_init(pdev, i2s); |
|---|
| 871 | 920 | if (ret) |
|---|
| 872 | 921 | return ret; |
|---|
| 873 | 922 | |
|---|
| 874 | | - i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->base, |
|---|
| 875 | | - i2s->regmap_conf); |
|---|
| 923 | + i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk", |
|---|
| 924 | + i2s->base, i2s->regmap_conf); |
|---|
| 876 | 925 | if (IS_ERR(i2s->regmap)) { |
|---|
| 877 | | - dev_err(&pdev->dev, "regmap init failed\n"); |
|---|
| 926 | + if (PTR_ERR(i2s->regmap) != -EPROBE_DEFER) |
|---|
| 927 | + dev_err(&pdev->dev, "Regmap init error %ld\n", |
|---|
| 928 | + PTR_ERR(i2s->regmap)); |
|---|
| 878 | 929 | return PTR_ERR(i2s->regmap); |
|---|
| 879 | 930 | } |
|---|
| 880 | 931 | |
|---|
| 881 | | - ret = clk_prepare_enable(i2s->pclk); |
|---|
| 932 | + ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0); |
|---|
| 882 | 933 | if (ret) { |
|---|
| 883 | | - dev_err(&pdev->dev, "Enable pclk failed: %d\n", ret); |
|---|
| 934 | + if (ret != -EPROBE_DEFER) |
|---|
| 935 | + dev_err(&pdev->dev, "PCM DMA register error %d\n", ret); |
|---|
| 884 | 936 | return ret; |
|---|
| 885 | 937 | } |
|---|
| 886 | 938 | |
|---|
| 887 | | - ret = clk_prepare_enable(i2s->i2sclk); |
|---|
| 939 | + ret = snd_soc_register_component(&pdev->dev, &stm32_i2s_component, |
|---|
| 940 | + i2s->dai_drv, 1); |
|---|
| 888 | 941 | if (ret) { |
|---|
| 889 | | - dev_err(&pdev->dev, "Enable i2sclk failed: %d\n", ret); |
|---|
| 890 | | - goto err_pclk_disable; |
|---|
| 942 | + snd_dmaengine_pcm_unregister(&pdev->dev); |
|---|
| 943 | + return ret; |
|---|
| 891 | 944 | } |
|---|
| 892 | | - |
|---|
| 893 | | - ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component, |
|---|
| 894 | | - i2s->dai_drv, 1); |
|---|
| 895 | | - if (ret) |
|---|
| 896 | | - goto err_clocks_disable; |
|---|
| 897 | | - |
|---|
| 898 | | - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, |
|---|
| 899 | | - &stm32_i2s_pcm_config, 0); |
|---|
| 900 | | - if (ret) |
|---|
| 901 | | - goto err_clocks_disable; |
|---|
| 902 | 945 | |
|---|
| 903 | 946 | /* Set SPI/I2S in i2s mode */ |
|---|
| 904 | 947 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
|---|
| 905 | 948 | I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD); |
|---|
| 906 | 949 | if (ret) |
|---|
| 907 | | - goto err_clocks_disable; |
|---|
| 950 | + goto error; |
|---|
| 951 | + |
|---|
| 952 | + ret = regmap_read(i2s->regmap, STM32_I2S_IPIDR_REG, &val); |
|---|
| 953 | + if (ret) |
|---|
| 954 | + goto error; |
|---|
| 955 | + |
|---|
| 956 | + if (val == I2S_IPIDR_NUMBER) { |
|---|
| 957 | + ret = regmap_read(i2s->regmap, STM32_I2S_HWCFGR_REG, &val); |
|---|
| 958 | + if (ret) |
|---|
| 959 | + goto error; |
|---|
| 960 | + |
|---|
| 961 | + if (!FIELD_GET(I2S_HWCFGR_I2S_SUPPORT_MASK, val)) { |
|---|
| 962 | + dev_err(&pdev->dev, |
|---|
| 963 | + "Device does not support i2s mode\n"); |
|---|
| 964 | + ret = -EPERM; |
|---|
| 965 | + goto error; |
|---|
| 966 | + } |
|---|
| 967 | + |
|---|
| 968 | + ret = regmap_read(i2s->regmap, STM32_I2S_VERR_REG, &val); |
|---|
| 969 | + if (ret) |
|---|
| 970 | + goto error; |
|---|
| 971 | + |
|---|
| 972 | + dev_dbg(&pdev->dev, "I2S version: %lu.%lu registered\n", |
|---|
| 973 | + FIELD_GET(I2S_VERR_MAJ_MASK, val), |
|---|
| 974 | + FIELD_GET(I2S_VERR_MIN_MASK, val)); |
|---|
| 975 | + } |
|---|
| 908 | 976 | |
|---|
| 909 | 977 | return ret; |
|---|
| 910 | 978 | |
|---|
| 911 | | -err_clocks_disable: |
|---|
| 912 | | - clk_disable_unprepare(i2s->i2sclk); |
|---|
| 913 | | -err_pclk_disable: |
|---|
| 914 | | - clk_disable_unprepare(i2s->pclk); |
|---|
| 979 | +error: |
|---|
| 980 | + stm32_i2s_remove(pdev); |
|---|
| 915 | 981 | |
|---|
| 916 | 982 | return ret; |
|---|
| 917 | 983 | } |
|---|
| 918 | 984 | |
|---|
| 919 | | -static int stm32_i2s_remove(struct platform_device *pdev) |
|---|
| 920 | | -{ |
|---|
| 921 | | - struct stm32_i2s_data *i2s = platform_get_drvdata(pdev); |
|---|
| 985 | +MODULE_DEVICE_TABLE(of, stm32_i2s_ids); |
|---|
| 922 | 986 | |
|---|
| 923 | | - clk_disable_unprepare(i2s->i2sclk); |
|---|
| 924 | | - clk_disable_unprepare(i2s->pclk); |
|---|
| 987 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 988 | +static int stm32_i2s_suspend(struct device *dev) |
|---|
| 989 | +{ |
|---|
| 990 | + struct stm32_i2s_data *i2s = dev_get_drvdata(dev); |
|---|
| 991 | + |
|---|
| 992 | + regcache_cache_only(i2s->regmap, true); |
|---|
| 993 | + regcache_mark_dirty(i2s->regmap); |
|---|
| 925 | 994 | |
|---|
| 926 | 995 | return 0; |
|---|
| 927 | 996 | } |
|---|
| 928 | 997 | |
|---|
| 929 | | -MODULE_DEVICE_TABLE(of, stm32_i2s_ids); |
|---|
| 998 | +static int stm32_i2s_resume(struct device *dev) |
|---|
| 999 | +{ |
|---|
| 1000 | + struct stm32_i2s_data *i2s = dev_get_drvdata(dev); |
|---|
| 1001 | + |
|---|
| 1002 | + regcache_cache_only(i2s->regmap, false); |
|---|
| 1003 | + return regcache_sync(i2s->regmap); |
|---|
| 1004 | +} |
|---|
| 1005 | +#endif /* CONFIG_PM_SLEEP */ |
|---|
| 1006 | + |
|---|
| 1007 | +static const struct dev_pm_ops stm32_i2s_pm_ops = { |
|---|
| 1008 | + SET_SYSTEM_SLEEP_PM_OPS(stm32_i2s_suspend, stm32_i2s_resume) |
|---|
| 1009 | +}; |
|---|
| 930 | 1010 | |
|---|
| 931 | 1011 | static struct platform_driver stm32_i2s_driver = { |
|---|
| 932 | 1012 | .driver = { |
|---|
| 933 | 1013 | .name = "st,stm32-i2s", |
|---|
| 934 | 1014 | .of_match_table = stm32_i2s_ids, |
|---|
| 1015 | + .pm = &stm32_i2s_pm_ops, |
|---|
| 935 | 1016 | }, |
|---|
| 936 | 1017 | .probe = stm32_i2s_probe, |
|---|
| 937 | 1018 | .remove = stm32_i2s_remove, |
|---|