.. | .. |
---|
| 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, |
---|