1/* 2 * Copyright (C) 2015 Linaro 3 * 4 * Author: Jun Nie <jun.nie@linaro.org> 5 * 6 * License terms: GNU General Public License (GPL) version 2 7 */ 8 9#include <linux/clk.h> 10#include <linux/device.h> 11#include <linux/dmaengine.h> 12#include <linux/init.h> 13#include <linux/io.h> 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/of_address.h> 17#include <sound/asoundef.h> 18#include <sound/core.h> 19#include <sound/dmaengine_pcm.h> 20#include <sound/initval.h> 21#include <sound/pcm.h> 22#include <sound/pcm_params.h> 23#include <sound/soc.h> 24#include <sound/soc-dai.h> 25 26#define ZX_CTRL 0x04 27#define ZX_FIFOCTRL 0x08 28#define ZX_INT_STATUS 0x10 29#define ZX_INT_MASK 0x14 30#define ZX_DATA 0x18 31#define ZX_VALID_BIT 0x1c 32#define ZX_CH_STA_1 0x20 33#define ZX_CH_STA_2 0x24 34#define ZX_CH_STA_3 0x28 35#define ZX_CH_STA_4 0x2c 36#define ZX_CH_STA_5 0x30 37#define ZX_CH_STA_6 0x34 38 39#define ZX_CTRL_MODA_16 (0 << 6) 40#define ZX_CTRL_MODA_18 BIT(6) 41#define ZX_CTRL_MODA_20 (2 << 6) 42#define ZX_CTRL_MODA_24 (3 << 6) 43#define ZX_CTRL_MODA_MASK (3 << 6) 44 45#define ZX_CTRL_ENB BIT(4) 46#define ZX_CTRL_DNB (0 << 4) 47#define ZX_CTRL_ENB_MASK BIT(4) 48 49#define ZX_CTRL_TX_OPEN BIT(0) 50#define ZX_CTRL_TX_CLOSE (0 << 0) 51#define ZX_CTRL_TX_MASK BIT(0) 52 53#define ZX_CTRL_OPEN (ZX_CTRL_TX_OPEN | ZX_CTRL_ENB) 54#define ZX_CTRL_CLOSE (ZX_CTRL_TX_CLOSE | ZX_CTRL_DNB) 55 56#define ZX_CTRL_DOUBLE_TRACK (0 << 8) 57#define ZX_CTRL_LEFT_TRACK BIT(8) 58#define ZX_CTRL_RIGHT_TRACK (2 << 8) 59#define ZX_CTRL_TRACK_MASK (3 << 8) 60 61#define ZX_FIFOCTRL_TXTH_MASK (0x1f << 8) 62#define ZX_FIFOCTRL_TXTH(x) (x << 8) 63#define ZX_FIFOCTRL_TX_DMA_EN BIT(2) 64#define ZX_FIFOCTRL_TX_DMA_DIS (0 << 2) 65#define ZX_FIFOCTRL_TX_DMA_EN_MASK BIT(2) 66#define ZX_FIFOCTRL_TX_FIFO_RST BIT(0) 67#define ZX_FIFOCTRL_TX_FIFO_RST_MASK BIT(0) 68 69#define ZX_VALID_DOUBLE_TRACK (0 << 0) 70#define ZX_VALID_LEFT_TRACK BIT(1) 71#define ZX_VALID_RIGHT_TRACK (2 << 0) 72#define ZX_VALID_TRACK_MASK (3 << 0) 73 74#define ZX_SPDIF_CLK_RAT (4 * 32) 75 76struct zx_spdif_info { 77 struct snd_dmaengine_dai_dma_data dma_data; 78 struct clk *dai_clk; 79 void __iomem *reg_base; 80 resource_size_t mapbase; 81}; 82 83static int zx_spdif_dai_probe(struct snd_soc_dai *dai) 84{ 85 struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); 86 87 snd_soc_dai_set_drvdata(dai, zx_spdif); 88 zx_spdif->dma_data.addr = zx_spdif->mapbase + ZX_DATA; 89 zx_spdif->dma_data.maxburst = 8; 90 snd_soc_dai_init_dma_data(dai, &zx_spdif->dma_data, NULL); 91 return 0; 92} 93 94static int zx_spdif_chanstats(void __iomem *base, unsigned int rate) 95{ 96 u32 cstas1; 97 98 switch (rate) { 99 case 22050: 100 cstas1 = IEC958_AES3_CON_FS_22050; 101 break; 102 case 24000: 103 cstas1 = IEC958_AES3_CON_FS_24000; 104 break; 105 case 32000: 106 cstas1 = IEC958_AES3_CON_FS_32000; 107 break; 108 case 44100: 109 cstas1 = IEC958_AES3_CON_FS_44100; 110 break; 111 case 48000: 112 cstas1 = IEC958_AES3_CON_FS_48000; 113 break; 114 case 88200: 115 cstas1 = IEC958_AES3_CON_FS_88200; 116 break; 117 case 96000: 118 cstas1 = IEC958_AES3_CON_FS_96000; 119 break; 120 case 176400: 121 cstas1 = IEC958_AES3_CON_FS_176400; 122 break; 123 case 192000: 124 cstas1 = IEC958_AES3_CON_FS_192000; 125 break; 126 default: 127 return -EINVAL; 128 } 129 cstas1 = cstas1 << 24; 130 cstas1 |= IEC958_AES0_CON_NOT_COPYRIGHT; 131 132 writel_relaxed(cstas1, base + ZX_CH_STA_1); 133 return 0; 134} 135 136static int zx_spdif_hw_params(struct snd_pcm_substream *substream, 137 struct snd_pcm_hw_params *params, 138 struct snd_soc_dai *socdai) 139{ 140 struct zx_spdif_info *zx_spdif = dev_get_drvdata(socdai->dev); 141 struct zx_spdif_info *spdif = snd_soc_dai_get_drvdata(socdai); 142 struct snd_dmaengine_dai_dma_data *dma_data = &zx_spdif->dma_data; 143 u32 val, ch_num, rate; 144 int ret; 145 146 dma_data = snd_soc_dai_get_dma_data(socdai, substream); 147 dma_data->addr_width = params_width(params) >> 3; 148 149 val = readl_relaxed(zx_spdif->reg_base + ZX_CTRL); 150 val &= ~ZX_CTRL_MODA_MASK; 151 switch (params_format(params)) { 152 case SNDRV_PCM_FORMAT_S16_LE: 153 val |= ZX_CTRL_MODA_16; 154 break; 155 156 case SNDRV_PCM_FORMAT_S18_3LE: 157 val |= ZX_CTRL_MODA_18; 158 break; 159 160 case SNDRV_PCM_FORMAT_S20_3LE: 161 val |= ZX_CTRL_MODA_20; 162 break; 163 164 case SNDRV_PCM_FORMAT_S24_LE: 165 val |= ZX_CTRL_MODA_24; 166 break; 167 default: 168 dev_err(socdai->dev, "Format not support!\n"); 169 return -EINVAL; 170 } 171 172 ch_num = params_channels(params); 173 if (ch_num == 2) 174 val |= ZX_CTRL_DOUBLE_TRACK; 175 else 176 val |= ZX_CTRL_LEFT_TRACK; 177 writel_relaxed(val, zx_spdif->reg_base + ZX_CTRL); 178 179 val = readl_relaxed(zx_spdif->reg_base + ZX_VALID_BIT); 180 val &= ~ZX_VALID_TRACK_MASK; 181 if (ch_num == 2) 182 val |= ZX_VALID_DOUBLE_TRACK; 183 else 184 val |= ZX_VALID_RIGHT_TRACK; 185 writel_relaxed(val, zx_spdif->reg_base + ZX_VALID_BIT); 186 187 rate = params_rate(params); 188 ret = zx_spdif_chanstats(zx_spdif->reg_base, rate); 189 if (ret) 190 return ret; 191 return clk_set_rate(spdif->dai_clk, rate * ch_num * ZX_SPDIF_CLK_RAT); 192} 193 194static void zx_spdif_cfg_tx(void __iomem *base, int on) 195{ 196 u32 val; 197 198 val = readl_relaxed(base + ZX_CTRL); 199 val &= ~(ZX_CTRL_ENB_MASK | ZX_CTRL_TX_MASK); 200 val |= on ? ZX_CTRL_OPEN : ZX_CTRL_CLOSE; 201 writel_relaxed(val, base + ZX_CTRL); 202 203 val = readl_relaxed(base + ZX_FIFOCTRL); 204 val &= ~ZX_FIFOCTRL_TX_DMA_EN_MASK; 205 if (on) 206 val |= ZX_FIFOCTRL_TX_DMA_EN; 207 writel_relaxed(val, base + ZX_FIFOCTRL); 208} 209 210static int zx_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 211 struct snd_soc_dai *dai) 212{ 213 u32 val; 214 struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); 215 int ret = 0; 216 217 switch (cmd) { 218 case SNDRV_PCM_TRIGGER_START: 219 val = readl_relaxed(zx_spdif->reg_base + ZX_FIFOCTRL); 220 val |= ZX_FIFOCTRL_TX_FIFO_RST; 221 writel_relaxed(val, zx_spdif->reg_base + ZX_FIFOCTRL); 222 /* fall thru */ 223 case SNDRV_PCM_TRIGGER_RESUME: 224 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 225 zx_spdif_cfg_tx(zx_spdif->reg_base, true); 226 break; 227 228 case SNDRV_PCM_TRIGGER_STOP: 229 case SNDRV_PCM_TRIGGER_SUSPEND: 230 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 231 zx_spdif_cfg_tx(zx_spdif->reg_base, false); 232 break; 233 234 default: 235 ret = -EINVAL; 236 break; 237 } 238 239 return ret; 240} 241 242static int zx_spdif_startup(struct snd_pcm_substream *substream, 243 struct snd_soc_dai *dai) 244{ 245 struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); 246 247 return clk_prepare_enable(zx_spdif->dai_clk); 248} 249 250static void zx_spdif_shutdown(struct snd_pcm_substream *substream, 251 struct snd_soc_dai *dai) 252{ 253 struct zx_spdif_info *zx_spdif = dev_get_drvdata(dai->dev); 254 255 clk_disable_unprepare(zx_spdif->dai_clk); 256} 257 258#define ZX_RATES \ 259 (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 260 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |\ 261 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000) 262 263#define ZX_FORMAT \ 264 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE \ 265 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) 266 267static struct snd_soc_dai_ops zx_spdif_dai_ops = { 268 .trigger = zx_spdif_trigger, 269 .startup = zx_spdif_startup, 270 .shutdown = zx_spdif_shutdown, 271 .hw_params = zx_spdif_hw_params, 272}; 273 274static struct snd_soc_dai_driver zx_spdif_dai = { 275 .name = "spdif", 276 .id = 0, 277 .probe = zx_spdif_dai_probe, 278 .playback = { 279 .channels_min = 1, 280 .channels_max = 2, 281 .rates = ZX_RATES, 282 .formats = ZX_FORMAT, 283 }, 284 .ops = &zx_spdif_dai_ops, 285}; 286 287static const struct snd_soc_component_driver zx_spdif_component = { 288 .name = "spdif", 289}; 290 291static void zx_spdif_dev_init(void __iomem *base) 292{ 293 u32 val; 294 295 writel_relaxed(0, base + ZX_CTRL); 296 writel_relaxed(0, base + ZX_INT_MASK); 297 writel_relaxed(0xf, base + ZX_INT_STATUS); 298 writel_relaxed(0x1, base + ZX_FIFOCTRL); 299 300 val = readl_relaxed(base + ZX_FIFOCTRL); 301 val &= ~(ZX_FIFOCTRL_TXTH_MASK | ZX_FIFOCTRL_TX_FIFO_RST_MASK); 302 val |= ZX_FIFOCTRL_TXTH(8); 303 writel_relaxed(val, base + ZX_FIFOCTRL); 304} 305 306static int zx_spdif_probe(struct platform_device *pdev) 307{ 308 struct resource *res; 309 struct zx_spdif_info *zx_spdif; 310 int ret; 311 312 zx_spdif = devm_kzalloc(&pdev->dev, sizeof(*zx_spdif), GFP_KERNEL); 313 if (!zx_spdif) 314 return -ENOMEM; 315 316 zx_spdif->dai_clk = devm_clk_get(&pdev->dev, "tx"); 317 if (IS_ERR(zx_spdif->dai_clk)) { 318 dev_err(&pdev->dev, "Fail to get clk\n"); 319 return PTR_ERR(zx_spdif->dai_clk); 320 } 321 322 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 323 zx_spdif->mapbase = res->start; 324 zx_spdif->reg_base = devm_ioremap_resource(&pdev->dev, res); 325 if (IS_ERR(zx_spdif->reg_base)) { 326 dev_err(&pdev->dev, "ioremap failed!\n"); 327 return PTR_ERR(zx_spdif->reg_base); 328 } 329 330 zx_spdif_dev_init(zx_spdif->reg_base); 331 platform_set_drvdata(pdev, zx_spdif); 332 333 ret = devm_snd_soc_register_component(&pdev->dev, &zx_spdif_component, 334 &zx_spdif_dai, 1); 335 if (ret) { 336 dev_err(&pdev->dev, "Register DAI failed: %d\n", ret); 337 return ret; 338 } 339 340 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 341 if (ret) 342 dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret); 343 344 return ret; 345} 346 347static const struct of_device_id zx_spdif_dt_ids[] = { 348 { .compatible = "zte,zx296702-spdif", }, 349 {} 350}; 351MODULE_DEVICE_TABLE(of, zx_spdif_dt_ids); 352 353static struct platform_driver spdif_driver = { 354 .probe = zx_spdif_probe, 355 .driver = { 356 .name = "zx-spdif", 357 .of_match_table = zx_spdif_dt_ids, 358 }, 359}; 360 361module_platform_driver(spdif_driver); 362 363MODULE_AUTHOR("Jun Nie <jun.nie@linaro.org>"); 364MODULE_DESCRIPTION("ZTE SPDIF SoC DAI"); 365MODULE_LICENSE("GPL"); 366