1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
8 * This file contains the implementation of the Sample Rate Convertor
9 * resource management object.
16 #include "cthardware.h"
17 #include <linux/slab.h>
19 #define SRC_RESOURCE_NUM 256
20 #define SRCIMP_RESOURCE_NUM 256
22 static unsigned int conj_mask
;
24 static int src_default_config_memrd(struct src
*src
);
25 static int src_default_config_memwr(struct src
*src
);
26 static int src_default_config_arcrw(struct src
*src
);
28 static int (*src_default_config
[3])(struct src
*) = {
29 [MEMRD
] = src_default_config_memrd
,
30 [MEMWR
] = src_default_config_memwr
,
31 [ARCRW
] = src_default_config_arcrw
34 static int src_set_state(struct src
*src
, unsigned int state
)
39 hw
->src_set_state(src
->rsc
.ctrl_blk
, state
);
44 static int src_set_bm(struct src
*src
, unsigned int bm
)
49 hw
->src_set_bm(src
->rsc
.ctrl_blk
, bm
);
54 static int src_set_sf(struct src
*src
, unsigned int sf
)
59 hw
->src_set_sf(src
->rsc
.ctrl_blk
, sf
);
64 static int src_set_pm(struct src
*src
, unsigned int pm
)
69 hw
->src_set_pm(src
->rsc
.ctrl_blk
, pm
);
74 static int src_set_rom(struct src
*src
, unsigned int rom
)
79 hw
->src_set_rom(src
->rsc
.ctrl_blk
, rom
);
84 static int src_set_vo(struct src
*src
, unsigned int vo
)
89 hw
->src_set_vo(src
->rsc
.ctrl_blk
, vo
);
94 static int src_set_st(struct src
*src
, unsigned int st
)
99 hw
->src_set_st(src
->rsc
.ctrl_blk
, st
);
104 static int src_set_bp(struct src
*src
, unsigned int bp
)
109 hw
->src_set_bp(src
->rsc
.ctrl_blk
, bp
);
114 static int src_set_cisz(struct src
*src
, unsigned int cisz
)
119 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, cisz
);
124 static int src_set_ca(struct src
*src
, unsigned int ca
)
129 hw
->src_set_ca(src
->rsc
.ctrl_blk
, ca
);
134 static int src_set_sa(struct src
*src
, unsigned int sa
)
139 hw
->src_set_sa(src
->rsc
.ctrl_blk
, sa
);
144 static int src_set_la(struct src
*src
, unsigned int la
)
149 hw
->src_set_la(src
->rsc
.ctrl_blk
, la
);
154 static int src_set_pitch(struct src
*src
, unsigned int pitch
)
159 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, pitch
);
164 static int src_set_clear_zbufs(struct src
*src
)
169 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
174 static int src_commit_write(struct src
*src
)
178 unsigned int dirty
= 0;
181 src
->rsc
.ops
->master(&src
->rsc
);
182 if (src
->rsc
.msr
> 1) {
183 /* Save dirty flags for conjugate resource programming */
184 dirty
= hw
->src_get_dirty(src
->rsc
.ctrl_blk
) & conj_mask
;
186 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
189 /* Program conjugate parameter mixer resources */
190 if (MEMWR
== src
->mode
)
193 for (i
= 1; i
< src
->rsc
.msr
; i
++) {
194 src
->rsc
.ops
->next_conj(&src
->rsc
);
195 hw
->src_set_dirty(src
->rsc
.ctrl_blk
, dirty
);
196 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
199 src
->rsc
.ops
->master(&src
->rsc
);
204 static int src_get_ca(struct src
*src
)
209 return hw
->src_get_ca(hw
, src
->rsc
.ops
->index(&src
->rsc
),
213 static int src_init(struct src
*src
)
215 src_default_config
[src
->mode
](src
);
220 static struct src
*src_next_interleave(struct src
*src
)
225 static int src_default_config_memrd(struct src
*src
)
227 struct hw
*hw
= src
->rsc
.hw
;
228 unsigned int rsr
, msr
;
230 hw
->src_set_state(src
->rsc
.ctrl_blk
, SRC_STATE_OFF
);
231 hw
->src_set_bm(src
->rsc
.ctrl_blk
, 1);
232 for (rsr
= 0, msr
= src
->rsc
.msr
; msr
> 1; msr
>>= 1)
235 hw
->src_set_rsr(src
->rsc
.ctrl_blk
, rsr
);
236 hw
->src_set_sf(src
->rsc
.ctrl_blk
, SRC_SF_S16
);
237 hw
->src_set_wr(src
->rsc
.ctrl_blk
, 0);
238 hw
->src_set_pm(src
->rsc
.ctrl_blk
, 0);
239 hw
->src_set_rom(src
->rsc
.ctrl_blk
, 0);
240 hw
->src_set_vo(src
->rsc
.ctrl_blk
, 0);
241 hw
->src_set_st(src
->rsc
.ctrl_blk
, 0);
242 hw
->src_set_ilsz(src
->rsc
.ctrl_blk
, src
->multi
- 1);
243 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, 0x80);
244 hw
->src_set_sa(src
->rsc
.ctrl_blk
, 0x0);
245 hw
->src_set_la(src
->rsc
.ctrl_blk
, 0x1000);
246 hw
->src_set_ca(src
->rsc
.ctrl_blk
, 0x80);
247 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
248 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
250 src
->rsc
.ops
->master(&src
->rsc
);
251 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
254 for (msr
= 1; msr
< src
->rsc
.msr
; msr
++) {
255 src
->rsc
.ops
->next_conj(&src
->rsc
);
256 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
257 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
260 src
->rsc
.ops
->master(&src
->rsc
);
265 static int src_default_config_memwr(struct src
*src
)
267 struct hw
*hw
= src
->rsc
.hw
;
269 hw
->src_set_state(src
->rsc
.ctrl_blk
, SRC_STATE_OFF
);
270 hw
->src_set_bm(src
->rsc
.ctrl_blk
, 1);
271 hw
->src_set_rsr(src
->rsc
.ctrl_blk
, 0);
272 hw
->src_set_sf(src
->rsc
.ctrl_blk
, SRC_SF_S16
);
273 hw
->src_set_wr(src
->rsc
.ctrl_blk
, 1);
274 hw
->src_set_pm(src
->rsc
.ctrl_blk
, 0);
275 hw
->src_set_rom(src
->rsc
.ctrl_blk
, 0);
276 hw
->src_set_vo(src
->rsc
.ctrl_blk
, 0);
277 hw
->src_set_st(src
->rsc
.ctrl_blk
, 0);
278 hw
->src_set_ilsz(src
->rsc
.ctrl_blk
, 0);
279 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, 0x80);
280 hw
->src_set_sa(src
->rsc
.ctrl_blk
, 0x0);
281 hw
->src_set_la(src
->rsc
.ctrl_blk
, 0x1000);
282 hw
->src_set_ca(src
->rsc
.ctrl_blk
, 0x80);
283 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
284 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
286 src
->rsc
.ops
->master(&src
->rsc
);
287 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
293 static int src_default_config_arcrw(struct src
*src
)
295 struct hw
*hw
= src
->rsc
.hw
;
296 unsigned int rsr
, msr
;
299 hw
->src_set_state(src
->rsc
.ctrl_blk
, SRC_STATE_OFF
);
300 hw
->src_set_bm(src
->rsc
.ctrl_blk
, 0);
301 for (rsr
= 0, msr
= src
->rsc
.msr
; msr
> 1; msr
>>= 1)
304 hw
->src_set_rsr(src
->rsc
.ctrl_blk
, rsr
);
305 hw
->src_set_sf(src
->rsc
.ctrl_blk
, SRC_SF_F32
);
306 hw
->src_set_wr(src
->rsc
.ctrl_blk
, 0);
307 hw
->src_set_pm(src
->rsc
.ctrl_blk
, 0);
308 hw
->src_set_rom(src
->rsc
.ctrl_blk
, 0);
309 hw
->src_set_vo(src
->rsc
.ctrl_blk
, 0);
310 hw
->src_set_st(src
->rsc
.ctrl_blk
, 0);
311 hw
->src_set_ilsz(src
->rsc
.ctrl_blk
, 0);
312 hw
->src_set_cisz(src
->rsc
.ctrl_blk
, 0x80);
313 hw
->src_set_sa(src
->rsc
.ctrl_blk
, 0x0);
314 /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/
315 hw
->src_set_la(src
->rsc
.ctrl_blk
, 0x1000);
316 /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/
317 hw
->src_set_ca(src
->rsc
.ctrl_blk
, 0x80);
318 hw
->src_set_pitch(src
->rsc
.ctrl_blk
, 0x1000000);
319 hw
->src_set_clear_zbufs(src
->rsc
.ctrl_blk
, 1);
321 dirty
= hw
->src_get_dirty(src
->rsc
.ctrl_blk
);
322 src
->rsc
.ops
->master(&src
->rsc
);
323 for (msr
= 0; msr
< src
->rsc
.msr
; msr
++) {
324 hw
->src_set_dirty(src
->rsc
.ctrl_blk
, dirty
);
325 hw
->src_commit_write(hw
, src
->rsc
.ops
->index(&src
->rsc
),
327 src
->rsc
.ops
->next_conj(&src
->rsc
);
329 src
->rsc
.ops
->master(&src
->rsc
);
334 static const struct src_rsc_ops src_rsc_ops
= {
335 .set_state
= src_set_state
,
336 .set_bm
= src_set_bm
,
337 .set_sf
= src_set_sf
,
338 .set_pm
= src_set_pm
,
339 .set_rom
= src_set_rom
,
340 .set_vo
= src_set_vo
,
341 .set_st
= src_set_st
,
342 .set_bp
= src_set_bp
,
343 .set_cisz
= src_set_cisz
,
344 .set_ca
= src_set_ca
,
345 .set_sa
= src_set_sa
,
346 .set_la
= src_set_la
,
347 .set_pitch
= src_set_pitch
,
348 .set_clr_zbufs
= src_set_clear_zbufs
,
349 .commit_write
= src_commit_write
,
350 .get_ca
= src_get_ca
,
352 .next_interleave
= src_next_interleave
,
356 src_rsc_init(struct src
*src
, u32 idx
,
357 const struct src_desc
*desc
, struct src_mgr
*mgr
)
363 n
= (MEMRD
== desc
->mode
) ? desc
->multi
: 1;
364 for (i
= 0, p
= src
; i
< n
; i
++, p
++) {
365 err
= rsc_init(&p
->rsc
, idx
+ i
, SRC
, desc
->msr
, mgr
->mgr
.hw
);
369 /* Initialize src specific rsc operations */
370 p
->ops
= &src_rsc_ops
;
371 p
->multi
= (0 == i
) ? desc
->multi
: 1;
372 p
->mode
= desc
->mode
;
373 src_default_config
[desc
->mode
](p
);
374 mgr
->src_enable(mgr
, p
);
377 (--p
)->intlv
= NULL
; /* Set @intlv of the last SRC to NULL */
379 mgr
->commit_write(mgr
);
384 for (i
--, p
--; i
>= 0; i
--, p
--) {
385 mgr
->src_disable(mgr
, p
);
388 mgr
->commit_write(mgr
);
392 static int src_rsc_uninit(struct src
*src
, struct src_mgr
*mgr
)
397 n
= (MEMRD
== src
->mode
) ? src
->multi
: 1;
398 for (i
= 0, p
= src
; i
< n
; i
++, p
++) {
399 mgr
->src_disable(mgr
, p
);
403 p
->mode
= NUM_SRCMODES
;
406 mgr
->commit_write(mgr
);
412 get_src_rsc(struct src_mgr
*mgr
, const struct src_desc
*desc
, struct src
**rsrc
)
414 unsigned int idx
= SRC_RESOURCE_NUM
;
421 /* Check whether there are sufficient src resources to meet request. */
422 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
423 if (MEMRD
== desc
->mode
)
424 err
= mgr_get_resource(&mgr
->mgr
, desc
->multi
, &idx
);
426 err
= mgr_get_resource(&mgr
->mgr
, 1, &idx
);
428 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
430 dev_err(mgr
->card
->dev
,
431 "Can't meet SRC resource request!\n");
435 /* Allocate mem for master src resource */
436 if (MEMRD
== desc
->mode
)
437 src
= kcalloc(desc
->multi
, sizeof(*src
), GFP_KERNEL
);
439 src
= kzalloc(sizeof(*src
), GFP_KERNEL
);
446 err
= src_rsc_init(src
, idx
, desc
, mgr
);
457 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
458 if (MEMRD
== desc
->mode
)
459 mgr_put_resource(&mgr
->mgr
, desc
->multi
, idx
);
461 mgr_put_resource(&mgr
->mgr
, 1, idx
);
463 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
467 static int put_src_rsc(struct src_mgr
*mgr
, struct src
*src
)
471 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
472 src
->rsc
.ops
->master(&src
->rsc
);
473 if (MEMRD
== src
->mode
)
474 mgr_put_resource(&mgr
->mgr
, src
->multi
,
475 src
->rsc
.ops
->index(&src
->rsc
));
477 mgr_put_resource(&mgr
->mgr
, 1, src
->rsc
.ops
->index(&src
->rsc
));
479 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
480 src_rsc_uninit(src
, mgr
);
486 static int src_enable_s(struct src_mgr
*mgr
, struct src
*src
)
488 struct hw
*hw
= mgr
->mgr
.hw
;
491 src
->rsc
.ops
->master(&src
->rsc
);
492 for (i
= 0; i
< src
->rsc
.msr
; i
++) {
493 hw
->src_mgr_enbs_src(mgr
->mgr
.ctrl_blk
,
494 src
->rsc
.ops
->index(&src
->rsc
));
495 src
->rsc
.ops
->next_conj(&src
->rsc
);
497 src
->rsc
.ops
->master(&src
->rsc
);
502 static int src_enable(struct src_mgr
*mgr
, struct src
*src
)
504 struct hw
*hw
= mgr
->mgr
.hw
;
507 src
->rsc
.ops
->master(&src
->rsc
);
508 for (i
= 0; i
< src
->rsc
.msr
; i
++) {
509 hw
->src_mgr_enb_src(mgr
->mgr
.ctrl_blk
,
510 src
->rsc
.ops
->index(&src
->rsc
));
511 src
->rsc
.ops
->next_conj(&src
->rsc
);
513 src
->rsc
.ops
->master(&src
->rsc
);
518 static int src_disable(struct src_mgr
*mgr
, struct src
*src
)
520 struct hw
*hw
= mgr
->mgr
.hw
;
523 src
->rsc
.ops
->master(&src
->rsc
);
524 for (i
= 0; i
< src
->rsc
.msr
; i
++) {
525 hw
->src_mgr_dsb_src(mgr
->mgr
.ctrl_blk
,
526 src
->rsc
.ops
->index(&src
->rsc
));
527 src
->rsc
.ops
->next_conj(&src
->rsc
);
529 src
->rsc
.ops
->master(&src
->rsc
);
534 static int src_mgr_commit_write(struct src_mgr
*mgr
)
536 struct hw
*hw
= mgr
->mgr
.hw
;
538 hw
->src_mgr_commit_write(hw
, mgr
->mgr
.ctrl_blk
);
543 int src_mgr_create(struct hw
*hw
, struct src_mgr
**rsrc_mgr
)
546 struct src_mgr
*src_mgr
;
549 src_mgr
= kzalloc(sizeof(*src_mgr
), GFP_KERNEL
);
553 err
= rsc_mgr_init(&src_mgr
->mgr
, SRC
, SRC_RESOURCE_NUM
, hw
);
557 spin_lock_init(&src_mgr
->mgr_lock
);
558 conj_mask
= hw
->src_dirty_conj_mask();
560 src_mgr
->get_src
= get_src_rsc
;
561 src_mgr
->put_src
= put_src_rsc
;
562 src_mgr
->src_enable_s
= src_enable_s
;
563 src_mgr
->src_enable
= src_enable
;
564 src_mgr
->src_disable
= src_disable
;
565 src_mgr
->commit_write
= src_mgr_commit_write
;
566 src_mgr
->card
= hw
->card
;
568 /* Disable all SRC resources. */
569 for (i
= 0; i
< 256; i
++)
570 hw
->src_mgr_dsb_src(src_mgr
->mgr
.ctrl_blk
, i
);
572 hw
->src_mgr_commit_write(hw
, src_mgr
->mgr
.ctrl_blk
);
583 int src_mgr_destroy(struct src_mgr
*src_mgr
)
585 rsc_mgr_uninit(&src_mgr
->mgr
);
591 /* SRCIMP resource manager operations */
593 static int srcimp_master(struct rsc
*rsc
)
596 return rsc
->idx
= container_of(rsc
, struct srcimp
, rsc
)->idx
[0];
599 static int srcimp_next_conj(struct rsc
*rsc
)
602 return container_of(rsc
, struct srcimp
, rsc
)->idx
[rsc
->conj
];
605 static int srcimp_index(const struct rsc
*rsc
)
607 return container_of(rsc
, struct srcimp
, rsc
)->idx
[rsc
->conj
];
610 static const struct rsc_ops srcimp_basic_rsc_ops
= {
611 .master
= srcimp_master
,
612 .next_conj
= srcimp_next_conj
,
613 .index
= srcimp_index
,
617 static int srcimp_map(struct srcimp
*srcimp
, struct src
*src
, struct rsc
*input
)
619 struct imapper
*entry
;
622 srcimp
->rsc
.ops
->master(&srcimp
->rsc
);
623 src
->rsc
.ops
->master(&src
->rsc
);
624 input
->ops
->master(input
);
626 /* Program master and conjugate resources */
627 for (i
= 0; i
< srcimp
->rsc
.msr
; i
++) {
628 entry
= &srcimp
->imappers
[i
];
629 entry
->slot
= input
->ops
->output_slot(input
);
630 entry
->user
= src
->rsc
.ops
->index(&src
->rsc
);
631 entry
->addr
= srcimp
->rsc
.ops
->index(&srcimp
->rsc
);
632 srcimp
->mgr
->imap_add(srcimp
->mgr
, entry
);
633 srcimp
->mapped
|= (0x1 << i
);
635 srcimp
->rsc
.ops
->next_conj(&srcimp
->rsc
);
636 input
->ops
->next_conj(input
);
639 srcimp
->rsc
.ops
->master(&srcimp
->rsc
);
640 input
->ops
->master(input
);
645 static int srcimp_unmap(struct srcimp
*srcimp
)
649 /* Program master and conjugate resources */
650 for (i
= 0; i
< srcimp
->rsc
.msr
; i
++) {
651 if (srcimp
->mapped
& (0x1 << i
)) {
652 srcimp
->mgr
->imap_delete(srcimp
->mgr
,
653 &srcimp
->imappers
[i
]);
654 srcimp
->mapped
&= ~(0x1 << i
);
661 static const struct srcimp_rsc_ops srcimp_ops
= {
663 .unmap
= srcimp_unmap
666 static int srcimp_rsc_init(struct srcimp
*srcimp
,
667 const struct srcimp_desc
*desc
,
668 struct srcimp_mgr
*mgr
)
672 err
= rsc_init(&srcimp
->rsc
, srcimp
->idx
[0],
673 SRCIMP
, desc
->msr
, mgr
->mgr
.hw
);
677 /* Reserve memory for imapper nodes */
678 srcimp
->imappers
= kcalloc(desc
->msr
, sizeof(struct imapper
),
680 if (!srcimp
->imappers
) {
685 /* Set srcimp specific operations */
686 srcimp
->rsc
.ops
= &srcimp_basic_rsc_ops
;
687 srcimp
->ops
= &srcimp_ops
;
690 srcimp
->rsc
.ops
->master(&srcimp
->rsc
);
695 rsc_uninit(&srcimp
->rsc
);
699 static int srcimp_rsc_uninit(struct srcimp
*srcimp
)
701 kfree(srcimp
->imappers
);
702 srcimp
->imappers
= NULL
;
705 rsc_uninit(&srcimp
->rsc
);
710 static int get_srcimp_rsc(struct srcimp_mgr
*mgr
,
711 const struct srcimp_desc
*desc
,
712 struct srcimp
**rsrcimp
)
716 struct srcimp
*srcimp
;
721 /* Allocate mem for SRCIMP resource */
722 srcimp
= kzalloc(sizeof(*srcimp
), GFP_KERNEL
);
726 /* Check whether there are sufficient SRCIMP resources. */
728 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
729 for (i
= 0; i
< desc
->msr
; i
++) {
730 err
= mgr_get_resource(&mgr
->mgr
, 1, &idx
);
734 srcimp
->idx
[i
] = idx
;
736 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
738 dev_err(mgr
->card
->dev
,
739 "Can't meet SRCIMP resource request!\n");
743 err
= srcimp_rsc_init(srcimp
, desc
, mgr
);
752 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
753 for (i
--; i
>= 0; i
--)
754 mgr_put_resource(&mgr
->mgr
, 1, srcimp
->idx
[i
]);
756 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
761 static int put_srcimp_rsc(struct srcimp_mgr
*mgr
, struct srcimp
*srcimp
)
766 spin_lock_irqsave(&mgr
->mgr_lock
, flags
);
767 for (i
= 0; i
< srcimp
->rsc
.msr
; i
++)
768 mgr_put_resource(&mgr
->mgr
, 1, srcimp
->idx
[i
]);
770 spin_unlock_irqrestore(&mgr
->mgr_lock
, flags
);
771 srcimp_rsc_uninit(srcimp
);
777 static int srcimp_map_op(void *data
, struct imapper
*entry
)
779 struct rsc_mgr
*mgr
= &((struct srcimp_mgr
*)data
)->mgr
;
780 struct hw
*hw
= mgr
->hw
;
782 hw
->srcimp_mgr_set_imaparc(mgr
->ctrl_blk
, entry
->slot
);
783 hw
->srcimp_mgr_set_imapuser(mgr
->ctrl_blk
, entry
->user
);
784 hw
->srcimp_mgr_set_imapnxt(mgr
->ctrl_blk
, entry
->next
);
785 hw
->srcimp_mgr_set_imapaddr(mgr
->ctrl_blk
, entry
->addr
);
786 hw
->srcimp_mgr_commit_write(mgr
->hw
, mgr
->ctrl_blk
);
791 static int srcimp_imap_add(struct srcimp_mgr
*mgr
, struct imapper
*entry
)
796 spin_lock_irqsave(&mgr
->imap_lock
, flags
);
797 if ((0 == entry
->addr
) && (mgr
->init_imap_added
)) {
798 input_mapper_delete(&mgr
->imappers
,
799 mgr
->init_imap
, srcimp_map_op
, mgr
);
800 mgr
->init_imap_added
= 0;
802 err
= input_mapper_add(&mgr
->imappers
, entry
, srcimp_map_op
, mgr
);
803 spin_unlock_irqrestore(&mgr
->imap_lock
, flags
);
808 static int srcimp_imap_delete(struct srcimp_mgr
*mgr
, struct imapper
*entry
)
813 spin_lock_irqsave(&mgr
->imap_lock
, flags
);
814 err
= input_mapper_delete(&mgr
->imappers
, entry
, srcimp_map_op
, mgr
);
815 if (list_empty(&mgr
->imappers
)) {
816 input_mapper_add(&mgr
->imappers
, mgr
->init_imap
,
818 mgr
->init_imap_added
= 1;
820 spin_unlock_irqrestore(&mgr
->imap_lock
, flags
);
825 int srcimp_mgr_create(struct hw
*hw
, struct srcimp_mgr
**rsrcimp_mgr
)
828 struct srcimp_mgr
*srcimp_mgr
;
829 struct imapper
*entry
;
832 srcimp_mgr
= kzalloc(sizeof(*srcimp_mgr
), GFP_KERNEL
);
836 err
= rsc_mgr_init(&srcimp_mgr
->mgr
, SRCIMP
, SRCIMP_RESOURCE_NUM
, hw
);
840 spin_lock_init(&srcimp_mgr
->mgr_lock
);
841 spin_lock_init(&srcimp_mgr
->imap_lock
);
842 INIT_LIST_HEAD(&srcimp_mgr
->imappers
);
843 entry
= kzalloc(sizeof(*entry
), GFP_KERNEL
);
848 entry
->slot
= entry
->addr
= entry
->next
= entry
->user
= 0;
849 list_add(&entry
->list
, &srcimp_mgr
->imappers
);
850 srcimp_mgr
->init_imap
= entry
;
851 srcimp_mgr
->init_imap_added
= 1;
853 srcimp_mgr
->get_srcimp
= get_srcimp_rsc
;
854 srcimp_mgr
->put_srcimp
= put_srcimp_rsc
;
855 srcimp_mgr
->imap_add
= srcimp_imap_add
;
856 srcimp_mgr
->imap_delete
= srcimp_imap_delete
;
857 srcimp_mgr
->card
= hw
->card
;
859 *rsrcimp_mgr
= srcimp_mgr
;
864 rsc_mgr_uninit(&srcimp_mgr
->mgr
);
870 int srcimp_mgr_destroy(struct srcimp_mgr
*srcimp_mgr
)
874 /* free src input mapper list */
875 spin_lock_irqsave(&srcimp_mgr
->imap_lock
, flags
);
876 free_input_mapper_list(&srcimp_mgr
->imappers
);
877 spin_unlock_irqrestore(&srcimp_mgr
->imap_lock
, flags
);
879 rsc_mgr_uninit(&srcimp_mgr
->mgr
);