stm32_spdifrx.c (00f5764dbb040188e5dce2cd9e648360886b045c) stm32_spdifrx.c (1a5c0b28fc56044737f988960f3bc5fdcdba0827)
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SPDIF-rx) driver.
3 *
4 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
5 * 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 */
18
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SPDIF-rx) driver.
3 *
4 * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
5 * 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 */
18
19#include <linux/bitfield.h>
19#include <linux/clk.h>
20#include <linux/completion.h>
21#include <linux/delay.h>
22#include <linux/module.h>
23#include <linux/of_platform.h>
24#include <linux/pinctrl/consumer.h>
25#include <linux/regmap.h>
26#include <linux/reset.h>

--- 4 unchanged lines hidden (view full) ---

31/* SPDIF-rx Register Map */
32#define STM32_SPDIFRX_CR 0x00
33#define STM32_SPDIFRX_IMR 0x04
34#define STM32_SPDIFRX_SR 0x08
35#define STM32_SPDIFRX_IFCR 0x0C
36#define STM32_SPDIFRX_DR 0x10
37#define STM32_SPDIFRX_CSR 0x14
38#define STM32_SPDIFRX_DIR 0x18
20#include <linux/clk.h>
21#include <linux/completion.h>
22#include <linux/delay.h>
23#include <linux/module.h>
24#include <linux/of_platform.h>
25#include <linux/pinctrl/consumer.h>
26#include <linux/regmap.h>
27#include <linux/reset.h>

--- 4 unchanged lines hidden (view full) ---

32/* SPDIF-rx Register Map */
33#define STM32_SPDIFRX_CR 0x00
34#define STM32_SPDIFRX_IMR 0x04
35#define STM32_SPDIFRX_SR 0x08
36#define STM32_SPDIFRX_IFCR 0x0C
37#define STM32_SPDIFRX_DR 0x10
38#define STM32_SPDIFRX_CSR 0x14
39#define STM32_SPDIFRX_DIR 0x18
40#define STM32_SPDIFRX_VERR 0x3F4
41#define STM32_SPDIFRX_IDR 0x3F8
42#define STM32_SPDIFRX_SIDR 0x3FC
39
40/* Bit definition for SPDIF_CR register */
41#define SPDIFRX_CR_SPDIFEN_SHIFT 0
42#define SPDIFRX_CR_SPDIFEN_MASK GENMASK(1, SPDIFRX_CR_SPDIFEN_SHIFT)
43#define SPDIFRX_CR_SPDIFENSET(x) ((x) << SPDIFRX_CR_SPDIFEN_SHIFT)
44
45#define SPDIFRX_CR_RXDMAEN BIT(2)
46#define SPDIFRX_CR_RXSTEO BIT(3)

--- 117 unchanged lines hidden (view full) ---

164#define SPDIFRX_DIR_TLO_SHIFT 16
165#define SPDIFRX_DIR_TLO_MASK GENMASK(28, SPDIFRX_DIR_TLO_SHIFT)
166#define SPDIFRX_DIR_TLO_SET(x) ((x) << SPDIFRX_DIR_TLO_SHIFT)
167
168#define SPDIFRX_SPDIFEN_DISABLE 0x0
169#define SPDIFRX_SPDIFEN_SYNC 0x1
170#define SPDIFRX_SPDIFEN_ENABLE 0x3
171
43
44/* Bit definition for SPDIF_CR register */
45#define SPDIFRX_CR_SPDIFEN_SHIFT 0
46#define SPDIFRX_CR_SPDIFEN_MASK GENMASK(1, SPDIFRX_CR_SPDIFEN_SHIFT)
47#define SPDIFRX_CR_SPDIFENSET(x) ((x) << SPDIFRX_CR_SPDIFEN_SHIFT)
48
49#define SPDIFRX_CR_RXDMAEN BIT(2)
50#define SPDIFRX_CR_RXSTEO BIT(3)

--- 117 unchanged lines hidden (view full) ---

