Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / sound / soc / zte / zx-tdm.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ZTE's TDM driver
4  *
5  * Copyright (C) 2017 ZTE Ltd
6  *
7  * Author: Baoyou Xie <baoyou.xie@linaro.org>
8  */
9
10 #include <linux/clk.h>
11 #include <linux/io.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/module.h>
14 #include <sound/dmaengine_pcm.h>
15 #include <sound/pcm_params.h>
16 #include <sound/soc.h>
17 #include <sound/soc-dai.h>
18
19 #define REG_TIMING_CTRL         0x04
20 #define REG_TX_FIFO_CTRL        0x0C
21 #define REG_RX_FIFO_CTRL        0x10
22 #define REG_INT_EN              0x1C
23 #define REG_INT_STATUS          0x20
24 #define REG_DATABUF             0x24
25 #define REG_TS_MASK0            0x44
26 #define REG_PROCESS_CTRL        0x54
27
28 #define FIFO_CTRL_TX_RST        BIT(0)
29 #define FIFO_CTRL_RX_RST        BIT(0)
30 #define DEAGULT_FIFO_THRES      GENMASK(4, 2)
31
32 #define FIFO_CTRL_TX_DMA_EN     BIT(1)
33 #define FIFO_CTRL_RX_DMA_EN     BIT(1)
34
35 #define TX_FIFO_RST_MASK        BIT(0)
36 #define RX_FIFO_RST_MASK        BIT(0)
37
38 #define FIFOCTRL_TX_FIFO_RST    BIT(0)
39 #define FIFOCTRL_RX_FIFO_RST    BIT(0)
40
41 #define TXTH_MASK               GENMASK(5, 2)
42 #define RXTH_MASK               GENMASK(5, 2)
43
44 #define FIFOCTRL_THRESHOLD(x)   ((x) << 2)
45
46 #define TIMING_MS_MASK          BIT(1)
47 /*
48  * 00: 8 clk cycles every timeslot
49  * 01: 16 clk cycles every timeslot
50  * 10: 32 clk cycles every timeslot
51  */
52 #define TIMING_SYNC_WIDTH_MASK  GENMASK(6, 5)
53 #define TIMING_WIDTH_SHIFT      5
54 #define TIMING_DEFAULT_WIDTH    0
55 #define TIMING_TS_WIDTH(x)      ((x) << TIMING_WIDTH_SHIFT)
56 #define TIMING_WIDTH_FACTOR     8
57
58 #define TIMING_MASTER_MODE      BIT(21)
59 #define TIMING_LSB_FIRST        BIT(20)
60 #define TIMING_TS_NUM(x)        (((x) - 1) << 7)
61 #define TIMING_CLK_SEL_MASK     GENMASK(2, 0)
62 #define TIMING_CLK_SEL_DEF      BIT(2)
63
64 #define PROCESS_TX_EN           BIT(0)
65 #define PROCESS_RX_EN           BIT(1)
66 #define PROCESS_TDM_EN          BIT(2)
67 #define PROCESS_DISABLE_ALL     0
68
69 #define INT_DISABLE_ALL         0
70 #define INT_STATUS_MASK         GENMASK(6, 0)
71
72 struct zx_tdm_info {
73         struct snd_dmaengine_dai_dma_data       dma_playback;
74         struct snd_dmaengine_dai_dma_data       dma_capture;
75         resource_size_t                         phy_addr;
76         void __iomem                            *regbase;
77         struct clk                              *dai_wclk;
78         struct clk                              *dai_pclk;
79         int                                     master;
80         struct device                           *dev;
81 };
82
83 static inline u32 zx_tdm_readl(struct zx_tdm_info *tdm, u16 reg)
84 {
85         return readl_relaxed(tdm->regbase + reg);
86 }
87
88 static inline void zx_tdm_writel(struct zx_tdm_info *tdm, u16 reg, u32 val)
89 {
90         writel_relaxed(val, tdm->regbase + reg);
91 }
92
93 static void zx_tdm_tx_en(struct zx_tdm_info *tdm, bool on)
94 {
95         unsigned long val;
96
97         val = zx_tdm_readl(tdm, REG_PROCESS_CTRL);
98         if (on)
99                 val |= PROCESS_TX_EN | PROCESS_TDM_EN;
100         else
101                 val &= ~(PROCESS_TX_EN | PROCESS_TDM_EN);
102         zx_tdm_writel(tdm, REG_PROCESS_CTRL, val);
103 }
104
105 static void zx_tdm_rx_en(struct zx_tdm_info *tdm, bool on)
106 {
107         unsigned long val;
108
109         val = zx_tdm_readl(tdm, REG_PROCESS_CTRL);
110         if (on)
111                 val |= PROCESS_RX_EN | PROCESS_TDM_EN;
112         else
113                 val &= ~(PROCESS_RX_EN | PROCESS_TDM_EN);
114         zx_tdm_writel(tdm, REG_PROCESS_CTRL, val);
115 }
116
117 static void zx_tdm_tx_dma_en(struct zx_tdm_info *tdm, bool on)
118 {
119         unsigned long val;
120
121         val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL);
122         val |= FIFO_CTRL_TX_RST | DEAGULT_FIFO_THRES;
123         if (on)
124                 val |= FIFO_CTRL_TX_DMA_EN;
125         else
126                 val &= ~FIFO_CTRL_TX_DMA_EN;
127         zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val);
128 }
129
130 static void zx_tdm_rx_dma_en(struct zx_tdm_info *tdm, bool on)
131 {
132         unsigned long val;
133
134         val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL);
135         val |= FIFO_CTRL_RX_RST | DEAGULT_FIFO_THRES;
136         if (on)
137                 val |= FIFO_CTRL_RX_DMA_EN;
138         else
139                 val &= ~FIFO_CTRL_RX_DMA_EN;
140         zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val);
141 }
142
143 #define ZX_TDM_RATES    (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
144
145 #define ZX_TDM_FMTBIT \
146         (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_MU_LAW | \
147         SNDRV_PCM_FMTBIT_A_LAW)
148
149 static int zx_tdm_dai_probe(struct snd_soc_dai *dai)
150 {
151         struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
152
153         snd_soc_dai_set_drvdata(dai, zx_tdm);
154         zx_tdm->dma_playback.addr = zx_tdm->phy_addr + REG_DATABUF;
155         zx_tdm->dma_playback.maxburst = 16;
156         zx_tdm->dma_capture.addr = zx_tdm->phy_addr + REG_DATABUF;
157         zx_tdm->dma_capture.maxburst = 16;
158         snd_soc_dai_init_dma_data(dai, &zx_tdm->dma_playback,
159                                   &zx_tdm->dma_capture);
160         return 0;
161 }
162
163 static int zx_tdm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
164 {
165         struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(cpu_dai);
166         unsigned long val;
167
168         val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
169         val &= ~(TIMING_SYNC_WIDTH_MASK | TIMING_MS_MASK);
170         val |= TIMING_DEFAULT_WIDTH << TIMING_WIDTH_SHIFT;
171
172         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
173         case SND_SOC_DAIFMT_CBM_CFM:
174                 tdm->master = 1;
175                 val |= TIMING_MASTER_MODE;
176                 break;
177         case SND_SOC_DAIFMT_CBS_CFS:
178                 tdm->master = 0;
179                 val &= ~TIMING_MASTER_MODE;
180                 break;
181         default:
182                 dev_err(cpu_dai->dev, "Unknown master/slave format\n");
183                 return -EINVAL;
184         }
185
186
187         zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
188
189         return 0;
190 }
191
192 static int zx_tdm_hw_params(struct snd_pcm_substream *substream,
193                             struct snd_pcm_hw_params *params,
194                             struct snd_soc_dai *socdai)
195 {
196         struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(socdai);
197         struct snd_dmaengine_dai_dma_data *dma_data;
198         unsigned int ts_width = TIMING_DEFAULT_WIDTH;
199         unsigned int ch_num = 32;
200         unsigned int mask = 0;
201         unsigned int ret = 0;
202         unsigned long val;
203
204         dma_data = snd_soc_dai_get_dma_data(socdai, substream);
205         dma_data->addr_width = ch_num >> 3;
206
207         switch (params_format(params)) {
208         case SNDRV_PCM_FORMAT_MU_LAW:
209         case SNDRV_PCM_FORMAT_A_LAW:
210         case SNDRV_PCM_FORMAT_S16_LE:
211                 ts_width = 1;
212                 break;
213         default:
214                 ts_width = 0;
215                 dev_err(socdai->dev, "Unknown data format\n");
216                 return -EINVAL;
217         }
218
219         val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
220         val |= TIMING_TS_WIDTH(ts_width) | TIMING_TS_NUM(1);
221         zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
222         zx_tdm_writel(tdm, REG_TS_MASK0, mask);
223
224         if (tdm->master)
225                 ret = clk_set_rate(tdm->dai_wclk,
226                         params_rate(params) * TIMING_WIDTH_FACTOR * ch_num);
227
228         return ret;
229 }
230
231 static int zx_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
232                           struct snd_soc_dai *dai)
233 {
234         int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
235         struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
236         unsigned int val;
237         int ret = 0;
238
239         switch (cmd) {
240         case SNDRV_PCM_TRIGGER_START:
241                 if (capture) {
242                         val = zx_tdm_readl(zx_tdm, REG_RX_FIFO_CTRL);
243                         val |= FIFOCTRL_RX_FIFO_RST;
244                         zx_tdm_writel(zx_tdm, REG_RX_FIFO_CTRL, val);
245
246                         zx_tdm_rx_dma_en(zx_tdm, true);
247                 } else {
248                         val = zx_tdm_readl(zx_tdm, REG_TX_FIFO_CTRL);
249                         val |= FIFOCTRL_TX_FIFO_RST;
250                         zx_tdm_writel(zx_tdm, REG_TX_FIFO_CTRL, val);
251
252                         zx_tdm_tx_dma_en(zx_tdm, true);
253                 }
254                 break;
255         case SNDRV_PCM_TRIGGER_RESUME:
256         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
257                 if (capture)
258                         zx_tdm_rx_en(zx_tdm, true);
259                 else
260                         zx_tdm_tx_en(zx_tdm, true);
261                 break;
262         case SNDRV_PCM_TRIGGER_STOP:
263                 if (capture)
264                         zx_tdm_rx_dma_en(zx_tdm, false);
265                 else
266                         zx_tdm_tx_dma_en(zx_tdm, false);
267                 break;
268         case SNDRV_PCM_TRIGGER_SUSPEND:
269         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
270                 if (capture)
271                         zx_tdm_rx_en(zx_tdm, false);
272                 else
273                         zx_tdm_tx_en(zx_tdm, false);
274                 break;
275         default:
276                 ret = -EINVAL;
277                 break;
278         }
279
280         return ret;
281 }
282
283 static int zx_tdm_startup(struct snd_pcm_substream *substream,
284                           struct snd_soc_dai *dai)
285 {
286         struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
287         int ret;
288
289         ret = clk_prepare_enable(zx_tdm->dai_wclk);
290         if (ret)
291                 return ret;
292
293         ret = clk_prepare_enable(zx_tdm->dai_pclk);
294         if (ret) {
295                 clk_disable_unprepare(zx_tdm->dai_wclk);
296                 return ret;
297         }
298
299         return 0;
300 }
301
302 static void zx_tdm_shutdown(struct snd_pcm_substream *substream,
303                             struct snd_soc_dai *dai)
304 {
305         struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
306
307         clk_disable_unprepare(zx_tdm->dai_pclk);
308         clk_disable_unprepare(zx_tdm->dai_wclk);
309 }
310
311 static const struct snd_soc_dai_ops zx_tdm_dai_ops = {
312         .trigger        = zx_tdm_trigger,
313         .hw_params      = zx_tdm_hw_params,
314         .set_fmt        = zx_tdm_set_fmt,
315         .startup        = zx_tdm_startup,
316         .shutdown       = zx_tdm_shutdown,
317 };
318
319 static const struct snd_soc_component_driver zx_tdm_component = {
320         .name                   = "zx-tdm",
321 };
322
323 static void zx_tdm_init_state(struct zx_tdm_info *tdm)
324 {
325         unsigned int val;
326
327         zx_tdm_writel(tdm, REG_PROCESS_CTRL, PROCESS_DISABLE_ALL);
328
329         val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
330         val |= TIMING_LSB_FIRST;
331         val &= ~TIMING_CLK_SEL_MASK;
332         val |= TIMING_CLK_SEL_DEF;
333         zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
334
335         zx_tdm_writel(tdm, REG_INT_EN, INT_DISABLE_ALL);
336         /*
337          * write INT_STATUS register to clear it.
338          */
339         zx_tdm_writel(tdm, REG_INT_STATUS, INT_STATUS_MASK);
340         zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, FIFOCTRL_RX_FIFO_RST);
341         zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, FIFOCTRL_TX_FIFO_RST);
342
343         val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL);
344         val &= ~(RXTH_MASK | RX_FIFO_RST_MASK);
345         val |= FIFOCTRL_THRESHOLD(8);
346         zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val);
347
348         val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL);
349         val &= ~(TXTH_MASK | TX_FIFO_RST_MASK);
350         val |= FIFOCTRL_THRESHOLD(8);
351         zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val);
352 }
353
354 static struct snd_soc_dai_driver zx_tdm_dai = {
355         .name   = "zx-tdm-dai",
356         .id     = 0,
357         .probe  = zx_tdm_dai_probe,
358         .playback   = {
359                 .channels_min   = 1,
360                 .channels_max   = 4,
361                 .rates          = ZX_TDM_RATES,
362                 .formats        = ZX_TDM_FMTBIT,
363         },
364         .capture = {
365                 .channels_min   = 1,
366                 .channels_max   = 4,
367                 .rates          = ZX_TDM_RATES,
368                 .formats        = ZX_TDM_FMTBIT,
369         },
370         .ops    = &zx_tdm_dai_ops,
371 };
372
373 static int zx_tdm_probe(struct platform_device *pdev)
374 {
375         struct device *dev = &pdev->dev;
376         struct of_phandle_args out_args;
377         unsigned int dma_reg_offset;
378         struct zx_tdm_info *zx_tdm;
379         unsigned int dma_mask;
380         struct resource *res;
381         struct regmap *regmap_sysctrl;
382         int ret;
383
384         zx_tdm = devm_kzalloc(&pdev->dev, sizeof(*zx_tdm), GFP_KERNEL);
385         if (!zx_tdm)
386                 return -ENOMEM;
387
388         zx_tdm->dev = dev;
389
390         zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk");
391         if (IS_ERR(zx_tdm->dai_wclk)) {
392                 dev_err(&pdev->dev, "Fail to get wclk\n");
393                 return PTR_ERR(zx_tdm->dai_wclk);
394         }
395
396         zx_tdm->dai_pclk = devm_clk_get(&pdev->dev, "pclk");
397         if (IS_ERR(zx_tdm->dai_pclk)) {
398                 dev_err(&pdev->dev, "Fail to get pclk\n");
399                 return PTR_ERR(zx_tdm->dai_pclk);
400         }
401
402         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
403         zx_tdm->phy_addr = res->start;
404         zx_tdm->regbase = devm_ioremap_resource(&pdev->dev, res);
405         if (IS_ERR(zx_tdm->regbase))
406                 return PTR_ERR(zx_tdm->regbase);
407
408         ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
409                                 "zte,tdm-dma-sysctrl", 2, 0, &out_args);
410         if (ret) {
411                 dev_err(&pdev->dev, "Fail to get zte,tdm-dma-sysctrl\n");
412                 return ret;
413         }
414
415         dma_reg_offset = out_args.args[0];
416         dma_mask = out_args.args[1];
417         regmap_sysctrl = syscon_node_to_regmap(out_args.np);
418         if (IS_ERR(regmap_sysctrl)) {
419                 of_node_put(out_args.np);
420                 return PTR_ERR(regmap_sysctrl);
421         }
422
423         regmap_update_bits(regmap_sysctrl, dma_reg_offset, dma_mask, dma_mask);
424         of_node_put(out_args.np);
425
426         zx_tdm_init_state(zx_tdm);
427         platform_set_drvdata(pdev, zx_tdm);
428
429         ret = devm_snd_soc_register_component(&pdev->dev, &zx_tdm_component,
430                                                 &zx_tdm_dai, 1);
431         if (ret) {
432                 dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
433                 return ret;
434         }
435
436         ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
437         if (ret)
438                 dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);
439
440         return ret;
441 }
442
443 static const struct of_device_id zx_tdm_dt_ids[] = {
444         { .compatible = "zte,zx296718-tdm", },
445         {}
446 };
447 MODULE_DEVICE_TABLE(of, zx_tdm_dt_ids);
448
449 static struct platform_driver tdm_driver = {
450         .probe = zx_tdm_probe,
451         .driver = {
452                 .name = "zx-tdm",
453                 .of_match_table = zx_tdm_dt_ids,
454         },
455 };
456 module_platform_driver(tdm_driver);
457
458 MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
459 MODULE_DESCRIPTION("ZTE TDM DAI driver");
460 MODULE_LICENSE("GPL v2");