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