xref: /linux/sound/pci/ctxfi/ctdaio.c (revision 277c6960d4ddb94d16198afd70c92c3d4593d131)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
4  *
5  * @File	ctdaio.c
6  *
7  * @Brief
8  * This file contains the implementation of Digital Audio Input Output
9  * resource management object.
10  *
11  * @Author	Liu Chun
12  * @Date 	May 23 2008
13  */
14 
15 #include "ctdaio.h"
16 #include "cthardware.h"
17 #include "ctimap.h"
18 #include <linux/slab.h>
19 #include <linux/kernel.h>
20 
21 struct daio_usage {
22 	unsigned short data;
23 };
24 
25 struct daio_rsc_idx {
26 	unsigned short left;
27 	unsigned short right;
28 };
29 
30 static const struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = {
31 	[LINEO1] = {.left = 0x00, .right = 0x01},
32 	[LINEO2] = {.left = 0x18, .right = 0x19},
33 	[LINEO3] = {.left = 0x08, .right = 0x09},
34 	[LINEO4] = {.left = 0x10, .right = 0x11},
35 	[LINEIM] = {.left = 0x1b5, .right = 0x1bd},
36 	[SPDIFOO] = {.left = 0x20, .right = 0x21},
37 	[SPDIFIO] = {.left = 0x15, .right = 0x1d},
38 	[SPDIFI1] = {.left = 0x95, .right = 0x9d},
39 };
40 
41 static const struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
42 	[LINEO1] = {.left = 0x40, .right = 0x41},
43 	[LINEO2] = {.left = 0x60, .right = 0x61},
44 	[LINEO3] = {.left = 0x50, .right = 0x51},
45 	[LINEO4] = {.left = 0x70, .right = 0x71},
46 	[LINEIM] = {.left = 0x45, .right = 0xc5},
47 	[MIC]	 = {.left = 0x55, .right = 0xd5},
48 	[RCA]	 = {.left = 0x30, .right = 0x31},
49 	[SPDIFOO] = {.left = 0x00, .right = 0x01},
50 	[SPDIFIO] = {.left = 0x05, .right = 0x85},
51 };
52 
53 static void daio_master(struct rsc *rsc)
54 {
55 	/* Actually, this is not the resource index of DAIO.
56 	 * For DAO, it is the input mapper index. And, for DAI,
57 	 * it is the output time-slot index. */
58 	rsc->conj = rsc->idx;
59 }
60 
61 static int daio_index(const struct rsc *rsc)
62 {
63 	return rsc->conj;
64 }
65 
66 static void daio_out_next_conj(struct rsc *rsc)
67 {
68 	rsc->conj += 2;
69 }
70 
71 static void daio_in_next_conj_20k1(struct rsc *rsc)
72 {
73 	rsc->conj += 0x200;
74 }
75 
76 static void daio_in_next_conj_20k2(struct rsc *rsc)
77 {
78 	rsc->conj += 0x100;
79 }
80 
81 static const struct rsc_ops daio_out_rsc_ops = {
82 	.master		= daio_master,
83 	.next_conj	= daio_out_next_conj,
84 	.index		= daio_index,
85 	.output_slot	= NULL,
86 };
87 
88 static const struct rsc_ops daio_in_rsc_ops_20k1 = {
89 	.master		= daio_master,
90 	.next_conj	= daio_in_next_conj_20k1,
91 	.index		= NULL,
92 	.output_slot	= daio_index,
93 };
94 
95 static const struct rsc_ops daio_in_rsc_ops_20k2 = {
96 	.master		= daio_master,
97 	.next_conj	= daio_in_next_conj_20k2,
98 	.index		= NULL,
99 	.output_slot	= daio_index,
100 };
101 
102 static int daio_device_index(enum DAIOTYP type, struct hw *hw)
103 {
104 	switch (hw->chip_type) {
105 	case ATC20K1:
106 		switch (type) {
107 		case SPDIFOO:	return 0;
108 		case SPDIFIO:	return 0;
109 		case SPDIFI1:	return 1;
110 		case LINEO1:	return 4;
111 		case LINEO2:	return 7;
112 		case LINEO3:	return 5;
113 		case LINEO4:	return 6;
114 		case LINEIM:	return 7;
115 		default:
116 			pr_err("ctxfi: Invalid type %d for hw20k1\n", type);
117 			return -EINVAL;
118 		}
119 	case ATC20K2:
120 		switch (type) {
121 		case SPDIFOO:	return 0;
122 		case SPDIFIO:	return 0;
123 		case SPDIFI1:	return 1;
124 		case LINEO1:	return 4;
125 		case LINEO2:	return 7;
126 		case LINEO3:	return 5;
127 		case LINEO4:	return 6;
128 		case LINEIM:	return 4;
129 		case MIC:	return 5;
130 		case RCA:	return 3;
131 		default:
132 			pr_err("ctxfi: Invalid type %d for hw20k2\n", type);
133 			return -EINVAL;
134 		}
135 	default:
136 		pr_err("ctxfi: Invalid chip type %d\n", hw->chip_type);
137 		return -EINVAL;
138 	}
139 }
140 
141 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc);
142 
143 static int dao_spdif_get_spos(struct dao *dao, unsigned int *spos)
144 {
145 	dao->hw->dao_get_spos(dao->ctrl_blk, spos);
146 	return 0;
147 }
148 
149 static int dao_spdif_set_spos(struct dao *dao, unsigned int spos)
150 {
151 	dao->hw->dao_set_spos(dao->ctrl_blk, spos);
152 	return 0;
153 }
154 
155 static int dao_commit_write(struct dao *dao)
156 {
157 	int idx = daio_device_index(dao->daio.type, dao->hw);
158 
159 	if (idx < 0)
160 		return idx;
161 	dao->hw->dao_commit_write(dao->hw, idx, dao->ctrl_blk);
162 	return 0;
163 }
164 
165 static int dao_set_left_input(struct dao *dao, struct rsc *input)
166 {
167 	struct imapper *entry;
168 	struct daio *daio = &dao->daio;
169 	int i;
170 
171 	entry = kzalloc_objs(*entry, daio->rscl.msr);
172 	if (!entry)
173 		return -ENOMEM;
174 
175 	dao->ops->clear_left_input(dao);
176 	/* Program master and conjugate resources */
177 	input->ops->master(input);
178 	daio->rscl.ops->master(&daio->rscl);
179 	for (i = 0; i < daio->rscl.msr; i++, entry++) {
180 		entry->slot = input->ops->output_slot(input);
181 		entry->user = entry->addr = daio->rscl.ops->index(&daio->rscl);
182 		dao->mgr->imap_add(dao->mgr, entry);
183 		dao->imappers[i] = entry;
184 
185 		input->ops->next_conj(input);
186 		daio->rscl.ops->next_conj(&daio->rscl);
187 	}
188 	input->ops->master(input);
189 	daio->rscl.ops->master(&daio->rscl);
190 
191 	return 0;
192 }
193 
194 static int dao_set_right_input(struct dao *dao, struct rsc *input)
195 {
196 	struct imapper *entry;
197 	struct daio *daio = &dao->daio;
198 	int i;
199 
200 	entry = kzalloc_objs(*entry, daio->rscr.msr);
201 	if (!entry)
202 		return -ENOMEM;
203 
204 	dao->ops->clear_right_input(dao);
205 	/* Program master and conjugate resources */
206 	input->ops->master(input);
207 	daio->rscr.ops->master(&daio->rscr);
208 	for (i = 0; i < daio->rscr.msr; i++, entry++) {
209 		entry->slot = input->ops->output_slot(input);
210 		entry->user = entry->addr = daio->rscr.ops->index(&daio->rscr);
211 		dao->mgr->imap_add(dao->mgr, entry);
212 		dao->imappers[daio->rscl.msr + i] = entry;
213 
214 		input->ops->next_conj(input);
215 		daio->rscr.ops->next_conj(&daio->rscr);
216 	}
217 	input->ops->master(input);
218 	daio->rscr.ops->master(&daio->rscr);
219 
220 	return 0;
221 }
222 
223 static int dao_clear_input(struct dao *dao, unsigned int start, unsigned int end)
224 {
225 	unsigned int i;
226 
227 	if (!dao->imappers[start])
228 		return 0;
229 	for (i = start; i < end; i++) {
230 		dao->mgr->imap_delete(dao->mgr, dao->imappers[i]);
231 		dao->imappers[i] = NULL;
232 	}
233 
234 	return 0;
235 }
236 
237 
238 static int dao_clear_left_input(struct dao *dao)
239 {
240 	return dao_clear_input(dao, 0, dao->daio.rscl.msr);
241 }
242 
243 static int dao_clear_right_input(struct dao *dao)
244 {
245 	return dao_clear_input(dao, dao->daio.rscl.msr,
246 			dao->daio.rscl.msr + dao->daio.rscr.msr);
247 }
248 
249 static const struct dao_rsc_ops dao_ops = {
250 	.set_spos		= dao_spdif_set_spos,
251 	.commit_write		= dao_commit_write,
252 	.get_spos		= dao_spdif_get_spos,
253 	.reinit			= dao_rsc_reinit,
254 	.set_left_input		= dao_set_left_input,
255 	.set_right_input	= dao_set_right_input,
256 	.clear_left_input	= dao_clear_left_input,
257 	.clear_right_input	= dao_clear_right_input,
258 };
259 
260 static int dai_set_srt_srcl(struct dai *dai, struct rsc *src)
261 {
262 	src->ops->master(src);
263 	dai->hw->dai_srt_set_srcm(dai->ctrl_blk, src->ops->index(src));
264 	return 0;
265 }
266 
267 static int dai_set_srt_srcr(struct dai *dai, struct rsc *src)
268 {
269 	src->ops->master(src);
270 	dai->hw->dai_srt_set_srco(dai->ctrl_blk, src->ops->index(src));
271 	return 0;
272 }
273 
274 static int dai_set_srt_msr(struct dai *dai, unsigned int msr)
275 {
276 	unsigned int rsr;
277 
278 	for (rsr = 0; msr > 1; msr >>= 1)
279 		rsr++;
280 
281 	dai->hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
282 	return 0;
283 }
284 
285 static int dai_set_enb_src(struct dai *dai, unsigned int enb)
286 {
287 	dai->hw->dai_srt_set_ec(dai->ctrl_blk, enb);
288 	return 0;
289 }
290 
291 static int dai_set_enb_srt(struct dai *dai, unsigned int enb)
292 {
293 	dai->hw->dai_srt_set_et(dai->ctrl_blk, enb);
294 	return 0;
295 }
296 
297 static int dai_commit_write(struct dai *dai)
298 {
299 	int idx = daio_device_index(dai->daio.type, dai->hw);
300 
301 	if (idx < 0)
302 		return idx;
303 	dai->hw->dai_commit_write(dai->hw, idx, dai->ctrl_blk);
304 	return 0;
305 }
306 
307 static const struct dai_rsc_ops dai_ops = {
308 	.set_srt_srcl		= dai_set_srt_srcl,
309 	.set_srt_srcr		= dai_set_srt_srcr,
310 	.set_srt_msr		= dai_set_srt_msr,
311 	.set_enb_src		= dai_set_enb_src,
312 	.set_enb_srt		= dai_set_enb_srt,
313 	.commit_write		= dai_commit_write,
314 };
315 
316 static int daio_rsc_init(struct daio *daio,
317 			 const struct daio_desc *desc,
318 			 struct hw *hw)
319 {
320 	int err;
321 	unsigned int idx_l, idx_r;
322 
323 	switch (hw->chip_type) {
324 	case ATC20K1:
325 		idx_l = idx_20k1[desc->type].left;
326 		idx_r = idx_20k1[desc->type].right;
327 		break;
328 	case ATC20K2:
329 		idx_l = idx_20k2[desc->type].left;
330 		idx_r = idx_20k2[desc->type].right;
331 		break;
332 	default:
333 		return -EINVAL;
334 	}
335 	err = rsc_init(&daio->rscl, idx_l, DAIO, desc->msr, hw);
336 	if (err)
337 		return err;
338 
339 	err = rsc_init(&daio->rscr, idx_r, DAIO, desc->msr, hw);
340 	if (err)
341 		goto error1;
342 
343 	/* Set daio->rscl/r->ops to daio specific ones */
344 	if (desc->output) {
345 		daio->rscl.ops = daio->rscr.ops = &daio_out_rsc_ops;
346 	} else {
347 		switch (hw->chip_type) {
348 		case ATC20K1:
349 			daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k1;
350 			break;
351 		case ATC20K2:
352 			daio->rscl.ops = daio->rscr.ops = &daio_in_rsc_ops_20k2;
353 			break;
354 		default:
355 			break;
356 		}
357 	}
358 	daio->type = desc->type;
359 	daio->output = desc->output;
360 
361 	return 0;
362 
363 error1:
364 	rsc_uninit(&daio->rscl);
365 	return err;
366 }
367 
368 static int daio_rsc_uninit(struct daio *daio)
369 {
370 	rsc_uninit(&daio->rscl);
371 	rsc_uninit(&daio->rscr);
372 
373 	return 0;
374 }
375 
376 static int dao_rsc_init(struct dao *dao,
377 			const struct daio_desc *desc,
378 			struct daio_mgr *mgr)
379 {
380 	struct hw *hw = mgr->mgr.hw;
381 	unsigned int conf;
382 	int idx, err;
383 
384 	err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw);
385 	if (err)
386 		return err;
387 
388 	dao->imappers = kzalloc(array3_size(sizeof(void *), desc->msr, 2),
389 				GFP_KERNEL);
390 	if (!dao->imappers) {
391 		err = -ENOMEM;
392 		goto error1;
393 	}
394 	dao->ops = &dao_ops;
395 	dao->mgr = mgr;
396 	dao->hw = hw;
397 	err = hw->dao_get_ctrl_blk(&dao->ctrl_blk);
398 	if (err)
399 		goto error2;
400 
401 	idx = daio_device_index(dao->daio.type, hw);
402 	if (idx < 0) {
403 		err = idx;
404 		goto error2;
405 	}
406 
407 	hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, idx);
408 	hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
409 
410 	conf = (desc->msr & 0x7) | (desc->passthru << 3);
411 	hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk, idx, conf);
412 	hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, idx);
413 	hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
414 
415 	return 0;
416 
417 error2:
418 	kfree(dao->imappers);
419 	dao->imappers = NULL;
420 error1:
421 	daio_rsc_uninit(&dao->daio);
422 	return err;
423 }
424 
425 static int dao_rsc_uninit(struct dao *dao)
426 {
427 	if (dao->imappers) {
428 		if (dao->imappers[0])
429 			dao_clear_left_input(dao);
430 
431 		if (dao->imappers[dao->daio.rscl.msr])
432 			dao_clear_right_input(dao);
433 
434 		kfree(dao->imappers);
435 		dao->imappers = NULL;
436 	}
437 	dao->hw->dao_put_ctrl_blk(dao->ctrl_blk);
438 	dao->hw = dao->ctrl_blk = NULL;
439 	daio_rsc_uninit(&dao->daio);
440 
441 	return 0;
442 }
443 
444 static int dao_rsc_reinit(struct dao *dao, const struct dao_desc *desc)
445 {
446 	struct daio_mgr *mgr = dao->mgr;
447 	struct daio_desc dsc = {0};
448 
449 	dsc.type = dao->daio.type;
450 	dsc.msr = desc->msr;
451 	dsc.passthru = desc->passthru;
452 	dsc.output = dao->daio.output;
453 	dao_rsc_uninit(dao);
454 	return dao_rsc_init(dao, &dsc, mgr);
455 }
456 
457 static int dai_rsc_init(struct dai *dai,
458 			const struct daio_desc *desc,
459 			struct daio_mgr *mgr)
460 {
461 	int idx, err;
462 	struct hw *hw = mgr->mgr.hw;
463 	unsigned int rsr, msr;
464 
465 	err = daio_rsc_init(&dai->daio, desc, mgr->mgr.hw);
466 	if (err)
467 		return err;
468 
469 	dai->ops = &dai_ops;
470 	dai->hw = mgr->mgr.hw;
471 	err = hw->dai_get_ctrl_blk(&dai->ctrl_blk);
472 	if (err)
473 		goto error1;
474 
475 	idx = daio_device_index(dai->daio.type, dai->hw);
476 	if (idx < 0) {
477 		err = idx;
478 		goto error1;
479 	}
480 
481 	for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1)
482 		rsr++;
483 
484 	hw->dai_srt_set_rsr(dai->ctrl_blk, rsr);
485 	hw->dai_srt_set_drat(dai->ctrl_blk, 0);
486 	/* default to disabling control of a SRC */
487 	hw->dai_srt_set_ec(dai->ctrl_blk, 0);
488 	hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */
489 	hw->dai_commit_write(hw, idx, dai->ctrl_blk);
490 
491 	return 0;
492 
493 error1:
494 	daio_rsc_uninit(&dai->daio);
495 	return err;
496 }
497 
498 static int dai_rsc_uninit(struct dai *dai)
499 {
500 	dai->hw->dai_put_ctrl_blk(dai->ctrl_blk);
501 	dai->hw = dai->ctrl_blk = NULL;
502 	daio_rsc_uninit(&dai->daio);
503 	return 0;
504 }
505 
506 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
507 {
508 	if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
509 		return -ENOENT;
510 
511 	((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
512 
513 	return 0;
514 }
515 
516 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
517 {
518 	((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
519 
520 	return 0;
521 }
522 
523 static int get_daio_rsc(struct daio_mgr *mgr,
524 			const struct daio_desc *desc,
525 			struct daio **rdaio)
526 {
527 	int err;
528 
529 	*rdaio = NULL;
530 
531 	/* Check whether there are sufficient daio resources to meet request. */
532 	scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
533 		err = daio_mgr_get_rsc(&mgr->mgr, desc->type);
534 	}
535 	if (err) {
536 		dev_err(mgr->card->dev,
537 			"Can't meet DAIO resource request!\n");
538 		return err;
539 	}
540 
541 	err = -ENOMEM;
542 	/* Allocate mem for daio resource */
543 	if (desc->output) {
544 		struct dao *dao = kzalloc(sizeof(*dao), GFP_KERNEL);
545 		if (!dao)
546 			goto error;
547 
548 		err = dao_rsc_init(dao, desc, mgr);
549 		if (err) {
550 			kfree(dao);
551 			goto error;
552 		}
553 
554 		*rdaio = &dao->daio;
555 	} else {
556 		struct dai *dai = kzalloc(sizeof(*dai), GFP_KERNEL);
557 		if (!dai)
558 			goto error;
559 
560 		err = dai_rsc_init(dai, desc, mgr);
561 		if (err) {
562 			kfree(dai);
563 			goto error;
564 		}
565 
566 		*rdaio = &dai->daio;
567 	}
568 
569 	mgr->daio_enable(mgr, *rdaio);
570 	mgr->commit_write(mgr);
571 
572 	return 0;
573 
574 error:
575 	scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
576 		daio_mgr_put_rsc(&mgr->mgr, desc->type);
577 	}
578 	return err;
579 }
580 
581 static int put_daio_rsc(struct daio_mgr *mgr, struct daio *daio)
582 {
583 	mgr->daio_disable(mgr, daio);
584 	mgr->commit_write(mgr);
585 
586 	scoped_guard(spinlock_irqsave, &mgr->mgr_lock) {
587 		daio_mgr_put_rsc(&mgr->mgr, daio->type);
588 	}
589 
590 	if (daio->output) {
591 		dao_rsc_uninit(container_of(daio, struct dao, daio));
592 		kfree(container_of(daio, struct dao, daio));
593 	} else {
594 		dai_rsc_uninit(container_of(daio, struct dai, daio));
595 		kfree(container_of(daio, struct dai, daio));
596 	}
597 
598 	return 0;
599 }
600 
601 static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio)
602 {
603 	struct hw *hw = mgr->mgr.hw;
604 	int idx = daio_device_index(daio->type, hw);
605 
606 	if (idx < 0)
607 		return idx;
608 	if (daio->output)
609 		hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, idx);
610 	else
611 		hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk, idx);
612 	return 0;
613 }
614 
615 static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio)
616 {
617 	struct hw *hw = mgr->mgr.hw;
618 	int idx = daio_device_index(daio->type, hw);
619 
620 	if (idx < 0)
621 		return idx;
622 	if (daio->output)
623 		hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, idx);
624 	else
625 		hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk, idx);
626 	return 0;
627 }
628 
629 static int daio_map_op(void *data, struct imapper *entry)
630 {
631 	struct rsc_mgr *mgr = &((struct daio_mgr *)data)->mgr;
632 	struct hw *hw = mgr->hw;
633 
634 	hw->daio_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
635 	hw->daio_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
636 	hw->daio_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
637 	hw->daio_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
638 
639 	return 0;
640 }
641 
642 static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
643 {
644 	guard(spinlock_irqsave)(&mgr->imap_lock);
645 	if (!entry->addr && mgr->init_imap_added) {
646 		input_mapper_delete(&mgr->imappers, mgr->init_imap,
647 							daio_map_op, mgr);
648 		mgr->init_imap_added = 0;
649 	}
650 	return input_mapper_add(&mgr->imappers, entry, daio_map_op, mgr);
651 }
652 
653 static int daio_imap_delete(struct daio_mgr *mgr, struct imapper *entry)
654 {
655 	int err;
656 
657 	guard(spinlock_irqsave)(&mgr->imap_lock);
658 	err = input_mapper_delete(&mgr->imappers, entry, daio_map_op, mgr);
659 	if (list_empty(&mgr->imappers)) {
660 		input_mapper_add(&mgr->imappers, mgr->init_imap,
661 							daio_map_op, mgr);
662 		mgr->init_imap_added = 1;
663 	}
664 
665 	return err;
666 }
667 
668 static int daio_mgr_commit_write(struct daio_mgr *mgr)
669 {
670 	struct hw *hw = mgr->mgr.hw;
671 
672 	hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
673 	return 0;
674 }
675 
676 int daio_mgr_create(struct hw *hw, void **rdaio_mgr)
677 {
678 	int err, i;
679 	struct daio_mgr *daio_mgr;
680 	struct imapper *entry;
681 
682 	*rdaio_mgr = NULL;
683 	daio_mgr = kzalloc_obj(*daio_mgr);
684 	if (!daio_mgr)
685 		return -ENOMEM;
686 
687 	err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
688 	if (err)
689 		goto error1;
690 
691 	spin_lock_init(&daio_mgr->mgr_lock);
692 	spin_lock_init(&daio_mgr->imap_lock);
693 	INIT_LIST_HEAD(&daio_mgr->imappers);
694 	entry = kzalloc_obj(*entry);
695 	if (!entry) {
696 		err = -ENOMEM;
697 		goto error2;
698 	}
699 	entry->slot = entry->addr = entry->next = entry->user = 0;
700 	list_add(&entry->list, &daio_mgr->imappers);
701 	daio_mgr->init_imap = entry;
702 	daio_mgr->init_imap_added = 1;
703 
704 	daio_mgr->get_daio = get_daio_rsc;
705 	daio_mgr->put_daio = put_daio_rsc;
706 	daio_mgr->daio_enable = daio_mgr_enb_daio;
707 	daio_mgr->daio_disable = daio_mgr_dsb_daio;
708 	daio_mgr->imap_add = daio_imap_add;
709 	daio_mgr->imap_delete = daio_imap_delete;
710 	daio_mgr->commit_write = daio_mgr_commit_write;
711 	daio_mgr->card = hw->card;
712 
713 	for (i = 0; i < 8; i++) {
714 		hw->daio_mgr_dsb_dao(daio_mgr->mgr.ctrl_blk, i);
715 		hw->daio_mgr_dsb_dai(daio_mgr->mgr.ctrl_blk, i);
716 	}
717 	hw->daio_mgr_commit_write(hw, daio_mgr->mgr.ctrl_blk);
718 
719 	*rdaio_mgr = daio_mgr;
720 
721 	return 0;
722 
723 error2:
724 	rsc_mgr_uninit(&daio_mgr->mgr);
725 error1:
726 	kfree(daio_mgr);
727 	return err;
728 }
729 
730 int daio_mgr_destroy(void *ptr)
731 {
732 	struct daio_mgr *daio_mgr = ptr;
733 
734 	/* free daio input mapper list */
735 	scoped_guard(spinlock_irqsave, &daio_mgr->imap_lock) {
736 		free_input_mapper_list(&daio_mgr->imappers);
737 	}
738 
739 	rsc_mgr_uninit(&daio_mgr->mgr);
740 	kfree(daio_mgr);
741 
742 	return 0;
743 }
744 
745