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