1084 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * STM32 ALSA SoC Digital Audio Interface (SPDIF-rx) driver.4 *5 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved6 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.7 */8 9#include <linux/bitfield.h>10#include <linux/clk.h>11#include <linux/completion.h>12#include <linux/delay.h>13#include <linux/module.h>14#include <linux/of_platform.h>15#include <linux/pm_runtime.h>16#include <linux/regmap.h>17#include <linux/reset.h>18 19#include <sound/dmaengine_pcm.h>20#include <sound/pcm_params.h>21 22/* SPDIF-rx Register Map */23#define STM32_SPDIFRX_CR 0x0024#define STM32_SPDIFRX_IMR 0x0425#define STM32_SPDIFRX_SR 0x0826#define STM32_SPDIFRX_IFCR 0x0C27#define STM32_SPDIFRX_DR 0x1028#define STM32_SPDIFRX_CSR 0x1429#define STM32_SPDIFRX_DIR 0x1830#define STM32_SPDIFRX_VERR 0x3F431#define STM32_SPDIFRX_IDR 0x3F832#define STM32_SPDIFRX_SIDR 0x3FC33 34/* Bit definition for SPDIF_CR register */35#define SPDIFRX_CR_SPDIFEN_SHIFT 036#define SPDIFRX_CR_SPDIFEN_MASK GENMASK(1, SPDIFRX_CR_SPDIFEN_SHIFT)37#define SPDIFRX_CR_SPDIFENSET(x) ((x) << SPDIFRX_CR_SPDIFEN_SHIFT)38 39#define SPDIFRX_CR_RXDMAEN BIT(2)40#define SPDIFRX_CR_RXSTEO BIT(3)41 42#define SPDIFRX_CR_DRFMT_SHIFT 443#define SPDIFRX_CR_DRFMT_MASK GENMASK(5, SPDIFRX_CR_DRFMT_SHIFT)44#define SPDIFRX_CR_DRFMTSET(x) ((x) << SPDIFRX_CR_DRFMT_SHIFT)45 46#define SPDIFRX_CR_PMSK BIT(6)47#define SPDIFRX_CR_VMSK BIT(7)48#define SPDIFRX_CR_CUMSK BIT(8)49#define SPDIFRX_CR_PTMSK BIT(9)50#define SPDIFRX_CR_CBDMAEN BIT(10)51#define SPDIFRX_CR_CHSEL_SHIFT 1152#define SPDIFRX_CR_CHSEL BIT(SPDIFRX_CR_CHSEL_SHIFT)53 54#define SPDIFRX_CR_NBTR_SHIFT 1255#define SPDIFRX_CR_NBTR_MASK GENMASK(13, SPDIFRX_CR_NBTR_SHIFT)56#define SPDIFRX_CR_NBTRSET(x) ((x) << SPDIFRX_CR_NBTR_SHIFT)57 58#define SPDIFRX_CR_WFA BIT(14)59 60#define SPDIFRX_CR_INSEL_SHIFT 1661#define SPDIFRX_CR_INSEL_MASK GENMASK(18, PDIFRX_CR_INSEL_SHIFT)62#define SPDIFRX_CR_INSELSET(x) ((x) << SPDIFRX_CR_INSEL_SHIFT)63 64#define SPDIFRX_CR_CKSEN_SHIFT 2065#define SPDIFRX_CR_CKSEN BIT(20)66#define SPDIFRX_CR_CKSBKPEN BIT(21)67 68/* Bit definition for SPDIFRX_IMR register */69#define SPDIFRX_IMR_RXNEI BIT(0)70#define SPDIFRX_IMR_CSRNEIE BIT(1)71#define SPDIFRX_IMR_PERRIE BIT(2)72#define SPDIFRX_IMR_OVRIE BIT(3)73#define SPDIFRX_IMR_SBLKIE BIT(4)74#define SPDIFRX_IMR_SYNCDIE BIT(5)75#define SPDIFRX_IMR_IFEIE BIT(6)76 77#define SPDIFRX_XIMR_MASK GENMASK(6, 0)78 79/* Bit definition for SPDIFRX_SR register */80#define SPDIFRX_SR_RXNE BIT(0)81#define SPDIFRX_SR_CSRNE BIT(1)82#define SPDIFRX_SR_PERR BIT(2)83#define SPDIFRX_SR_OVR BIT(3)84#define SPDIFRX_SR_SBD BIT(4)85#define SPDIFRX_SR_SYNCD BIT(5)86#define SPDIFRX_SR_FERR BIT(6)87#define SPDIFRX_SR_SERR BIT(7)88#define SPDIFRX_SR_TERR BIT(8)89 90#define SPDIFRX_SR_WIDTH5_SHIFT 1691#define SPDIFRX_SR_WIDTH5_MASK GENMASK(30, PDIFRX_SR_WIDTH5_SHIFT)92#define SPDIFRX_SR_WIDTH5SET(x) ((x) << SPDIFRX_SR_WIDTH5_SHIFT)93 94/* Bit definition for SPDIFRX_IFCR register */95#define SPDIFRX_IFCR_PERRCF BIT(2)96#define SPDIFRX_IFCR_OVRCF BIT(3)97#define SPDIFRX_IFCR_SBDCF BIT(4)98#define SPDIFRX_IFCR_SYNCDCF BIT(5)99 100#define SPDIFRX_XIFCR_MASK GENMASK(5, 2)101 102/* Bit definition for SPDIFRX_DR register (DRFMT = 0b00) */103#define SPDIFRX_DR0_DR_SHIFT 0104#define SPDIFRX_DR0_DR_MASK GENMASK(23, SPDIFRX_DR0_DR_SHIFT)105#define SPDIFRX_DR0_DRSET(x) ((x) << SPDIFRX_DR0_DR_SHIFT)106 107#define SPDIFRX_DR0_PE BIT(24)108 109#define SPDIFRX_DR0_V BIT(25)110#define SPDIFRX_DR0_U BIT(26)111#define SPDIFRX_DR0_C BIT(27)112 113#define SPDIFRX_DR0_PT_SHIFT 28114#define SPDIFRX_DR0_PT_MASK GENMASK(29, SPDIFRX_DR0_PT_SHIFT)115#define SPDIFRX_DR0_PTSET(x) ((x) << SPDIFRX_DR0_PT_SHIFT)116 117/* Bit definition for SPDIFRX_DR register (DRFMT = 0b01) */118#define SPDIFRX_DR1_PE BIT(0)119#define SPDIFRX_DR1_V BIT(1)120#define SPDIFRX_DR1_U BIT(2)121#define SPDIFRX_DR1_C BIT(3)122 123#define SPDIFRX_DR1_PT_SHIFT 4124#define SPDIFRX_DR1_PT_MASK GENMASK(5, SPDIFRX_DR1_PT_SHIFT)125#define SPDIFRX_DR1_PTSET(x) ((x) << SPDIFRX_DR1_PT_SHIFT)126 127#define SPDIFRX_DR1_DR_SHIFT 8128#define SPDIFRX_DR1_DR_MASK GENMASK(31, SPDIFRX_DR1_DR_SHIFT)129#define SPDIFRX_DR1_DRSET(x) ((x) << SPDIFRX_DR1_DR_SHIFT)130 131/* Bit definition for SPDIFRX_DR register (DRFMT = 0b10) */132#define SPDIFRX_DR1_DRNL1_SHIFT 0133#define SPDIFRX_DR1_DRNL1_MASK GENMASK(15, SPDIFRX_DR1_DRNL1_SHIFT)134#define SPDIFRX_DR1_DRNL1SET(x) ((x) << SPDIFRX_DR1_DRNL1_SHIFT)135 136#define SPDIFRX_DR1_DRNL2_SHIFT 16137#define SPDIFRX_DR1_DRNL2_MASK GENMASK(31, SPDIFRX_DR1_DRNL2_SHIFT)138#define SPDIFRX_DR1_DRNL2SET(x) ((x) << SPDIFRX_DR1_DRNL2_SHIFT)139 140/* Bit definition for SPDIFRX_CSR register */141#define SPDIFRX_CSR_USR_SHIFT 0142#define SPDIFRX_CSR_USR_MASK GENMASK(15, SPDIFRX_CSR_USR_SHIFT)143#define SPDIFRX_CSR_USRGET(x) (((x) & SPDIFRX_CSR_USR_MASK)\144 >> SPDIFRX_CSR_USR_SHIFT)145 146#define SPDIFRX_CSR_CS_SHIFT 16147#define SPDIFRX_CSR_CS_MASK GENMASK(23, SPDIFRX_CSR_CS_SHIFT)148#define SPDIFRX_CSR_CSGET(x) (((x) & SPDIFRX_CSR_CS_MASK)\149 >> SPDIFRX_CSR_CS_SHIFT)150 151#define SPDIFRX_CSR_SOB BIT(24)152 153/* Bit definition for SPDIFRX_DIR register */154#define SPDIFRX_DIR_THI_SHIFT 0155#define SPDIFRX_DIR_THI_MASK GENMASK(12, SPDIFRX_DIR_THI_SHIFT)156#define SPDIFRX_DIR_THI_SET(x) ((x) << SPDIFRX_DIR_THI_SHIFT)157 158#define SPDIFRX_DIR_TLO_SHIFT 16159#define SPDIFRX_DIR_TLO_MASK GENMASK(28, SPDIFRX_DIR_TLO_SHIFT)160#define SPDIFRX_DIR_TLO_SET(x) ((x) << SPDIFRX_DIR_TLO_SHIFT)161 162#define SPDIFRX_SPDIFEN_DISABLE 0x0163#define SPDIFRX_SPDIFEN_SYNC 0x1164#define SPDIFRX_SPDIFEN_ENABLE 0x3165 166/* Bit definition for SPDIFRX_VERR register */167#define SPDIFRX_VERR_MIN_MASK GENMASK(3, 0)168#define SPDIFRX_VERR_MAJ_MASK GENMASK(7, 4)169 170/* Bit definition for SPDIFRX_IDR register */171#define SPDIFRX_IDR_ID_MASK GENMASK(31, 0)172 173/* Bit definition for SPDIFRX_SIDR register */174#define SPDIFRX_SIDR_SID_MASK GENMASK(31, 0)175 176#define SPDIFRX_IPIDR_NUMBER 0x00130041177 178#define SPDIFRX_IN1 0x1179#define SPDIFRX_IN2 0x2180#define SPDIFRX_IN3 0x3181#define SPDIFRX_IN4 0x4182#define SPDIFRX_IN5 0x5183#define SPDIFRX_IN6 0x6184#define SPDIFRX_IN7 0x7185#define SPDIFRX_IN8 0x8186 187#define SPDIFRX_NBTR_NONE 0x0188#define SPDIFRX_NBTR_3 0x1189#define SPDIFRX_NBTR_15 0x2190#define SPDIFRX_NBTR_63 0x3191 192#define SPDIFRX_DRFMT_RIGHT 0x0193#define SPDIFRX_DRFMT_LEFT 0x1194#define SPDIFRX_DRFMT_PACKED 0x2195 196/* 192 CS bits in S/PDIF frame. i.e 24 CS bytes */197#define SPDIFRX_CS_BYTES_NB 24198#define SPDIFRX_UB_BYTES_NB 48199 200/*201 * CSR register is retrieved as a 32 bits word202 * It contains 1 channel status byte and 2 user data bytes203 * 2 S/PDIF frames are acquired to get all CS/UB bits204 */205#define SPDIFRX_CSR_BUF_LENGTH (SPDIFRX_CS_BYTES_NB * 4 * 2)206 207/**208 * struct stm32_spdifrx_data - private data of SPDIFRX209 * @pdev: device data pointer210 * @base: mmio register base virtual address211 * @regmap: SPDIFRX register map pointer212 * @regmap_conf: SPDIFRX register map configuration pointer213 * @cs_completion: channel status retrieving completion214 * @kclk: kernel clock feeding the SPDIFRX clock generator215 * @dma_params: dma configuration data for rx channel216 * @substream: PCM substream data pointer217 * @dmab: dma buffer info pointer218 * @ctrl_chan: dma channel for S/PDIF control bits219 * @desc:dma async transaction descriptor220 * @slave_config: dma slave channel runtime config pointer221 * @phys_addr: SPDIFRX registers physical base address222 * @lock: synchronization enabling lock223 * @irq_lock: prevent race condition with IRQ on stream state224 * @cs: channel status buffer225 * @ub: user data buffer226 * @irq: SPDIFRX interrupt line227 * @refcount: keep count of opened DMA channels228 */229struct stm32_spdifrx_data {230 struct platform_device *pdev;231 void __iomem *base;232 struct regmap *regmap;233 const struct regmap_config *regmap_conf;234 struct completion cs_completion;235 struct clk *kclk;236 struct snd_dmaengine_dai_dma_data dma_params;237 struct snd_pcm_substream *substream;238 struct snd_dma_buffer *dmab;239 struct dma_chan *ctrl_chan;240 struct dma_async_tx_descriptor *desc;241 struct dma_slave_config slave_config;242 dma_addr_t phys_addr;243 spinlock_t lock; /* Sync enabling lock */244 spinlock_t irq_lock; /* Prevent race condition on stream state */245 unsigned char cs[SPDIFRX_CS_BYTES_NB];246 unsigned char ub[SPDIFRX_UB_BYTES_NB];247 int irq;248 int refcount;249};250 251static void stm32_spdifrx_dma_complete(void *data)252{253 struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)data;254 struct platform_device *pdev = spdifrx->pdev;255 u32 *p_start = (u32 *)spdifrx->dmab->area;256 u32 *p_end = p_start + (2 * SPDIFRX_CS_BYTES_NB) - 1;257 u32 *ptr = p_start;258 u16 *ub_ptr = (short *)spdifrx->ub;259 int i = 0;260 261 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,262 SPDIFRX_CR_CBDMAEN,263 (unsigned int)~SPDIFRX_CR_CBDMAEN);264 265 if (!spdifrx->dmab->area)266 return;267 268 while (ptr <= p_end) {269 if (*ptr & SPDIFRX_CSR_SOB)270 break;271 ptr++;272 }273 274 if (ptr > p_end) {275 dev_err(&pdev->dev, "Start of S/PDIF block not found\n");276 return;277 }278 279 while (i < SPDIFRX_CS_BYTES_NB) {280 spdifrx->cs[i] = (unsigned char)SPDIFRX_CSR_CSGET(*ptr);281 *ub_ptr++ = SPDIFRX_CSR_USRGET(*ptr++);282 if (ptr > p_end) {283 dev_err(&pdev->dev, "Failed to get channel status\n");284 return;285 }286 i++;287 }288 289 complete(&spdifrx->cs_completion);290}291 292static int stm32_spdifrx_dma_ctrl_start(struct stm32_spdifrx_data *spdifrx)293{294 dma_cookie_t cookie;295 int err;296 297 spdifrx->desc = dmaengine_prep_slave_single(spdifrx->ctrl_chan,298 spdifrx->dmab->addr,299 SPDIFRX_CSR_BUF_LENGTH,300 DMA_DEV_TO_MEM,301 DMA_CTRL_ACK);302 if (!spdifrx->desc)303 return -EINVAL;304 305 spdifrx->desc->callback = stm32_spdifrx_dma_complete;306 spdifrx->desc->callback_param = spdifrx;307 cookie = dmaengine_submit(spdifrx->desc);308 err = dma_submit_error(cookie);309 if (err)310 return -EINVAL;311 312 dma_async_issue_pending(spdifrx->ctrl_chan);313 314 return 0;315}316 317static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)318{319 dmaengine_terminate_async(spdifrx->ctrl_chan);320}321 322static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)323{324 int cr, cr_mask, imr, ret;325 unsigned long flags;326 327 /* Enable IRQs */328 imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE;329 ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR, imr, imr);330 if (ret)331 return ret;332 333 spin_lock_irqsave(&spdifrx->lock, flags);334 335 spdifrx->refcount++;336 337 regmap_read(spdifrx->regmap, STM32_SPDIFRX_CR, &cr);338 339 if (!(cr & SPDIFRX_CR_SPDIFEN_MASK)) {340 /*341 * Start sync if SPDIFRX is still in idle state.342 * SPDIFRX reception enabled when sync done343 */344 dev_dbg(&spdifrx->pdev->dev, "start synchronization\n");345 346 /*347 * SPDIFRX configuration:348 * Wait for activity before starting sync process. This avoid349 * to issue sync errors when spdif signal is missing on input.350 * Preamble, CS, user, validity and parity error bits not copied351 * to DR register.352 */353 cr = SPDIFRX_CR_WFA | SPDIFRX_CR_PMSK | SPDIFRX_CR_VMSK |354 SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK | SPDIFRX_CR_RXSTEO;355 cr_mask = cr;356 357 cr |= SPDIFRX_CR_NBTRSET(SPDIFRX_NBTR_63);358 cr_mask |= SPDIFRX_CR_NBTR_MASK;359 cr |= SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_SYNC);360 cr_mask |= SPDIFRX_CR_SPDIFEN_MASK;361 ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,362 cr_mask, cr);363 if (ret < 0)364 dev_err(&spdifrx->pdev->dev,365 "Failed to start synchronization\n");366 }367 368 spin_unlock_irqrestore(&spdifrx->lock, flags);369 370 return ret;371}372 373static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)374{375 int cr, cr_mask, reg;376 unsigned long flags;377 378 spin_lock_irqsave(&spdifrx->lock, flags);379 380 if (--spdifrx->refcount) {381 spin_unlock_irqrestore(&spdifrx->lock, flags);382 return;383 }384 385 cr = SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_DISABLE);386 cr_mask = SPDIFRX_CR_SPDIFEN_MASK | SPDIFRX_CR_RXDMAEN;387 388 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, cr_mask, cr);389 390 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR,391 SPDIFRX_XIMR_MASK, 0);392 393 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IFCR,394 SPDIFRX_XIFCR_MASK, SPDIFRX_XIFCR_MASK);395 396 /* dummy read to clear CSRNE and RXNE in status register */397 regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, ®);398 regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, ®);399 400 spin_unlock_irqrestore(&spdifrx->lock, flags);401}402 403static int stm32_spdifrx_dma_ctrl_register(struct device *dev,404 struct stm32_spdifrx_data *spdifrx)405{406 int ret;407 408 spdifrx->ctrl_chan = dma_request_chan(dev, "rx-ctrl");409 if (IS_ERR(spdifrx->ctrl_chan))410 return dev_err_probe(dev, PTR_ERR(spdifrx->ctrl_chan),411 "dma_request_slave_channel error\n");412 413 spdifrx->dmab = devm_kzalloc(dev, sizeof(struct snd_dma_buffer),414 GFP_KERNEL);415 if (!spdifrx->dmab)416 return -ENOMEM;417 418 spdifrx->dmab->dev.type = SNDRV_DMA_TYPE_DEV_IRAM;419 spdifrx->dmab->dev.dev = dev;420 ret = snd_dma_alloc_pages(spdifrx->dmab->dev.type, dev,421 SPDIFRX_CSR_BUF_LENGTH, spdifrx->dmab);422 if (ret < 0) {423 dev_err(dev, "snd_dma_alloc_pages returned error %d\n", ret);424 return ret;425 }426 427 spdifrx->slave_config.direction = DMA_DEV_TO_MEM;428 spdifrx->slave_config.src_addr = (dma_addr_t)(spdifrx->phys_addr +429 STM32_SPDIFRX_CSR);430 spdifrx->slave_config.dst_addr = spdifrx->dmab->addr;431 spdifrx->slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;432 spdifrx->slave_config.src_maxburst = 1;433 434 ret = dmaengine_slave_config(spdifrx->ctrl_chan,435 &spdifrx->slave_config);436 if (ret < 0) {437 dev_err(dev, "dmaengine_slave_config returned error %d\n", ret);438 spdifrx->ctrl_chan = NULL;439 }440 441 return ret;442};443 444static const char * const spdifrx_enum_input[] = {445 "in0", "in1", "in2", "in3"446};447 448/* By default CS bits are retrieved from channel A */449static const char * const spdifrx_enum_cs_channel[] = {450 "A", "B"451};452 453static SOC_ENUM_SINGLE_DECL(ctrl_enum_input,454 STM32_SPDIFRX_CR, SPDIFRX_CR_INSEL_SHIFT,455 spdifrx_enum_input);456 457static SOC_ENUM_SINGLE_DECL(ctrl_enum_cs_channel,458 STM32_SPDIFRX_CR, SPDIFRX_CR_CHSEL_SHIFT,459 spdifrx_enum_cs_channel);460 461static int stm32_spdifrx_info(struct snd_kcontrol *kcontrol,462 struct snd_ctl_elem_info *uinfo)463{464 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;465 uinfo->count = 1;466 467 return 0;468}469 470static int stm32_spdifrx_ub_info(struct snd_kcontrol *kcontrol,471 struct snd_ctl_elem_info *uinfo)472{473 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;474 uinfo->count = 1;475 476 return 0;477}478 479static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)480{481 int ret = 0;482 483 memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB);484 memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB);485 486 ret = stm32_spdifrx_dma_ctrl_start(spdifrx);487 if (ret < 0)488 return ret;489 490 ret = clk_prepare_enable(spdifrx->kclk);491 if (ret) {492 dev_err(&spdifrx->pdev->dev, "Enable kclk failed: %d\n", ret);493 return ret;494 }495 496 ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,497 SPDIFRX_CR_CBDMAEN, SPDIFRX_CR_CBDMAEN);498 if (ret < 0)499 goto end;500 501 ret = stm32_spdifrx_start_sync(spdifrx);502 if (ret < 0)503 goto end;504 505 if (wait_for_completion_interruptible_timeout(&spdifrx->cs_completion,506 msecs_to_jiffies(100))507 <= 0) {508 dev_dbg(&spdifrx->pdev->dev, "Failed to get control data\n");509 ret = -EAGAIN;510 }511 512 stm32_spdifrx_stop(spdifrx);513 stm32_spdifrx_dma_ctrl_stop(spdifrx);514 515end:516 clk_disable_unprepare(spdifrx->kclk);517 518 return ret;519}520 521static int stm32_spdifrx_capture_get(struct snd_kcontrol *kcontrol,522 struct snd_ctl_elem_value *ucontrol)523{524 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);525 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);526 527 stm32_spdifrx_get_ctrl_data(spdifrx);528 529 ucontrol->value.iec958.status[0] = spdifrx->cs[0];530 ucontrol->value.iec958.status[1] = spdifrx->cs[1];531 ucontrol->value.iec958.status[2] = spdifrx->cs[2];532 ucontrol->value.iec958.status[3] = spdifrx->cs[3];533 ucontrol->value.iec958.status[4] = spdifrx->cs[4];534 535 return 0;536}537 538static int stm32_spdif_user_bits_get(struct snd_kcontrol *kcontrol,539 struct snd_ctl_elem_value *ucontrol)540{541 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);542 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);543 544 stm32_spdifrx_get_ctrl_data(spdifrx);545 546 ucontrol->value.iec958.status[0] = spdifrx->ub[0];547 ucontrol->value.iec958.status[1] = spdifrx->ub[1];548 ucontrol->value.iec958.status[2] = spdifrx->ub[2];549 ucontrol->value.iec958.status[3] = spdifrx->ub[3];550 ucontrol->value.iec958.status[4] = spdifrx->ub[4];551 552 return 0;553}554 555static struct snd_kcontrol_new stm32_spdifrx_iec_ctrls[] = {556 /* Channel status control */557 {558 .iface = SNDRV_CTL_ELEM_IFACE_PCM,559 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),560 .access = SNDRV_CTL_ELEM_ACCESS_READ |561 SNDRV_CTL_ELEM_ACCESS_VOLATILE,562 .info = stm32_spdifrx_info,563 .get = stm32_spdifrx_capture_get,564 },565 /* User bits control */566 {567 .iface = SNDRV_CTL_ELEM_IFACE_PCM,568 .name = "IEC958 User Bit Capture Default",569 .access = SNDRV_CTL_ELEM_ACCESS_READ |570 SNDRV_CTL_ELEM_ACCESS_VOLATILE,571 .info = stm32_spdifrx_ub_info,572 .get = stm32_spdif_user_bits_get,573 },574};575 576static struct snd_kcontrol_new stm32_spdifrx_ctrls[] = {577 SOC_ENUM("SPDIFRX input", ctrl_enum_input),578 SOC_ENUM("SPDIFRX CS channel", ctrl_enum_cs_channel),579};580 581static int stm32_spdifrx_dai_register_ctrls(struct snd_soc_dai *cpu_dai)582{583 int ret;584 585 ret = snd_soc_add_dai_controls(cpu_dai, stm32_spdifrx_iec_ctrls,586 ARRAY_SIZE(stm32_spdifrx_iec_ctrls));587 if (ret < 0)588 return ret;589 590 return snd_soc_add_component_controls(cpu_dai->component,591 stm32_spdifrx_ctrls,592 ARRAY_SIZE(stm32_spdifrx_ctrls));593}594 595static int stm32_spdifrx_dai_probe(struct snd_soc_dai *cpu_dai)596{597 struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(cpu_dai->dev);598 599 spdifrx->dma_params.addr = (dma_addr_t)(spdifrx->phys_addr +600 STM32_SPDIFRX_DR);601 spdifrx->dma_params.maxburst = 1;602 603 snd_soc_dai_init_dma_data(cpu_dai, NULL, &spdifrx->dma_params);604 605 return stm32_spdifrx_dai_register_ctrls(cpu_dai);606}607 608static bool stm32_spdifrx_readable_reg(struct device *dev, unsigned int reg)609{610 switch (reg) {611 case STM32_SPDIFRX_CR:612 case STM32_SPDIFRX_IMR:613 case STM32_SPDIFRX_SR:614 case STM32_SPDIFRX_IFCR:615 case STM32_SPDIFRX_DR:616 case STM32_SPDIFRX_CSR:617 case STM32_SPDIFRX_DIR:618 case STM32_SPDIFRX_VERR:619 case STM32_SPDIFRX_IDR:620 case STM32_SPDIFRX_SIDR:621 return true;622 default:623 return false;624 }625}626 627static bool stm32_spdifrx_volatile_reg(struct device *dev, unsigned int reg)628{629 switch (reg) {630 case STM32_SPDIFRX_DR:631 case STM32_SPDIFRX_CSR:632 case STM32_SPDIFRX_SR:633 case STM32_SPDIFRX_DIR:634 return true;635 default:636 return false;637 }638}639 640static bool stm32_spdifrx_writeable_reg(struct device *dev, unsigned int reg)641{642 switch (reg) {643 case STM32_SPDIFRX_CR:644 case STM32_SPDIFRX_IMR:645 case STM32_SPDIFRX_IFCR:646 return true;647 default:648 return false;649 }650}651 652static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {653 .reg_bits = 32,654 .reg_stride = 4,655 .val_bits = 32,656 .max_register = STM32_SPDIFRX_SIDR,657 .readable_reg = stm32_spdifrx_readable_reg,658 .volatile_reg = stm32_spdifrx_volatile_reg,659 .writeable_reg = stm32_spdifrx_writeable_reg,660 .num_reg_defaults_raw = STM32_SPDIFRX_SIDR / sizeof(u32) + 1,661 .fast_io = true,662 .cache_type = REGCACHE_FLAT,663};664 665static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)666{667 struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid;668 struct platform_device *pdev = spdifrx->pdev;669 unsigned int cr, mask, sr, imr;670 unsigned int flags, sync_state;671 int err = 0, err_xrun = 0;672 673 regmap_read(spdifrx->regmap, STM32_SPDIFRX_SR, &sr);674 regmap_read(spdifrx->regmap, STM32_SPDIFRX_IMR, &imr);675 676 mask = imr & SPDIFRX_XIMR_MASK;677 /* SERR, TERR, FERR IRQs are generated if IFEIE is set */678 if (mask & SPDIFRX_IMR_IFEIE)679 mask |= (SPDIFRX_IMR_IFEIE << 1) | (SPDIFRX_IMR_IFEIE << 2);680 681 flags = sr & mask;682 if (!flags) {683 dev_err(&pdev->dev, "Unexpected IRQ. rflags=%#x, imr=%#x\n",684 sr, imr);685 return IRQ_NONE;686 }687 688 /* Clear IRQs */689 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IFCR,690 SPDIFRX_XIFCR_MASK, flags);691 692 if (flags & SPDIFRX_SR_PERR) {693 dev_dbg(&pdev->dev, "Parity error\n");694 err_xrun = 1;695 }696 697 if (flags & SPDIFRX_SR_OVR) {698 dev_dbg(&pdev->dev, "Overrun error\n");699 err_xrun = 1;700 }701 702 if (flags & SPDIFRX_SR_SBD)703 dev_dbg(&pdev->dev, "Synchronization block detected\n");704 705 if (flags & SPDIFRX_SR_SYNCD) {706 dev_dbg(&pdev->dev, "Synchronization done\n");707 708 /* Enable spdifrx */709 cr = SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_ENABLE);710 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,711 SPDIFRX_CR_SPDIFEN_MASK, cr);712 }713 714 if (flags & SPDIFRX_SR_FERR) {715 dev_dbg(&pdev->dev, "Frame error\n");716 err = 1;717 }718 719 if (flags & SPDIFRX_SR_SERR) {720 dev_dbg(&pdev->dev, "Synchronization error\n");721 err = 1;722 }723 724 if (flags & SPDIFRX_SR_TERR) {725 dev_dbg(&pdev->dev, "Timeout error\n");726 err = 1;727 }728 729 if (err) {730 regmap_read(spdifrx->regmap, STM32_SPDIFRX_CR, &cr);731 sync_state = FIELD_GET(SPDIFRX_CR_SPDIFEN_MASK, cr) &&732 SPDIFRX_SPDIFEN_SYNC;733 734 /* SPDIFRX is in STATE_STOP. Disable SPDIFRX to clear errors */735 cr = SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_DISABLE);736 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,737 SPDIFRX_CR_SPDIFEN_MASK, cr);738 739 /* If SPDIFRX was in STATE_SYNC, retry synchro */740 if (sync_state) {741 cr = SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_SYNC);742 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,743 SPDIFRX_CR_SPDIFEN_MASK, cr);744 return IRQ_HANDLED;745 }746 747 spin_lock(&spdifrx->irq_lock);748 if (spdifrx->substream)749 snd_pcm_stop(spdifrx->substream,750 SNDRV_PCM_STATE_DISCONNECTED);751 spin_unlock(&spdifrx->irq_lock);752 753 return IRQ_HANDLED;754 }755 756 spin_lock(&spdifrx->irq_lock);757 if (err_xrun && spdifrx->substream)758 snd_pcm_stop_xrun(spdifrx->substream);759 spin_unlock(&spdifrx->irq_lock);760 761 return IRQ_HANDLED;762}763 764static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,765 struct snd_soc_dai *cpu_dai)766{767 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);768 unsigned long flags;769 int ret;770 771 spin_lock_irqsave(&spdifrx->irq_lock, flags);772 spdifrx->substream = substream;773 spin_unlock_irqrestore(&spdifrx->irq_lock, flags);774 775 ret = clk_prepare_enable(spdifrx->kclk);776 if (ret)777 dev_err(&spdifrx->pdev->dev, "Enable kclk failed: %d\n", ret);778 779 return ret;780}781 782static int stm32_spdifrx_hw_params(struct snd_pcm_substream *substream,783 struct snd_pcm_hw_params *params,784 struct snd_soc_dai *cpu_dai)785{786 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);787 int data_size = params_width(params);788 int fmt;789 790 switch (data_size) {791 case 16:792 fmt = SPDIFRX_DRFMT_PACKED;793 break;794 case 32:795 fmt = SPDIFRX_DRFMT_LEFT;796 break;797 default:798 dev_err(&spdifrx->pdev->dev, "Unexpected data format\n");799 return -EINVAL;800 }801 802 /*803 * Set buswidth to 4 bytes for all data formats.804 * Packed format: transfer 2 x 2 bytes samples805 * Left format: transfer 1 x 3 bytes samples + 1 dummy byte806 */807 spdifrx->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;808 snd_soc_dai_init_dma_data(cpu_dai, NULL, &spdifrx->dma_params);809 810 return regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,811 SPDIFRX_CR_DRFMT_MASK,812 SPDIFRX_CR_DRFMTSET(fmt));813}814 815static int stm32_spdifrx_trigger(struct snd_pcm_substream *substream, int cmd,816 struct snd_soc_dai *cpu_dai)817{818 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);819 int ret = 0;820 821 switch (cmd) {822 case SNDRV_PCM_TRIGGER_START:823 case SNDRV_PCM_TRIGGER_RESUME:824 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:825 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR,826 SPDIFRX_IMR_OVRIE, SPDIFRX_IMR_OVRIE);827 828 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR,829 SPDIFRX_CR_RXDMAEN, SPDIFRX_CR_RXDMAEN);830 831 ret = stm32_spdifrx_start_sync(spdifrx);832 break;833 case SNDRV_PCM_TRIGGER_SUSPEND:834 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:835 case SNDRV_PCM_TRIGGER_STOP:836 stm32_spdifrx_stop(spdifrx);837 break;838 default:839 return -EINVAL;840 }841 842 return ret;843}844 845static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,846 struct snd_soc_dai *cpu_dai)847{848 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);849 unsigned long flags;850 851 spin_lock_irqsave(&spdifrx->irq_lock, flags);852 spdifrx->substream = NULL;853 spin_unlock_irqrestore(&spdifrx->irq_lock, flags);854 855 clk_disable_unprepare(spdifrx->kclk);856}857 858static const struct snd_soc_dai_ops stm32_spdifrx_pcm_dai_ops = {859 .probe = stm32_spdifrx_dai_probe,860 .startup = stm32_spdifrx_startup,861 .hw_params = stm32_spdifrx_hw_params,862 .trigger = stm32_spdifrx_trigger,863 .shutdown = stm32_spdifrx_shutdown,864};865 866static struct snd_soc_dai_driver stm32_spdifrx_dai[] = {867 {868 .capture = {869 .stream_name = "CPU-Capture",870 .channels_min = 1,871 .channels_max = 2,872 .rates = SNDRV_PCM_RATE_8000_192000,873 .formats = SNDRV_PCM_FMTBIT_S32_LE |874 SNDRV_PCM_FMTBIT_S16_LE,875 },876 .ops = &stm32_spdifrx_pcm_dai_ops,877 }878};879 880static const struct snd_pcm_hardware stm32_spdifrx_pcm_hw = {881 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,882 .buffer_bytes_max = 8 * PAGE_SIZE,883 .period_bytes_min = 1024,884 .period_bytes_max = 4 * PAGE_SIZE,885 .periods_min = 2,886 .periods_max = 8,887};888 889static const struct snd_soc_component_driver stm32_spdifrx_component = {890 .name = "stm32-spdifrx",891 .legacy_dai_naming = 1,892};893 894static const struct snd_dmaengine_pcm_config stm32_spdifrx_pcm_config = {895 .pcm_hardware = &stm32_spdifrx_pcm_hw,896 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,897};898 899static const struct of_device_id stm32_spdifrx_ids[] = {900 {901 .compatible = "st,stm32h7-spdifrx",902 .data = &stm32_h7_spdifrx_regmap_conf903 },904 {}905};906 907static int stm32_spdifrx_parse_of(struct platform_device *pdev,908 struct stm32_spdifrx_data *spdifrx)909{910 struct device_node *np = pdev->dev.of_node;911 struct resource *res;912 913 if (!np)914 return -ENODEV;915 916 spdifrx->regmap_conf = device_get_match_data(&pdev->dev);917 if (!spdifrx->regmap_conf)918 return -EINVAL;919 920 spdifrx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);921 if (IS_ERR(spdifrx->base))922 return PTR_ERR(spdifrx->base);923 924 spdifrx->phys_addr = res->start;925 926 spdifrx->kclk = devm_clk_get(&pdev->dev, "kclk");927 if (IS_ERR(spdifrx->kclk))928 return dev_err_probe(&pdev->dev, PTR_ERR(spdifrx->kclk),929 "Could not get kclk\n");930 931 spdifrx->irq = platform_get_irq(pdev, 0);932 if (spdifrx->irq < 0)933 return spdifrx->irq;934 935 return 0;936}937 938static void stm32_spdifrx_remove(struct platform_device *pdev)939{940 struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev);941 942 if (!IS_ERR(spdifrx->ctrl_chan))943 dma_release_channel(spdifrx->ctrl_chan);944 945 if (spdifrx->dmab)946 snd_dma_free_pages(spdifrx->dmab);947 948 snd_dmaengine_pcm_unregister(&pdev->dev);949 snd_soc_unregister_component(&pdev->dev);950 pm_runtime_disable(&pdev->dev);951}952 953static int stm32_spdifrx_probe(struct platform_device *pdev)954{955 struct stm32_spdifrx_data *spdifrx;956 struct reset_control *rst;957 const struct snd_dmaengine_pcm_config *pcm_config = NULL;958 u32 ver, idr;959 int ret;960 961 spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);962 if (!spdifrx)963 return -ENOMEM;964 965 spdifrx->pdev = pdev;966 init_completion(&spdifrx->cs_completion);967 spin_lock_init(&spdifrx->lock);968 spin_lock_init(&spdifrx->irq_lock);969 970 platform_set_drvdata(pdev, spdifrx);971 972 ret = stm32_spdifrx_parse_of(pdev, spdifrx);973 if (ret)974 return ret;975 976 spdifrx->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "kclk",977 spdifrx->base,978 spdifrx->regmap_conf);979 if (IS_ERR(spdifrx->regmap))980 return dev_err_probe(&pdev->dev, PTR_ERR(spdifrx->regmap),981 "Regmap init error\n");982 983 ret = devm_request_irq(&pdev->dev, spdifrx->irq, stm32_spdifrx_isr, 0,984 dev_name(&pdev->dev), spdifrx);985 if (ret) {986 dev_err(&pdev->dev, "IRQ request returned %d\n", ret);987 return ret;988 }989 990 rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);991 if (IS_ERR(rst))992 return dev_err_probe(&pdev->dev, PTR_ERR(rst),993 "Reset controller error\n");994 995 reset_control_assert(rst);996 udelay(2);997 reset_control_deassert(rst);998 999 pcm_config = &stm32_spdifrx_pcm_config;1000 ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);1001 if (ret)1002 return dev_err_probe(&pdev->dev, ret, "PCM DMA register error\n");1003 1004 ret = snd_soc_register_component(&pdev->dev,1005 &stm32_spdifrx_component,1006 stm32_spdifrx_dai,1007 ARRAY_SIZE(stm32_spdifrx_dai));1008 if (ret) {1009 snd_dmaengine_pcm_unregister(&pdev->dev);1010 return ret;1011 }1012 1013 ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx);1014 if (ret)1015 goto error;1016 1017 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr);1018 if (ret)1019 goto error;1020 1021 if (idr == SPDIFRX_IPIDR_NUMBER) {1022 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_VERR, &ver);1023 if (ret)1024 goto error;1025 1026 dev_dbg(&pdev->dev, "SPDIFRX version: %lu.%lu registered\n",1027 FIELD_GET(SPDIFRX_VERR_MAJ_MASK, ver),1028 FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));1029 }1030 1031 pm_runtime_enable(&pdev->dev);1032 1033 return ret;1034 1035error:1036 stm32_spdifrx_remove(pdev);1037 1038 return ret;1039}1040 1041MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids);1042 1043#ifdef CONFIG_PM_SLEEP1044static int stm32_spdifrx_suspend(struct device *dev)1045{1046 struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev);1047 1048 regcache_cache_only(spdifrx->regmap, true);1049 regcache_mark_dirty(spdifrx->regmap);1050 1051 return 0;1052}1053 1054static int stm32_spdifrx_resume(struct device *dev)1055{1056 struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev);1057 1058 regcache_cache_only(spdifrx->regmap, false);1059 1060 return regcache_sync(spdifrx->regmap);1061}1062#endif /* CONFIG_PM_SLEEP */1063 1064static const struct dev_pm_ops stm32_spdifrx_pm_ops = {1065 SET_SYSTEM_SLEEP_PM_OPS(stm32_spdifrx_suspend, stm32_spdifrx_resume)1066};1067 1068static struct platform_driver stm32_spdifrx_driver = {1069 .driver = {1070 .name = "st,stm32-spdifrx",1071 .of_match_table = stm32_spdifrx_ids,1072 .pm = &stm32_spdifrx_pm_ops,1073 },1074 .probe = stm32_spdifrx_probe,1075 .remove = stm32_spdifrx_remove,1076};1077 1078module_platform_driver(stm32_spdifrx_driver);1079 1080MODULE_DESCRIPTION("STM32 Soc spdifrx Interface");1081MODULE_AUTHOR("Olivier Moysan, <olivier.moysan@st.com>");1082MODULE_ALIAS("platform:stm32-spdifrx");1083MODULE_LICENSE("GPL v2");1084