xref: /linux/sound/soc/starfive/jh7110_pwmdac.c (revision 5027ec19f1049a07df5b0a37b1f462514cf2724b)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * jh7110_pwmdac.c -- StarFive JH7110 PWM-DAC driver
4  *
5  * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
6  *
7  * Authors: Jenny Zhang
8  *	    Curry Zhang
9  *	    Xingyu Wu <xingyu.wu@starfivetech.com>
10  *	    Hal Feng <hal.feng@starfivetech.com>
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/device.h>
15 #include <linux/init.h>
16 #include <linux/interrupt.h>
17 #include <linux/io.h>
18 #include <linux/module.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/reset.h>
21 #include <linux/slab.h>
22 #include <linux/types.h>
23 #include <sound/dmaengine_pcm.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
26 #include <sound/soc.h>
27 
28 #define JH7110_PWMDAC_WDATA				0x00
29 #define JH7110_PWMDAC_CTRL				0x04
30 	#define JH7110_PWMDAC_ENABLE			BIT(0)
31 	#define JH7110_PWMDAC_SHIFT			BIT(1)
32 	#define JH7110_PWMDAC_DUTY_CYCLE_SHIFT		2
33 	#define JH7110_PWMDAC_DUTY_CYCLE_MASK		GENMASK(3, 2)
34 	#define JH7110_PWMDAC_CNT_N_SHIFT		4
35 	#define JH7110_PWMDAC_CNT_N_MASK		GENMASK(12, 4)
36 	#define JH7110_PWMDAC_DATA_CHANGE		BIT(13)
37 	#define JH7110_PWMDAC_DATA_MODE			BIT(14)
38 	#define JH7110_PWMDAC_DATA_SHIFT_SHIFT		15
39 	#define JH7110_PWMDAC_DATA_SHIFT_MASK		GENMASK(17, 15)
40 
41 enum JH7110_PWMDAC_SHIFT_VAL {
42 	PWMDAC_SHIFT_8 = 0,
43 	PWMDAC_SHIFT_10,
44 };
45 
46 enum JH7110_PWMDAC_DUTY_CYCLE_VAL {
47 	PWMDAC_CYCLE_LEFT = 0,
48 	PWMDAC_CYCLE_RIGHT,
49 	PWMDAC_CYCLE_CENTER,
50 };
51 
52 enum JH7110_PWMDAC_CNT_N_VAL {
53 	PWMDAC_SAMPLE_CNT_1 = 1,
54 	PWMDAC_SAMPLE_CNT_2,
55 	PWMDAC_SAMPLE_CNT_3,
56 	PWMDAC_SAMPLE_CNT_512 = 512, /* max */
57 };
58 
59 enum JH7110_PWMDAC_DATA_CHANGE_VAL {
60 	NO_CHANGE = 0,
61 	CHANGE,
62 };
63 
64 enum JH7110_PWMDAC_DATA_MODE_VAL {
65 	UNSIGNED_DATA = 0,
66 	INVERTER_DATA_MSB,
67 };
68 
69 enum JH7110_PWMDAC_DATA_SHIFT_VAL {
70 	PWMDAC_DATA_LEFT_SHIFT_BIT_0 = 0,
71 	PWMDAC_DATA_LEFT_SHIFT_BIT_1,
72 	PWMDAC_DATA_LEFT_SHIFT_BIT_2,
73 	PWMDAC_DATA_LEFT_SHIFT_BIT_3,
74 	PWMDAC_DATA_LEFT_SHIFT_BIT_4,
75 	PWMDAC_DATA_LEFT_SHIFT_BIT_5,
76 	PWMDAC_DATA_LEFT_SHIFT_BIT_6,
77 	PWMDAC_DATA_LEFT_SHIFT_BIT_7,
78 };
79 
80 struct jh7110_pwmdac_cfg {
81 	enum JH7110_PWMDAC_SHIFT_VAL shift;
82 	enum JH7110_PWMDAC_DUTY_CYCLE_VAL duty_cycle;
83 	u16 cnt_n;
84 	enum JH7110_PWMDAC_DATA_CHANGE_VAL data_change;
85 	enum JH7110_PWMDAC_DATA_MODE_VAL data_mode;
86 	enum JH7110_PWMDAC_DATA_SHIFT_VAL data_shift;
87 };
88 
89 struct jh7110_pwmdac_dev {
90 	void __iomem *base;
91 	resource_size_t	mapbase;
92 	struct jh7110_pwmdac_cfg cfg;
93 
94 	struct clk_bulk_data clks[2];
95 	struct reset_control *rst_apb;
96 	struct device *dev;
97 	struct snd_dmaengine_dai_dma_data play_dma_data;
98 	u32 saved_ctrl;
99 };
100 
101 static inline void jh7110_pwmdac_write_reg(void __iomem *io_base, int reg, u32 val)
102 {
103 	writel(val, io_base + reg);
104 }
105 
106 static inline u32 jh7110_pwmdac_read_reg(void __iomem *io_base, int reg)
107 {
108 	return readl(io_base + reg);
109 }
110 
111 static void jh7110_pwmdac_set_enable(struct jh7110_pwmdac_dev *dev, bool enable)
112 {
113 	u32 value;
114 
115 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
116 	if (enable)
117 		value |= JH7110_PWMDAC_ENABLE;
118 	else
119 		value &= ~JH7110_PWMDAC_ENABLE;
120 
121 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
122 }
123 
124 static void jh7110_pwmdac_set_shift(struct jh7110_pwmdac_dev *dev)
125 {
126 	u32 value;
127 
128 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
129 	if (dev->cfg.shift == PWMDAC_SHIFT_8)
130 		value &= ~JH7110_PWMDAC_SHIFT;
131 	else if (dev->cfg.shift == PWMDAC_SHIFT_10)
132 		value |= JH7110_PWMDAC_SHIFT;
133 
134 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
135 }
136 
137 static void jh7110_pwmdac_set_duty_cycle(struct jh7110_pwmdac_dev *dev)
138 {
139 	u32 value;
140 
141 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
142 	value &= ~JH7110_PWMDAC_DUTY_CYCLE_MASK;
143 	value |= (dev->cfg.duty_cycle & 0x3) << JH7110_PWMDAC_DUTY_CYCLE_SHIFT;
144 
145 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
146 }
147 
148 static void jh7110_pwmdac_set_cnt_n(struct jh7110_pwmdac_dev *dev)
149 {
150 	u32 value;
151 
152 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
153 	value &= ~JH7110_PWMDAC_CNT_N_MASK;
154 	value |= ((dev->cfg.cnt_n - 1) & 0x1ff) << JH7110_PWMDAC_CNT_N_SHIFT;
155 
156 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
157 }
158 
159 static void jh7110_pwmdac_set_data_change(struct jh7110_pwmdac_dev *dev)
160 {
161 	u32 value;
162 
163 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
164 	if (dev->cfg.data_change == NO_CHANGE)
165 		value &= ~JH7110_PWMDAC_DATA_CHANGE;
166 	else if (dev->cfg.data_change == CHANGE)
167 		value |= JH7110_PWMDAC_DATA_CHANGE;
168 
169 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
170 }
171 
172 static void jh7110_pwmdac_set_data_mode(struct jh7110_pwmdac_dev *dev)
173 {
174 	u32 value;
175 
176 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
177 	if (dev->cfg.data_mode == UNSIGNED_DATA)
178 		value &= ~JH7110_PWMDAC_DATA_MODE;
179 	else if (dev->cfg.data_mode == INVERTER_DATA_MSB)
180 		value |= JH7110_PWMDAC_DATA_MODE;
181 
182 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
183 }
184 
185 static void jh7110_pwmdac_set_data_shift(struct jh7110_pwmdac_dev *dev)
186 {
187 	u32 value;
188 
189 	value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
190 	value &= ~JH7110_PWMDAC_DATA_SHIFT_MASK;
191 	value |= (dev->cfg.data_shift & 0x7) << JH7110_PWMDAC_DATA_SHIFT_SHIFT;
192 
193 	jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
194 }
195 
196 static void jh7110_pwmdac_set(struct jh7110_pwmdac_dev *dev)
197 {
198 	jh7110_pwmdac_set_shift(dev);
199 	jh7110_pwmdac_set_duty_cycle(dev);
200 	jh7110_pwmdac_set_cnt_n(dev);
201 	jh7110_pwmdac_set_enable(dev, true);
202 
203 	jh7110_pwmdac_set_data_change(dev);
204 	jh7110_pwmdac_set_data_mode(dev);
205 	jh7110_pwmdac_set_data_shift(dev);
206 }
207 
208 static void jh7110_pwmdac_stop(struct jh7110_pwmdac_dev *dev)
209 {
210 	jh7110_pwmdac_set_enable(dev, false);
211 }
212 
213 static int jh7110_pwmdac_startup(struct snd_pcm_substream *substream,
214 				 struct snd_soc_dai *dai)
215 {
216 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
217 	struct snd_soc_dai_link *dai_link = rtd->dai_link;
218 
219 	dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC;
220 
221 	return 0;
222 }
223 
224 static int jh7110_pwmdac_hw_params(struct snd_pcm_substream *substream,
225 				   struct snd_pcm_hw_params *params,
226 				   struct snd_soc_dai *dai)
227 {
228 	struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
229 	unsigned long core_clk_rate;
230 	int ret;
231 
232 	switch (params_rate(params)) {
233 	case 8000:
234 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
235 		core_clk_rate = 6144000;
236 		break;
237 	case 11025:
238 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_2;
239 		core_clk_rate = 5644800;
240 		break;
241 	case 16000:
242 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
243 		core_clk_rate = 12288000;
244 		break;
245 	case 22050:
246 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
247 		core_clk_rate = 5644800;
248 		break;
249 	case 32000:
250 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
251 		core_clk_rate = 8192000;
252 		break;
253 	case 44100:
254 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
255 		core_clk_rate = 11289600;
256 		break;
257 	case 48000:
258 		dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
259 		core_clk_rate = 12288000;
260 		break;
261 	default:
262 		dev_err(dai->dev, "%d rate not supported\n",
263 			params_rate(params));
264 		return -EINVAL;
265 	}
266 
267 	switch (params_channels(params)) {
268 	case 1:
269 		dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
270 		break;
271 	case 2:
272 		dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
273 		break;
274 	default:
275 		dev_err(dai->dev, "%d channels not supported\n",
276 			params_channels(params));
277 		return -EINVAL;
278 	}
279 
280 	/*
281 	 * The clock rate always rounds down when using clk_set_rate()
282 	 * so increase the rate a bit
283 	 */
284 	core_clk_rate += 64;
285 	jh7110_pwmdac_set(dev);
286 
287 	ret = clk_set_rate(dev->clks[1].clk, core_clk_rate);
288 	if (ret)
289 		return dev_err_probe(dai->dev, ret,
290 				     "failed to set rate %lu for core clock\n",
291 				     core_clk_rate);
292 
293 	return 0;
294 }
295 
296 static int jh7110_pwmdac_trigger(struct snd_pcm_substream *substream, int cmd,
297 				 struct snd_soc_dai *dai)
298 {
299 	struct jh7110_pwmdac_dev *dev = snd_soc_dai_get_drvdata(dai);
300 	int ret = 0;
301 
302 	switch (cmd) {
303 	case SNDRV_PCM_TRIGGER_START:
304 	case SNDRV_PCM_TRIGGER_RESUME:
305 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
306 		jh7110_pwmdac_set(dev);
307 		break;
308 
309 	case SNDRV_PCM_TRIGGER_STOP:
310 	case SNDRV_PCM_TRIGGER_SUSPEND:
311 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
312 		jh7110_pwmdac_stop(dev);
313 		break;
314 	default:
315 		ret = -EINVAL;
316 		break;
317 	}
318 
319 	return ret;
320 }
321 
322 static int jh7110_pwmdac_crg_enable(struct jh7110_pwmdac_dev *dev, bool enable)
323 {
324 	int ret;
325 
326 	if (enable) {
327 		ret = clk_bulk_prepare_enable(ARRAY_SIZE(dev->clks), dev->clks);
328 		if (ret)
329 			return dev_err_probe(dev->dev, ret,
330 					     "failed to enable pwmdac clocks\n");
331 
332 		ret = reset_control_deassert(dev->rst_apb);
333 		if (ret) {
334 			dev_err(dev->dev, "failed to deassert pwmdac apb reset\n");
335 			goto err_rst_apb;
336 		}
337 	} else {
338 		clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
339 	}
340 
341 	return 0;
342 
343 err_rst_apb:
344 	clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
345 
346 	return ret;
347 }
348 
349 static int jh7110_pwmdac_dai_probe(struct snd_soc_dai *dai)
350 {
351 	struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
352 
353 	snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, NULL);
354 	snd_soc_dai_set_drvdata(dai, dev);
355 
356 	return 0;
357 }
358 
359 static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
360 	.probe		= jh7110_pwmdac_dai_probe,
361 	.startup	= jh7110_pwmdac_startup,
362 	.hw_params	= jh7110_pwmdac_hw_params,
363 	.trigger	= jh7110_pwmdac_trigger,
364 };
365 
366 static const struct snd_soc_component_driver jh7110_pwmdac_component = {
367 	.name		= "jh7110-pwmdac",
368 };
369 
370 static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
371 	.name		= "jh7110-pwmdac",
372 	.id		= 0,
373 	.playback = {
374 		.channels_min = 1,
375 		.channels_max = 2,
376 		.rates = SNDRV_PCM_RATE_8000_48000,
377 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
378 	},
379 	.ops = &jh7110_pwmdac_dai_ops,
380 };
381 
382 static int jh7110_pwmdac_runtime_suspend(struct device *dev)
383 {
384 	struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
385 
386 	return jh7110_pwmdac_crg_enable(pwmdac, false);
387 }
388 
389 static int jh7110_pwmdac_runtime_resume(struct device *dev)
390 {
391 	struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
392 
393 	return jh7110_pwmdac_crg_enable(pwmdac, true);
394 }
395 
396 static int jh7110_pwmdac_system_suspend(struct device *dev)
397 {
398 	struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
399 
400 	/* save the CTRL register value */
401 	pwmdac->saved_ctrl = jh7110_pwmdac_read_reg(pwmdac->base,
402 						    JH7110_PWMDAC_CTRL);
403 	return pm_runtime_force_suspend(dev);
404 }
405 
406 static int jh7110_pwmdac_system_resume(struct device *dev)
407 {
408 	struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
409 	int ret;
410 
411 	ret = pm_runtime_force_resume(dev);
412 	if (ret)
413 		return ret;
414 
415 	/* restore the CTRL register value */
416 	jh7110_pwmdac_write_reg(pwmdac->base, JH7110_PWMDAC_CTRL,
417 				pwmdac->saved_ctrl);
418 	return 0;
419 }
420 
421 static const struct dev_pm_ops jh7110_pwmdac_pm_ops = {
422 	RUNTIME_PM_OPS(jh7110_pwmdac_runtime_suspend,
423 		       jh7110_pwmdac_runtime_resume, NULL)
424 	SYSTEM_SLEEP_PM_OPS(jh7110_pwmdac_system_suspend,
425 			    jh7110_pwmdac_system_resume)
426 };
427 
428 static void jh7110_pwmdac_init_params(struct jh7110_pwmdac_dev *dev)
429 {
430 	dev->cfg.shift = PWMDAC_SHIFT_8;
431 	dev->cfg.duty_cycle = PWMDAC_CYCLE_CENTER;
432 	dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
433 	dev->cfg.data_change = NO_CHANGE;
434 	dev->cfg.data_mode = INVERTER_DATA_MSB;
435 	dev->cfg.data_shift = PWMDAC_DATA_LEFT_SHIFT_BIT_0;
436 
437 	dev->play_dma_data.addr = dev->mapbase + JH7110_PWMDAC_WDATA;
438 	dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
439 	dev->play_dma_data.fifo_size = 1;
440 	dev->play_dma_data.maxburst = 16;
441 }
442 
443 static int jh7110_pwmdac_probe(struct platform_device *pdev)
444 {
445 	struct jh7110_pwmdac_dev *dev;
446 	struct resource *res;
447 	int ret;
448 
449 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
450 	if (!dev)
451 		return -ENOMEM;
452 
453 	dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
454 	if (IS_ERR(dev->base))
455 		return PTR_ERR(dev->base);
456 
457 	dev->mapbase = res->start;
458 
459 	dev->clks[0].id = "apb";
460 	dev->clks[1].id = "core";
461 
462 	ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(dev->clks), dev->clks);
463 	if (ret)
464 		return dev_err_probe(&pdev->dev, ret,
465 				     "failed to get pwmdac clocks\n");
466 
467 	dev->rst_apb = devm_reset_control_get_exclusive(&pdev->dev, NULL);
468 	if (IS_ERR(dev->rst_apb))
469 		return dev_err_probe(&pdev->dev, PTR_ERR(dev->rst_apb),
470 				     "failed to get pwmdac apb reset\n");
471 
472 	jh7110_pwmdac_init_params(dev);
473 
474 	dev->dev = &pdev->dev;
475 	dev_set_drvdata(&pdev->dev, dev);
476 	ret = devm_snd_soc_register_component(&pdev->dev,
477 					      &jh7110_pwmdac_component,
478 					      &jh7110_pwmdac_dai, 1);
479 	if (ret)
480 		return dev_err_probe(&pdev->dev, ret, "failed to register dai\n");
481 
482 	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
483 	if (ret)
484 		return dev_err_probe(&pdev->dev, ret, "failed to register pcm\n");
485 
486 	pm_runtime_enable(dev->dev);
487 	if (!pm_runtime_enabled(&pdev->dev)) {
488 		ret = jh7110_pwmdac_runtime_resume(&pdev->dev);
489 		if (ret)
490 			goto err_pm_disable;
491 	}
492 
493 	return 0;
494 
495 err_pm_disable:
496 	pm_runtime_disable(&pdev->dev);
497 
498 	return ret;
499 }
500 
501 static void jh7110_pwmdac_remove(struct platform_device *pdev)
502 {
503 	pm_runtime_disable(&pdev->dev);
504 }
505 
506 static const struct of_device_id jh7110_pwmdac_of_match[] = {
507 	{ .compatible = "starfive,jh7110-pwmdac" },
508 	{ /* sentinel */ }
509 };
510 MODULE_DEVICE_TABLE(of, jh7110_pwmdac_of_match);
511 
512 static struct platform_driver jh7110_pwmdac_driver = {
513 	.driver		= {
514 		.name	= "jh7110-pwmdac",
515 		.of_match_table = jh7110_pwmdac_of_match,
516 		.pm = pm_ptr(&jh7110_pwmdac_pm_ops),
517 	},
518 	.probe		= jh7110_pwmdac_probe,
519 	.remove_new	= jh7110_pwmdac_remove,
520 };
521 module_platform_driver(jh7110_pwmdac_driver);
522 
523 MODULE_AUTHOR("Jenny Zhang");
524 MODULE_AUTHOR("Curry Zhang");
525 MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
526 MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
527 MODULE_DESCRIPTION("StarFive JH7110 PWM-DAC driver");
528 MODULE_LICENSE("GPL");
529