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