^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* sound/soc/rockchip/rk_spdif.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * ALSA SoC Audio Layer - Rockchip I2S Controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Jianqun <jay.xu@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2015 Collabora Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/pcm_iec958.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "rockchip_spdif.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) enum rk_spdif_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) RK_SPDIF_RK3066,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) RK_SPDIF_RK3188,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) RK_SPDIF_RK3288,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) RK_SPDIF_RK3366,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * CS0: | Mode | d | c | b | a |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * CS1: | Category Code |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * CS2: | Channel Number | Source Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * CS3: | Clock Accuracy | Sample Freq |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * CS4: | Ori Sample Freq | Word Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * CS5: | | CGMS-A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * CS6~CS23: Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * a: use of channel status block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * b: linear PCM identification: 0 for lpcm, 1 for nlpcm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * c: copyright information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * d: additional format information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define CS_BYTE 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CS_FRAME(c) ((c) << 16 | (c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define RK3288_GRF_SOC_CON2 0x24c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct rk_spdif_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct clk *mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct clk *hclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct snd_dmaengine_dai_dma_data playback_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const struct of_device_id rk_spdif_match[] __maybe_unused = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) { .compatible = "rockchip,rk3066-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .data = (void *)RK_SPDIF_RK3066 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) { .compatible = "rockchip,rk3188-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .data = (void *)RK_SPDIF_RK3188 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { .compatible = "rockchip,rk3228-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) { .compatible = "rockchip,rk3288-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .data = (void *)RK_SPDIF_RK3288 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) { .compatible = "rockchip,rk3328-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) { .compatible = "rockchip,rk3366-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) { .compatible = "rockchip,rk3368-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) { .compatible = "rockchip,rk3399-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) { .compatible = "rockchip,rk3568-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) { .compatible = "rockchip,rk3588-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .data = (void *)RK_SPDIF_RK3366 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) MODULE_DEVICE_TABLE(of, rk_spdif_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int __maybe_unused rk_spdif_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) regcache_cache_only(spdif->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) clk_disable_unprepare(spdif->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) clk_disable_unprepare(spdif->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ret = clk_prepare_enable(spdif->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dev_err(spdif->dev, "mclk clock enable failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ret = clk_prepare_enable(spdif->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) regcache_cache_only(spdif->regmap, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) regcache_mark_dirty(spdif->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret = regcache_sync(spdif->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) clk_disable_unprepare(spdif->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) clk_disable_unprepare(spdif->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned int mclk_rate = clk_get_rate(spdif->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int bmc, div, ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u8 cs[CS_BYTE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u16 *fc = (u16 *)cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, sizeof(cs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) for (i = 0; i < CS_BYTE / 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) regmap_write(spdif->regmap, SPDIF_CHNSRn(i), CS_FRAME(fc[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CSE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SPDIF_CFGR_CSE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* bmc = 128fs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bmc = 128 * params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) div = DIV_ROUND_CLOSEST(mclk_rate, bmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) val |= SPDIF_CFGR_CLK_DIV(div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) val |= SPDIF_CFGR_VDW_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case SNDRV_PCM_FORMAT_S20_3LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) val |= SPDIF_CFGR_VDW_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case SNDRV_PCM_FORMAT_S24_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) val |= SPDIF_CFGR_VDW_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) val |= SPDIF_CFGR_ADJ_RIGHT_J;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) val |= SPDIF_CFGR_VDW_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) val |= SPDIF_CFGR_ADJ_LEFT_J;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) SPDIF_CFGR_CLK_DIV_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) SPDIF_CFGR_HALFWORD_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) SDPIF_CFGR_VDW_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) SPDIF_CFGR_ADJ_MASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int rk_spdif_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int cmd, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) SPDIF_DMACR_TDE_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) SPDIF_DMACR_TDL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) SPDIF_DMACR_TDE_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) SPDIF_DMACR_TDL(16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) SPDIF_XFER_TXS_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) SPDIF_XFER_TXS_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) SPDIF_DMACR_TDE_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) SPDIF_DMACR_TDE_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) SPDIF_XFER_TXS_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) SPDIF_XFER_TXS_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int rk_spdif_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dai->playback_dma_data = &spdif->playback_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int rk_spdif_set_sysclk(struct snd_soc_dai *dai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int clk_id, unsigned int freq, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = clk_set_rate(spdif->mclk, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_err(spdif->dev, "Failed to set mclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .set_sysclk = rk_spdif_set_sysclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .hw_params = rk_spdif_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .trigger = rk_spdif_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static struct snd_soc_dai_driver rk_spdif_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .probe = rk_spdif_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .stream_name = "Playback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .rates = SNDRV_PCM_RATE_8000_192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .formats = (SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) SNDRV_PCM_FMTBIT_S20_3LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) SNDRV_PCM_FMTBIT_S24_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) SNDRV_PCM_FMTBIT_S32_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .ops = &rk_spdif_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct snd_soc_component_driver rk_spdif_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .name = "rockchip-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case SPDIF_CFGR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case SPDIF_DMACR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case SPDIF_INTCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case SPDIF_XFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case SPDIF_SMPDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case SPDIF_CFGR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case SPDIF_SDBLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case SPDIF_INTCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) case SPDIF_INTSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case SPDIF_XFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case SPDIF_SMPDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) case SPDIF_INTSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case SPDIF_SDBLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case SPDIF_SMPDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static const struct regmap_config rk_spdif_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .max_register = SPDIF_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .writeable_reg = rk_spdif_wr_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .readable_reg = rk_spdif_rd_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .volatile_reg = rk_spdif_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .cache_type = REGCACHE_FLAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int rk_spdif_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct rk_spdif_dev *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) match = of_match_node(rk_spdif_match, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (match->data == (void *)RK_SPDIF_RK3288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct regmap *grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (IS_ERR(grf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) "rockchip_spdif missing 'rockchip,grf'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return PTR_ERR(grf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Select the 8 channel SPDIF solution on RK3288 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * the 2 channel one does not appear to work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regmap_write(grf, RK3288_GRF_SOC_CON2, BIT(1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (!spdif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) spdif->hclk = devm_clk_get(&pdev->dev, "hclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (IS_ERR(spdif->hclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return PTR_ERR(spdif->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) spdif->mclk = devm_clk_get(&pdev->dev, "mclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (IS_ERR(spdif->mclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return PTR_ERR(spdif->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (IS_ERR(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return PTR_ERR(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) spdif->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "hclk", regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) &rk_spdif_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (IS_ERR(spdif->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return PTR_ERR(spdif->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) spdif->playback_dma_data.maxburst = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) spdif->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) dev_set_drvdata(&pdev->dev, spdif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!pm_runtime_enabled(&pdev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ret = rk_spdif_runtime_resume(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto err_pm_runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = devm_snd_soc_register_component(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) &rk_spdif_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) &rk_spdif_dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) dev_err(&pdev->dev, "Could not register DAI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto err_pm_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) dev_err(&pdev->dev, "Could not register PCM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto err_pm_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) err_pm_suspend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!pm_runtime_status_suspended(&pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) rk_spdif_runtime_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) err_pm_runtime:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int rk_spdif_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!pm_runtime_status_suspended(&pdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) rk_spdif_runtime_suspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static const struct dev_pm_ops rk_spdif_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static struct platform_driver rk_spdif_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .probe = rk_spdif_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .remove = rk_spdif_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .name = "rockchip-spdif",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .of_match_table = of_match_ptr(rk_spdif_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .pm = &rk_spdif_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) module_platform_driver(rk_spdif_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) MODULE_ALIAS("platform:rockchip-spdif");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) MODULE_DESCRIPTION("ROCKCHIP SPDIF transceiver Interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) MODULE_AUTHOR("Sjoerd Simons <sjoerd.simons@collabora.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) MODULE_LICENSE("GPL v2");