168#define SPDIFRX_DIR_TLO_SHIFT 16
169#define SPDIFRX_DIR_TLO_MASK GENMASK(28, SPDIFRX_DIR_TLO_SHIFT)
170#define SPDIFRX_DIR_TLO_SET(x) ((x) << SPDIFRX_DIR_TLO_SHIFT)
171
172#define SPDIFRX_SPDIFEN_DISABLE 0x0
173#define SPDIFRX_SPDIFEN_SYNC 0x1
174#define SPDIFRX_SPDIFEN_ENABLE 0x3
175
176/* Bit definition for SPDIFRX_VERR register */
177#define SPDIFRX_VERR_MIN_MASK GENMASK(3, 0)
178#define SPDIFRX_VERR_MAJ_MASK GENMASK(7, 4)
179
180/* Bit definition for SPDIFRX_IDR register */
181#define SPDIFRX_IDR_ID_MASK GENMASK(31, 0)
182
183/* Bit definition for SPDIFRX_SIDR register */
184#define SPDIFRX_SIDR_SID_MASK GENMASK(31, 0)
185
186#define SPDIFRX_IPIDR_NUMBER 0x00130041
187
172#define SPDIFRX_IN1 0x1
173#define SPDIFRX_IN2 0x2
174#define SPDIFRX_IN3 0x3
175#define SPDIFRX_IN4 0x4
176#define SPDIFRX_IN5 0x5
177#define SPDIFRX_IN6 0x6
178#define SPDIFRX_IN7 0x7
179#define SPDIFRX_IN8 0x8

--- 311 unchanged lines hidden (view full) ---

491
492 ret = stm32_spdifrx_start_sync(spdifrx);
493 if (ret < 0)
494 goto end;
495
496 if (wait_for_completion_interruptible_timeout(&spdifrx->cs_completion,
497 msecs_to_jiffies(100))
498 <= 0) {
188#define SPDIFRX_IN1 0x1
189#define SPDIFRX_IN2 0x2
190#define SPDIFRX_IN3 0x3
191#define SPDIFRX_IN4 0x4
192#define SPDIFRX_IN5 0x5
193#define SPDIFRX_IN6 0x6
194#define SPDIFRX_IN7 0x7
195#define SPDIFRX_IN8 0x8

--- 311 unchanged lines hidden (view full) ---

507
508 ret = stm32_spdifrx_start_sync(spdifrx);
509 if (ret < 0)
510 goto end;
511
512 if (wait_for_completion_interruptible_timeout(&spdifrx->cs_completion,
513 msecs_to_jiffies(100))
514 <= 0) {
499 dev_dbg(&spdifrx->pdev->dev, "Failed to get control data\n");
515 dev_err(&spdifrx->pdev->dev, "Failed to get control data\n");
500 ret = -EAGAIN;
501 }
502
503 stm32_spdifrx_stop(spdifrx);
504 stm32_spdifrx_dma_ctrl_stop(spdifrx);
505
506end:
507 clk_disable_unprepare(spdifrx->kclk);

--- 94 unchanged lines hidden (view full) ---

602 switch (reg) {
603 case STM32_SPDIFRX_CR:
604 case STM32_SPDIFRX_IMR:
605 case STM32_SPDIFRX_SR:
606 case STM32_SPDIFRX_IFCR:
607 case STM32_SPDIFRX_DR:
608 case STM32_SPDIFRX_CSR:
609 case STM32_SPDIFRX_DIR:
516 ret = -EAGAIN;
517 }
518
519 stm32_spdifrx_stop(spdifrx);
520 stm32_spdifrx_dma_ctrl_stop(spdifrx);
521
522end:
523 clk_disable_unprepare(spdifrx->kclk);

--- 94 unchanged lines hidden (view full) ---

618 switch (reg) {
619 case STM32_SPDIFRX_CR:
620 case STM32_SPDIFRX_IMR:
621 case STM32_SPDIFRX_SR:
622 case STM32_SPDIFRX_IFCR:
623 case STM32_SPDIFRX_DR:
624 case STM32_SPDIFRX_CSR:
625 case STM32_SPDIFRX_DIR:
626 case STM32_SPDIFRX_VERR:
627 case STM32_SPDIFRX_IDR:
628 case STM32_SPDIFRX_SIDR:
610 return true;
611 default:
612 return false;
613 }
614}
615
616static bool stm32_spdifrx_volatile_reg(struct device *dev, unsigned int reg)
617{

--- 19 unchanged lines hidden (view full) ---

637 return false;
638 }
639}
640
641static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {
642 .reg_bits = 32,
643 .reg_stride = 4,
644 .val_bits = 32,
629 return true;
630 default:
631 return false;
632 }
633}
634
635static bool stm32_spdifrx_volatile_reg(struct device *dev, unsigned int reg)
636{

--- 19 unchanged lines hidden (view full) ---

656 return false;
657 }
658}
659
660static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {
661 .reg_bits = 32,
662 .reg_stride = 4,
663 .val_bits = 32,
645 .max_register = STM32_SPDIFRX_DIR,
664 .max_register = STM32_SPDIFRX_SIDR,
646 .readable_reg = stm32_spdifrx_readable_reg,
647 .volatile_reg = stm32_spdifrx_volatile_reg,
648 .writeable_reg = stm32_spdifrx_writeable_reg,
665 .readable_reg = stm32_spdifrx_readable_reg,
666 .volatile_reg = stm32_spdifrx_volatile_reg,
667 .writeable_reg = stm32_spdifrx_writeable_reg,
668 .num_reg_defaults_raw = STM32_SPDIFRX_SIDR / sizeof(u32) + 1,
649 .fast_io = true,
650 .cache_type = REGCACHE_FLAT,
651};
652
653static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
654{
655 struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid;
656 struct snd_pcm_substream *substream = spdifrx->substream;

--- 183 unchanged lines hidden (view full) ---

840 },
841 .ops = &stm32_spdifrx_pcm_dai_ops,
842 }
843};
844
845static const struct snd_pcm_hardware stm32_spdifrx_pcm_hw = {
846 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
847 .buffer_bytes_max = 8 * PAGE_SIZE,
669 .fast_io = true,
670 .cache_type = REGCACHE_FLAT,
671};
672
673static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
674{
675 struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid;
676 struct snd_pcm_substream *substream = spdifrx->substream;

--- 183 unchanged lines hidden (view full) ---

860 },
861 .ops = &stm32_spdifrx_pcm_dai_ops,
862 }
863};
864
865static const struct snd_pcm_hardware stm32_spdifrx_pcm_hw = {
866 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
867 .buffer_bytes_max = 8 * PAGE_SIZE,
848 .period_bytes_min = 1024,
849 .period_bytes_max = 4 * PAGE_SIZE,
868 .period_bytes_max = 2048, /* MDMA constraint */
850 .periods_min = 2,
851 .periods_max = 8,
852};
853
854static const struct snd_soc_component_driver stm32_spdifrx_component = {
855 .name = "stm32-spdifrx",
856};
857

