Deleted Added
sdiff udiff text old ( 89774 ) new ( 89834 )
full compact
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Portions Copyright by Luigi Rizzo - 1997-99
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <dev/sound/pcm/sound.h>
29
30#include "feeder_if.h"
31
32SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 89834 2002-01-26 22:13:24Z cg $");
33
34#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
35#define DMA_ALIGN_THRESHOLD 4
36#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
37
38#define MIN(x, y) (((x) < (y))? (x) : (y))
39#define CANCHANGE(c) (!(c->flags & CHN_F_TRIGGERED))
40

--- 640 unchanged lines hidden (view full) ---

681 ret = EINVAL;
682 fc = feeder_getclass(NULL);
683 if (fc == NULL)
684 goto out;
685 if (chn_addfeeder(c, fc, NULL))
686 goto out;
687
688 ret = ENOMEM;
689 b = sndbuf_create(c->dev, c->name, "primary");
690 if (b == NULL)
691 goto out;
692 bs = sndbuf_create(c->dev, c->name, "secondary");
693 if (bs == NULL)
694 goto out;
695 sndbuf_setup(bs, NULL, 0);
696 c->bufhard = b;
697 c->bufsoft = bs;
698 c->flags = 0;
699 c->feederflags = 0;
700

--- 326 unchanged lines hidden (view full) ---

1027}
1028
1029static int
1030chn_buildfeeder(struct pcm_channel *c)
1031{
1032 struct feeder_class *fc;
1033 struct pcm_feederdesc desc;
1034 u_int32_t tmp[2], type, flags, hwfmt;
1035 int err;
1036
1037 CHN_LOCKASSERT(c);
1038 while (chn_removefeeder(c) == 0);
1039 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
1040
1041 c->align = sndbuf_getalign(c->bufsoft);
1042
1043 if (SLIST_EMPTY(&c->children)) {
1044 fc = feeder_getclass(NULL);
1045 KASSERT(fc != NULL, ("can't find root feeder"));
1046
1047 err = chn_addfeeder(c, fc, NULL);
1048 if (err) {
1049 DEB(printf("can't add root feeder, err %d\n", err));
1050
1051 return err;
1052 }
1053 c->feeder->desc->out = c->format;
1054 } else {
1055 desc.type = FEEDER_MIXER;
1056 desc.in = 0;
1057 desc.out = c->format;
1058 desc.flags = 0;
1059 fc = feeder_getclass(&desc);
1060 if (fc == NULL) {
1061 DEB(printf("can't find vchan feeder\n"));
1062
1063 return EOPNOTSUPP;
1064 }
1065
1066 err = chn_addfeeder(c, fc, &desc);
1067 if (err) {
1068 DEB(printf("can't add vchan feeder, err %d\n", err));
1069
1070 return err;
1071 }
1072 }
1073 flags = c->feederflags;
1074
1075 DEB(printf("not mapped, feederflags %x\n", flags));
1076
1077 for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
1078 if (flags & (1 << type)) {
1079 desc.type = type;
1080 desc.in = 0;
1081 desc.out = 0;
1082 desc.flags = 0;
1083 DEB(printf("find feeder type %d, ", type));
1084 fc = feeder_getclass(&desc);
1085 DEB(printf("got %p\n", fc));
1086 if (fc == NULL) {
1087 DEB(printf("can't find required feeder type %d\n", type));
1088
1089 return EOPNOTSUPP;
1090 }
1091
1092 if (c->feeder->desc->out != fc->desc->in) {
1093 DEB(printf("build fmtchain from %x to %x: ", c->feeder->desc->out, fc->desc->in));
1094 tmp[0] = fc->desc->in;
1095 tmp[1] = 0;
1096 if (chn_fmtchain(c, tmp) == 0) {
1097 DEB(printf("failed\n"));
1098
1099 return ENODEV;
1100 }
1101 DEB(printf("ok\n"));
1102 }
1103
1104 err = chn_addfeeder(c, fc, fc->desc);
1105 if (err) {
1106 DEB(printf("can't add feeder %p, output %x, err %d\n", fc, fc->desc->out, err));
1107
1108 return err;
1109 }
1110 DEB(printf("added feeder %p, output %x\n", fc, c->feeder->desc->out));
1111 }
1112 }
1113
1114 if (fmtvalid(c->feeder->desc->out, chn_getcaps(c)->fmtlist)) {
1115 hwfmt = c->feeder->desc->out;
1116 } else {
1117 if (c->direction == PCMDIR_REC) {
1118 tmp[0] = c->format;
1119 tmp[1] = NULL;
1120 hwfmt = chn_fmtchain(c, tmp);
1121 } else {
1122 hwfmt = chn_fmtchain(c, chn_getcaps(c)->fmtlist);
1123 }
1124 }
1125
1126 if (hwfmt == 0)
1127 return ENODEV;
1128
1129 sndbuf_setfmt(c->bufhard, hwfmt);
1130
1131 return 0;
1132}
1133
1134int
1135chn_notify(struct pcm_channel *c, u_int32_t flags)
1136{
1137 struct pcmchan_children *pce;
1138 struct pcm_channel *child;

--- 64 unchanged lines hidden ---