--- 49 unchanged lines hidden (view full) ---

907 return 0;
908}
909
910static int stm32_spdifrx_probe(struct platform_device *pdev)
911{
912 struct stm32_spdifrx_data *spdifrx;
913 struct reset_control *rst;
914 const struct snd_dmaengine_pcm_config *pcm_config = NULL;
869 .periods_min = 2,
870 .periods_max = 8,
871};
872
873static const struct snd_soc_component_driver stm32_spdifrx_component = {
874 .name = "stm32-spdifrx",
875};
876

--- 49 unchanged lines hidden (view full) ---

926 return 0;
927}
928
929static int stm32_spdifrx_probe(struct platform_device *pdev)
930{
931 struct stm32_spdifrx_data *spdifrx;
932 struct reset_control *rst;
933 const struct snd_dmaengine_pcm_config *pcm_config = NULL;
934 u32 ver, idr;
915 int ret;
916
917 spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);
918 if (!spdifrx)
919 return -ENOMEM;
920
921 spdifrx->pdev = pdev;
922 init_completion(&spdifrx->cs_completion);

--- 40 unchanged lines hidden (view full) ---

963
964 pcm_config = &stm32_spdifrx_pcm_config;
965 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
966 if (ret) {
967 dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret);
968 goto error;
969 }
970
935 int ret;
936
937 spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL);
938 if (!spdifrx)
939 return -ENOMEM;
940
941 spdifrx->pdev = pdev;
942 init_completion(&spdifrx->cs_completion);

--- 40 unchanged lines hidden (view full) ---

983
984 pcm_config = &stm32_spdifrx_pcm_config;
985 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
986 if (ret) {
987 dev_err(&pdev->dev, "PCM DMA register returned %d\n", ret);
988 goto error;
989 }
990
971 return 0;
991 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr);
992 if (ret)
993 goto error;
972
994
995 if (idr == SPDIFRX_IPIDR_NUMBER) {
996 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_VERR, &ver);
997
998 dev_dbg(&pdev->dev, "SPDIFRX version: %lu.%lu registered\n",
999 FIELD_GET(SPDIFRX_VERR_MAJ_MASK, ver),
1000 FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));
1001 }
1002
1003 return ret;
1004
973error:
974 if (!IS_ERR(spdifrx->ctrl_chan))
975 dma_release_channel(spdifrx->ctrl_chan);
976 if (spdifrx->dmab)
977 snd_dma_free_pages(spdifrx->dmab);
978
979 return ret;
980}

--- 57 unchanged lines hidden ---
1005error:
1006 if (!IS_ERR(spdifrx->ctrl_chan))
1007 dma_release_channel(spdifrx->ctrl_chan);
1008 if (spdifrx->dmab)
1009 snd_dma_free_pages(spdifrx->dmab);
1010
1011 return ret;
1012}

--- 57 unchanged lines hidden ---