| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *  linux/sound/oss/dmasound/trans_16.c | 
 | 3 |  * | 
 | 4 |  *  16 bit translation routines.  Only used by Power mac at present. | 
 | 5 |  * | 
 | 6 |  *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and | 
 | 7 |  *  history prior to 08/02/2001. | 
 | 8 |  * | 
 | 9 |  *  08/02/2001 Iain Sandoe | 
 | 10 |  *		split from dmasound_awacs.c | 
 | 11 |  *  11/29/2003 Renzo Davoli (King Enzo) | 
 | 12 |  *  	- input resampling (for soft rate < hard rate) | 
 | 13 |  *  	- software line in gain control | 
 | 14 |  */ | 
 | 15 |  | 
 | 16 | #include <linux/soundcard.h> | 
 | 17 | #include <asm/uaccess.h> | 
 | 18 | #include "dmasound.h" | 
 | 19 |  | 
 | 20 | static short dmasound_alaw2dma16[] ; | 
 | 21 | static short dmasound_ulaw2dma16[] ; | 
 | 22 |  | 
 | 23 | static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, | 
 | 24 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 25 | 			   ssize_t frameLeft); | 
 | 26 | static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, | 
 | 27 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 28 | 			  ssize_t frameLeft); | 
 | 29 | static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, | 
 | 30 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 31 | 			  ssize_t frameLeft); | 
 | 32 | static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, | 
 | 33 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 34 | 			   ssize_t frameLeft); | 
 | 35 | static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, | 
 | 36 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 37 | 			   ssize_t frameLeft); | 
 | 38 |  | 
 | 39 | static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, | 
 | 40 | 			    u_char frame[], ssize_t *frameUsed, | 
 | 41 | 			    ssize_t frameLeft); | 
 | 42 | static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, | 
 | 43 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 44 | 			   ssize_t frameLeft); | 
 | 45 | static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, | 
 | 46 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 47 | 			   ssize_t frameLeft); | 
 | 48 | static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, | 
 | 49 | 			    u_char frame[], ssize_t *frameUsed, | 
 | 50 | 			    ssize_t frameLeft); | 
 | 51 | static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, | 
 | 52 | 			    u_char frame[], ssize_t *frameUsed, | 
 | 53 | 			    ssize_t frameLeft); | 
 | 54 |  | 
 | 55 | static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, | 
 | 56 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 57 | 			   ssize_t frameLeft); | 
 | 58 | static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, | 
 | 59 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 60 | 			   ssize_t frameLeft); | 
 | 61 |  | 
 | 62 | /*** Translations ************************************************************/ | 
 | 63 |  | 
 | 64 | static int expand_data;	/* Data for expanding */ | 
 | 65 |  | 
 | 66 | static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, | 
 | 67 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 68 | 			   ssize_t frameLeft) | 
 | 69 | { | 
 | 70 | 	short *table = dmasound.soft.format == AFMT_MU_LAW | 
 | 71 | 		? dmasound_ulaw2dma16 : dmasound_alaw2dma16; | 
 | 72 | 	ssize_t count, used; | 
 | 73 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 74 | 	int val, stereo = dmasound.soft.stereo; | 
 | 75 |  | 
 | 76 | 	frameLeft >>= 2; | 
 | 77 | 	if (stereo) | 
 | 78 | 		userCount >>= 1; | 
 | 79 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 80 | 	while (count > 0) { | 
 | 81 | 		u_char data; | 
 | 82 | 		if (get_user(data, userPtr++)) | 
 | 83 | 			return -EFAULT; | 
 | 84 | 		val = table[data]; | 
 | 85 | 		*p++ = val; | 
 | 86 | 		if (stereo) { | 
 | 87 | 			if (get_user(data, userPtr++)) | 
 | 88 | 				return -EFAULT; | 
 | 89 | 			val = table[data]; | 
 | 90 | 		} | 
 | 91 | 		*p++ = val; | 
 | 92 | 		count--; | 
 | 93 | 	} | 
 | 94 | 	*frameUsed += used * 4; | 
 | 95 | 	return stereo? used * 2: used; | 
 | 96 | } | 
 | 97 |  | 
 | 98 |  | 
 | 99 | static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, | 
 | 100 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 101 | 			  ssize_t frameLeft) | 
 | 102 | { | 
 | 103 | 	ssize_t count, used; | 
 | 104 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 105 | 	int val, stereo = dmasound.soft.stereo; | 
 | 106 |  | 
 | 107 | 	frameLeft >>= 2; | 
 | 108 | 	if (stereo) | 
 | 109 | 		userCount >>= 1; | 
 | 110 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 111 | 	while (count > 0) { | 
 | 112 | 		u_char data; | 
 | 113 | 		if (get_user(data, userPtr++)) | 
 | 114 | 			return -EFAULT; | 
 | 115 | 		val = data << 8; | 
 | 116 | 		*p++ = val; | 
 | 117 | 		if (stereo) { | 
 | 118 | 			if (get_user(data, userPtr++)) | 
 | 119 | 				return -EFAULT; | 
 | 120 | 			val = data << 8; | 
 | 121 | 		} | 
 | 122 | 		*p++ = val; | 
 | 123 | 		count--; | 
 | 124 | 	} | 
 | 125 | 	*frameUsed += used * 4; | 
 | 126 | 	return stereo? used * 2: used; | 
 | 127 | } | 
 | 128 |  | 
 | 129 |  | 
 | 130 | static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, | 
 | 131 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 132 | 			  ssize_t frameLeft) | 
 | 133 | { | 
 | 134 | 	ssize_t count, used; | 
 | 135 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 136 | 	int val, stereo = dmasound.soft.stereo; | 
 | 137 |  | 
 | 138 | 	frameLeft >>= 2; | 
 | 139 | 	if (stereo) | 
 | 140 | 		userCount >>= 1; | 
 | 141 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 142 | 	while (count > 0) { | 
 | 143 | 		u_char data; | 
 | 144 | 		if (get_user(data, userPtr++)) | 
 | 145 | 			return -EFAULT; | 
 | 146 | 		val = (data ^ 0x80) << 8; | 
 | 147 | 		*p++ = val; | 
 | 148 | 		if (stereo) { | 
 | 149 | 			if (get_user(data, userPtr++)) | 
 | 150 | 				return -EFAULT; | 
 | 151 | 			val = (data ^ 0x80) << 8; | 
 | 152 | 		} | 
 | 153 | 		*p++ = val; | 
 | 154 | 		count--; | 
 | 155 | 	} | 
 | 156 | 	*frameUsed += used * 4; | 
 | 157 | 	return stereo? used * 2: used; | 
 | 158 | } | 
 | 159 |  | 
 | 160 |  | 
 | 161 | static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, | 
 | 162 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 163 | 			   ssize_t frameLeft) | 
 | 164 | { | 
 | 165 | 	ssize_t count, used; | 
 | 166 | 	int stereo = dmasound.soft.stereo; | 
 | 167 | 	short *fp = (short *) &frame[*frameUsed]; | 
 | 168 |  | 
 | 169 | 	frameLeft >>= 2; | 
 | 170 | 	userCount >>= (stereo? 2: 1); | 
 | 171 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 172 | 	if (!stereo) { | 
 | 173 | 		short __user *up = (short __user *) userPtr; | 
 | 174 | 		while (count > 0) { | 
 | 175 | 			short data; | 
 | 176 | 			if (get_user(data, up++)) | 
 | 177 | 				return -EFAULT; | 
 | 178 | 			*fp++ = data; | 
 | 179 | 			*fp++ = data; | 
 | 180 | 			count--; | 
 | 181 | 		} | 
 | 182 | 	} else { | 
 | 183 | 		if (copy_from_user(fp, userPtr, count * 4)) | 
 | 184 | 			return -EFAULT; | 
 | 185 | 	} | 
 | 186 | 	*frameUsed += used * 4; | 
 | 187 | 	return stereo? used * 4: used * 2; | 
 | 188 | } | 
 | 189 |  | 
 | 190 | static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, | 
 | 191 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 192 | 			   ssize_t frameLeft) | 
 | 193 | { | 
 | 194 | 	ssize_t count, used; | 
 | 195 | 	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | 
 | 196 | 	int stereo = dmasound.soft.stereo; | 
 | 197 | 	short *fp = (short *) &frame[*frameUsed]; | 
 | 198 | 	short __user *up = (short __user *) userPtr; | 
 | 199 |  | 
 | 200 | 	frameLeft >>= 2; | 
 | 201 | 	userCount >>= (stereo? 2: 1); | 
 | 202 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 203 | 	while (count > 0) { | 
 | 204 | 		short data; | 
 | 205 | 		if (get_user(data, up++)) | 
 | 206 | 			return -EFAULT; | 
 | 207 | 		data ^= mask; | 
 | 208 | 		*fp++ = data; | 
 | 209 | 		if (stereo) { | 
 | 210 | 			if (get_user(data, up++)) | 
 | 211 | 				return -EFAULT; | 
 | 212 | 			data ^= mask; | 
 | 213 | 		} | 
 | 214 | 		*fp++ = data; | 
 | 215 | 		count--; | 
 | 216 | 	} | 
 | 217 | 	*frameUsed += used * 4; | 
 | 218 | 	return stereo? used * 4: used * 2; | 
 | 219 | } | 
 | 220 |  | 
 | 221 |  | 
 | 222 | static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, | 
 | 223 | 			    u_char frame[], ssize_t *frameUsed, | 
 | 224 | 			    ssize_t frameLeft) | 
 | 225 | { | 
 | 226 | 	unsigned short *table = (unsigned short *) | 
 | 227 | 		(dmasound.soft.format == AFMT_MU_LAW | 
 | 228 | 		 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16); | 
 | 229 | 	unsigned int data = expand_data; | 
 | 230 | 	unsigned int *p = (unsigned int *) &frame[*frameUsed]; | 
 | 231 | 	int bal = expand_bal; | 
 | 232 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 233 | 	int utotal, ftotal; | 
 | 234 | 	int stereo = dmasound.soft.stereo; | 
 | 235 |  | 
 | 236 | 	frameLeft >>= 2; | 
 | 237 | 	if (stereo) | 
 | 238 | 		userCount >>= 1; | 
 | 239 | 	ftotal = frameLeft; | 
 | 240 | 	utotal = userCount; | 
 | 241 | 	while (frameLeft) { | 
 | 242 | 		u_char c; | 
 | 243 | 		if (bal < 0) { | 
 | 244 | 			if (userCount == 0) | 
 | 245 | 				break; | 
 | 246 | 			if (get_user(c, userPtr++)) | 
 | 247 | 				return -EFAULT; | 
 | 248 | 			data = table[c]; | 
 | 249 | 			if (stereo) { | 
 | 250 | 				if (get_user(c, userPtr++)) | 
 | 251 | 					return -EFAULT; | 
 | 252 | 				data = (data << 16) + table[c]; | 
 | 253 | 			} else | 
 | 254 | 				data = (data << 16) + data; | 
 | 255 | 			userCount--; | 
 | 256 | 			bal += hSpeed; | 
 | 257 | 		} | 
 | 258 | 		*p++ = data; | 
 | 259 | 		frameLeft--; | 
 | 260 | 		bal -= sSpeed; | 
 | 261 | 	} | 
 | 262 | 	expand_bal = bal; | 
 | 263 | 	expand_data = data; | 
 | 264 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 265 | 	utotal -= userCount; | 
 | 266 | 	return stereo? utotal * 2: utotal; | 
 | 267 | } | 
 | 268 |  | 
 | 269 | static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, | 
 | 270 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 271 | 			   ssize_t frameLeft) | 
 | 272 | { | 
 | 273 | 	unsigned int *p = (unsigned int *) &frame[*frameUsed]; | 
 | 274 | 	unsigned int data = expand_data; | 
 | 275 | 	int bal = expand_bal; | 
 | 276 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 277 | 	int stereo = dmasound.soft.stereo; | 
 | 278 | 	int utotal, ftotal; | 
 | 279 |  | 
 | 280 | 	frameLeft >>= 2; | 
 | 281 | 	if (stereo) | 
 | 282 | 		userCount >>= 1; | 
 | 283 | 	ftotal = frameLeft; | 
 | 284 | 	utotal = userCount; | 
 | 285 | 	while (frameLeft) { | 
 | 286 | 		u_char c; | 
 | 287 | 		if (bal < 0) { | 
 | 288 | 			if (userCount == 0) | 
 | 289 | 				break; | 
 | 290 | 			if (get_user(c, userPtr++)) | 
 | 291 | 				return -EFAULT; | 
 | 292 | 			data = c << 8; | 
 | 293 | 			if (stereo) { | 
 | 294 | 				if (get_user(c, userPtr++)) | 
 | 295 | 					return -EFAULT; | 
 | 296 | 				data = (data << 16) + (c << 8); | 
 | 297 | 			} else | 
 | 298 | 				data = (data << 16) + data; | 
 | 299 | 			userCount--; | 
 | 300 | 			bal += hSpeed; | 
 | 301 | 		} | 
 | 302 | 		*p++ = data; | 
 | 303 | 		frameLeft--; | 
 | 304 | 		bal -= sSpeed; | 
 | 305 | 	} | 
 | 306 | 	expand_bal = bal; | 
 | 307 | 	expand_data = data; | 
 | 308 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 309 | 	utotal -= userCount; | 
 | 310 | 	return stereo? utotal * 2: utotal; | 
 | 311 | } | 
 | 312 |  | 
 | 313 |  | 
 | 314 | static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, | 
 | 315 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 316 | 			   ssize_t frameLeft) | 
 | 317 | { | 
 | 318 | 	unsigned int *p = (unsigned int *) &frame[*frameUsed]; | 
 | 319 | 	unsigned int data = expand_data; | 
 | 320 | 	int bal = expand_bal; | 
 | 321 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 322 | 	int stereo = dmasound.soft.stereo; | 
 | 323 | 	int utotal, ftotal; | 
 | 324 |  | 
 | 325 | 	frameLeft >>= 2; | 
 | 326 | 	if (stereo) | 
 | 327 | 		userCount >>= 1; | 
 | 328 | 	ftotal = frameLeft; | 
 | 329 | 	utotal = userCount; | 
 | 330 | 	while (frameLeft) { | 
 | 331 | 		u_char c; | 
 | 332 | 		if (bal < 0) { | 
 | 333 | 			if (userCount == 0) | 
 | 334 | 				break; | 
 | 335 | 			if (get_user(c, userPtr++)) | 
 | 336 | 				return -EFAULT; | 
 | 337 | 			data = (c ^ 0x80) << 8; | 
 | 338 | 			if (stereo) { | 
 | 339 | 				if (get_user(c, userPtr++)) | 
 | 340 | 					return -EFAULT; | 
 | 341 | 				data = (data << 16) + ((c ^ 0x80) << 8); | 
 | 342 | 			} else | 
 | 343 | 				data = (data << 16) + data; | 
 | 344 | 			userCount--; | 
 | 345 | 			bal += hSpeed; | 
 | 346 | 		} | 
 | 347 | 		*p++ = data; | 
 | 348 | 		frameLeft--; | 
 | 349 | 		bal -= sSpeed; | 
 | 350 | 	} | 
 | 351 | 	expand_bal = bal; | 
 | 352 | 	expand_data = data; | 
 | 353 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 354 | 	utotal -= userCount; | 
 | 355 | 	return stereo? utotal * 2: utotal; | 
 | 356 | } | 
 | 357 |  | 
 | 358 |  | 
 | 359 | static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, | 
 | 360 | 			    u_char frame[], ssize_t *frameUsed, | 
 | 361 | 			    ssize_t frameLeft) | 
 | 362 | { | 
 | 363 | 	unsigned int *p = (unsigned int *) &frame[*frameUsed]; | 
 | 364 | 	unsigned int data = expand_data; | 
 | 365 | 	unsigned short __user *up = (unsigned short __user *) userPtr; | 
 | 366 | 	int bal = expand_bal; | 
 | 367 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 368 | 	int stereo = dmasound.soft.stereo; | 
 | 369 | 	int utotal, ftotal; | 
 | 370 |  | 
 | 371 | 	frameLeft >>= 2; | 
 | 372 | 	userCount >>= (stereo? 2: 1); | 
 | 373 | 	ftotal = frameLeft; | 
 | 374 | 	utotal = userCount; | 
 | 375 | 	while (frameLeft) { | 
 | 376 | 		unsigned short c; | 
 | 377 | 		if (bal < 0) { | 
 | 378 | 			if (userCount == 0) | 
 | 379 | 				break; | 
 | 380 | 			if (get_user(data, up++)) | 
 | 381 | 				return -EFAULT; | 
 | 382 | 			if (stereo) { | 
 | 383 | 				if (get_user(c, up++)) | 
 | 384 | 					return -EFAULT; | 
 | 385 | 				data = (data << 16) + c; | 
 | 386 | 			} else | 
 | 387 | 				data = (data << 16) + data; | 
 | 388 | 			userCount--; | 
 | 389 | 			bal += hSpeed; | 
 | 390 | 		} | 
 | 391 | 		*p++ = data; | 
 | 392 | 		frameLeft--; | 
 | 393 | 		bal -= sSpeed; | 
 | 394 | 	} | 
 | 395 | 	expand_bal = bal; | 
 | 396 | 	expand_data = data; | 
 | 397 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 398 | 	utotal -= userCount; | 
 | 399 | 	return stereo? utotal * 4: utotal * 2; | 
 | 400 | } | 
 | 401 |  | 
 | 402 |  | 
 | 403 | static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, | 
 | 404 | 			    u_char frame[], ssize_t *frameUsed, | 
 | 405 | 			    ssize_t frameLeft) | 
 | 406 | { | 
 | 407 | 	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | 
 | 408 | 	unsigned int *p = (unsigned int *) &frame[*frameUsed]; | 
 | 409 | 	unsigned int data = expand_data; | 
 | 410 | 	unsigned short __user *up = (unsigned short __user *) userPtr; | 
 | 411 | 	int bal = expand_bal; | 
 | 412 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 413 | 	int stereo = dmasound.soft.stereo; | 
 | 414 | 	int utotal, ftotal; | 
 | 415 |  | 
 | 416 | 	frameLeft >>= 2; | 
 | 417 | 	userCount >>= (stereo? 2: 1); | 
 | 418 | 	ftotal = frameLeft; | 
 | 419 | 	utotal = userCount; | 
 | 420 | 	while (frameLeft) { | 
 | 421 | 		unsigned short c; | 
 | 422 | 		if (bal < 0) { | 
 | 423 | 			if (userCount == 0) | 
 | 424 | 				break; | 
 | 425 | 			if (get_user(data, up++)) | 
 | 426 | 				return -EFAULT; | 
 | 427 | 			data ^= mask; | 
 | 428 | 			if (stereo) { | 
 | 429 | 				if (get_user(c, up++)) | 
 | 430 | 					return -EFAULT; | 
 | 431 | 				data = (data << 16) + (c ^ mask); | 
 | 432 | 			} else | 
 | 433 | 				data = (data << 16) + data; | 
 | 434 | 			userCount--; | 
 | 435 | 			bal += hSpeed; | 
 | 436 | 		} | 
 | 437 | 		*p++ = data; | 
 | 438 | 		frameLeft--; | 
 | 439 | 		bal -= sSpeed; | 
 | 440 | 	} | 
 | 441 | 	expand_bal = bal; | 
 | 442 | 	expand_data = data; | 
 | 443 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 444 | 	utotal -= userCount; | 
 | 445 | 	return stereo? utotal * 4: utotal * 2; | 
 | 446 | } | 
 | 447 |  | 
 | 448 | /* data in routines... */ | 
 | 449 |  | 
 | 450 | static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount, | 
 | 451 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 452 | 			  ssize_t frameLeft) | 
 | 453 | { | 
 | 454 | 	ssize_t count, used; | 
 | 455 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 456 | 	int val, stereo = dmasound.soft.stereo; | 
 | 457 |  | 
 | 458 | 	frameLeft >>= 2; | 
 | 459 | 	if (stereo) | 
 | 460 | 		userCount >>= 1; | 
 | 461 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 462 | 	while (count > 0) { | 
 | 463 | 		u_char data; | 
 | 464 |  | 
 | 465 | 		val = *p++; | 
 | 466 | 		val = (val * software_input_volume) >> 7; | 
 | 467 | 		data = val >> 8; | 
 | 468 | 		if (put_user(data, (u_char __user *)userPtr++)) | 
 | 469 | 			return -EFAULT; | 
 | 470 | 		if (stereo) { | 
 | 471 | 			val = *p; | 
 | 472 | 			val = (val * software_input_volume) >> 7; | 
 | 473 | 			data = val >> 8; | 
 | 474 | 			if (put_user(data, (u_char __user *)userPtr++)) | 
 | 475 | 				return -EFAULT; | 
 | 476 | 		} | 
 | 477 | 		p++; | 
 | 478 | 		count--; | 
 | 479 | 	} | 
 | 480 | 	*frameUsed += used * 4; | 
 | 481 | 	return stereo? used * 2: used; | 
 | 482 | } | 
 | 483 |  | 
 | 484 |  | 
 | 485 | static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount, | 
 | 486 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 487 | 			  ssize_t frameLeft) | 
 | 488 | { | 
 | 489 | 	ssize_t count, used; | 
 | 490 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 491 | 	int val, stereo = dmasound.soft.stereo; | 
 | 492 |  | 
 | 493 | 	frameLeft >>= 2; | 
 | 494 | 	if (stereo) | 
 | 495 | 		userCount >>= 1; | 
 | 496 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 497 | 	while (count > 0) { | 
 | 498 | 		u_char data; | 
 | 499 |  | 
 | 500 | 		val = *p++; | 
 | 501 | 		val = (val * software_input_volume) >> 7; | 
 | 502 | 		data = (val >> 8) ^ 0x80; | 
 | 503 | 		if (put_user(data, (u_char __user *)userPtr++)) | 
 | 504 | 			return -EFAULT; | 
 | 505 | 		if (stereo) { | 
 | 506 | 			val = *p; | 
 | 507 | 			val = (val * software_input_volume) >> 7; | 
 | 508 | 			data = (val >> 8) ^ 0x80; | 
 | 509 | 			if (put_user(data, (u_char __user *)userPtr++)) | 
 | 510 | 				return -EFAULT; | 
 | 511 | 		} | 
 | 512 | 		p++; | 
 | 513 | 		count--; | 
 | 514 | 	} | 
 | 515 | 	*frameUsed += used * 4; | 
 | 516 | 	return stereo? used * 2: used; | 
 | 517 | } | 
 | 518 |  | 
 | 519 | static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, | 
 | 520 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 521 | 			   ssize_t frameLeft) | 
 | 522 | { | 
 | 523 | 	ssize_t count, used; | 
 | 524 | 	int stereo = dmasound.soft.stereo; | 
 | 525 | 	short *fp = (short *) &frame[*frameUsed]; | 
 | 526 | 	short __user *up = (short __user *) userPtr; | 
 | 527 |  | 
 | 528 | 	frameLeft >>= 2; | 
 | 529 | 	userCount >>= (stereo? 2: 1); | 
 | 530 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 531 | 	while (count > 0) { | 
 | 532 | 		short data; | 
 | 533 |  | 
 | 534 | 		data = *fp++; | 
 | 535 | 		data = (data * software_input_volume) >> 7; | 
 | 536 | 		if (put_user(data, up++)) | 
 | 537 | 			return -EFAULT; | 
 | 538 | 		if (stereo) { | 
 | 539 | 			data = *fp; | 
 | 540 | 			data = (data * software_input_volume) >> 7; | 
 | 541 | 			if (put_user(data, up++)) | 
 | 542 | 				return -EFAULT; | 
 | 543 | 		} | 
 | 544 | 		fp++; | 
 | 545 | 		count--; | 
 | 546 |  	} | 
 | 547 | 	*frameUsed += used * 4; | 
 | 548 | 	return stereo? used * 4: used * 2; | 
 | 549 | } | 
 | 550 |  | 
 | 551 | static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, | 
 | 552 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 553 | 			   ssize_t frameLeft) | 
 | 554 | { | 
 | 555 | 	ssize_t count, used; | 
 | 556 | 	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | 
 | 557 | 	int stereo = dmasound.soft.stereo; | 
 | 558 | 	short *fp = (short *) &frame[*frameUsed]; | 
 | 559 | 	short __user *up = (short __user *) userPtr; | 
 | 560 |  | 
 | 561 | 	frameLeft >>= 2; | 
 | 562 | 	userCount >>= (stereo? 2: 1); | 
 | 563 | 	used = count = min_t(unsigned long, userCount, frameLeft); | 
 | 564 | 	while (count > 0) { | 
 | 565 | 		int data; | 
 | 566 |  | 
 | 567 | 		data = *fp++; | 
 | 568 | 		data = (data * software_input_volume) >> 7; | 
 | 569 | 		data ^= mask; | 
 | 570 | 		if (put_user(data, up++)) | 
 | 571 | 			return -EFAULT; | 
 | 572 | 		if (stereo) { | 
 | 573 | 			data = *fp; | 
 | 574 | 			data = (data * software_input_volume) >> 7; | 
 | 575 | 			data ^= mask; | 
 | 576 | 			if (put_user(data, up++)) | 
 | 577 | 				return -EFAULT; | 
 | 578 | 		} | 
 | 579 | 		fp++; | 
 | 580 | 		count--; | 
 | 581 | 	} | 
 | 582 | 	*frameUsed += used * 4; | 
 | 583 | 	return stereo? used * 4: used * 2; | 
 | 584 | } | 
 | 585 |  | 
 | 586 | /* data in routines (reducing speed)... */ | 
 | 587 |  | 
 | 588 | static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount, | 
 | 589 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 590 | 			  ssize_t frameLeft) | 
 | 591 | { | 
 | 592 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 593 | 	int bal = expand_read_bal; | 
 | 594 | 	int vall,valr, stereo = dmasound.soft.stereo; | 
 | 595 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 596 | 	int utotal, ftotal; | 
 | 597 |  | 
 | 598 | 	frameLeft >>= 2; | 
 | 599 | 	if (stereo) | 
 | 600 | 		userCount >>= 1; | 
 | 601 | 	ftotal = frameLeft; | 
 | 602 | 	utotal = userCount; | 
 | 603 | 	while (frameLeft) { | 
 | 604 | 		u_char data; | 
 | 605 |  | 
 | 606 | 		if (bal<0 && userCount == 0) | 
 | 607 | 			break; | 
 | 608 | 		vall = *p++; | 
 | 609 | 		vall = (vall * software_input_volume) >> 7; | 
 | 610 | 		if (stereo) { | 
 | 611 | 			valr = *p; | 
 | 612 | 			valr = (valr * software_input_volume) >> 7; | 
 | 613 | 		} | 
 | 614 | 		p++; | 
 | 615 | 		if (bal < 0) { | 
 | 616 | 			data = vall >> 8; | 
 | 617 | 			if (put_user(data, (u_char __user *)userPtr++)) | 
 | 618 | 				return -EFAULT; | 
 | 619 | 			if (stereo) { | 
 | 620 | 				data = valr >> 8; | 
 | 621 | 				if (put_user(data, (u_char __user *)userPtr++)) | 
 | 622 | 					return -EFAULT; | 
 | 623 | 			} | 
 | 624 | 			userCount--; | 
 | 625 | 			bal += hSpeed; | 
 | 626 | 		} | 
 | 627 | 		frameLeft--; | 
 | 628 | 		bal -= sSpeed; | 
 | 629 | 	} | 
 | 630 | 	expand_read_bal=bal; | 
 | 631 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 632 | 	utotal -= userCount; | 
 | 633 | 	return stereo? utotal * 2: utotal; | 
 | 634 | } | 
 | 635 |  | 
 | 636 |  | 
 | 637 | static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount, | 
 | 638 | 			  u_char frame[], ssize_t *frameUsed, | 
 | 639 | 			  ssize_t frameLeft) | 
 | 640 | { | 
 | 641 | 	short *p = (short *) &frame[*frameUsed]; | 
 | 642 | 	int bal = expand_read_bal; | 
 | 643 | 	int vall,valr, stereo = dmasound.soft.stereo; | 
 | 644 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 645 | 	int utotal, ftotal; | 
 | 646 |  | 
 | 647 | 	frameLeft >>= 2; | 
 | 648 | 	if (stereo) | 
 | 649 | 		userCount >>= 1; | 
 | 650 | 	ftotal = frameLeft; | 
 | 651 | 	utotal = userCount; | 
 | 652 | 	while (frameLeft) { | 
 | 653 | 		u_char data; | 
 | 654 |  | 
 | 655 | 		if (bal<0 && userCount == 0) | 
 | 656 | 			break; | 
 | 657 |  | 
 | 658 | 		vall = *p++; | 
 | 659 | 		vall = (vall * software_input_volume) >> 7; | 
 | 660 | 		if (stereo) { | 
 | 661 | 			valr = *p; | 
 | 662 | 			valr = (valr * software_input_volume) >> 7; | 
 | 663 | 		} | 
 | 664 | 		p++; | 
 | 665 | 		if (bal < 0) { | 
 | 666 | 			data = (vall >> 8) ^ 0x80; | 
 | 667 | 			if (put_user(data, (u_char __user *)userPtr++)) | 
 | 668 | 				return -EFAULT; | 
 | 669 | 			if (stereo) { | 
 | 670 | 				data = (valr >> 8) ^ 0x80; | 
 | 671 | 				if (put_user(data, (u_char __user *)userPtr++)) | 
 | 672 | 					return -EFAULT; | 
 | 673 | 			} | 
 | 674 | 			userCount--; | 
 | 675 | 			bal += hSpeed; | 
 | 676 | 		} | 
 | 677 | 		frameLeft--; | 
 | 678 | 		bal -= sSpeed; | 
 | 679 | 	} | 
 | 680 | 	expand_read_bal=bal; | 
 | 681 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 682 | 	utotal -= userCount; | 
 | 683 | 	return stereo? utotal * 2: utotal; | 
 | 684 | } | 
 | 685 |  | 
 | 686 | static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount, | 
 | 687 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 688 | 			   ssize_t frameLeft) | 
 | 689 | { | 
 | 690 | 	int bal = expand_read_bal; | 
 | 691 | 	short *fp = (short *) &frame[*frameUsed]; | 
 | 692 | 	short __user *up = (short __user *) userPtr; | 
 | 693 | 	int stereo = dmasound.soft.stereo; | 
 | 694 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 695 | 	int utotal, ftotal; | 
 | 696 |  | 
 | 697 | 	frameLeft >>= 2; | 
 | 698 | 	userCount >>= (stereo? 2: 1); | 
 | 699 | 	ftotal = frameLeft; | 
 | 700 | 	utotal = userCount; | 
 | 701 | 	while (frameLeft) { | 
 | 702 | 		int datal,datar; | 
 | 703 |  | 
 | 704 | 		if (bal<0 && userCount == 0) | 
 | 705 | 			break; | 
 | 706 |  | 
 | 707 | 		datal = *fp++; | 
 | 708 | 		datal = (datal * software_input_volume) >> 7; | 
 | 709 | 		if (stereo) { | 
 | 710 | 			datar = *fp; | 
 | 711 | 			datar = (datar * software_input_volume) >> 7; | 
 | 712 | 		} | 
 | 713 | 		fp++; | 
 | 714 | 		if (bal < 0) { | 
 | 715 | 			if (put_user(datal, up++)) | 
 | 716 | 				return -EFAULT; | 
 | 717 | 			if (stereo) { | 
 | 718 | 				if (put_user(datar, up++)) | 
 | 719 | 					return -EFAULT; | 
 | 720 | 			} | 
 | 721 | 			userCount--; | 
 | 722 | 			bal += hSpeed; | 
 | 723 | 		} | 
 | 724 | 		frameLeft--; | 
 | 725 | 		bal -= sSpeed; | 
 | 726 | 	} | 
 | 727 | 	expand_read_bal=bal; | 
 | 728 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 729 | 	utotal -= userCount; | 
 | 730 | 	return stereo? utotal * 4: utotal * 2; | 
 | 731 | } | 
 | 732 |  | 
 | 733 | static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount, | 
 | 734 | 			   u_char frame[], ssize_t *frameUsed, | 
 | 735 | 			   ssize_t frameLeft) | 
 | 736 | { | 
 | 737 | 	int bal = expand_read_bal; | 
 | 738 | 	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | 
 | 739 | 	short *fp = (short *) &frame[*frameUsed]; | 
 | 740 | 	short __user *up = (short __user *) userPtr; | 
 | 741 | 	int stereo = dmasound.soft.stereo; | 
 | 742 | 	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | 
 | 743 | 	int utotal, ftotal; | 
 | 744 |  | 
 | 745 | 	frameLeft >>= 2; | 
 | 746 | 	userCount >>= (stereo? 2: 1); | 
 | 747 | 	ftotal = frameLeft; | 
 | 748 | 	utotal = userCount; | 
 | 749 | 	while (frameLeft) { | 
 | 750 | 		int datal,datar; | 
 | 751 |  | 
 | 752 | 		if (bal<0 && userCount == 0) | 
 | 753 | 			break; | 
 | 754 |  | 
 | 755 | 		datal = *fp++; | 
 | 756 | 		datal = (datal * software_input_volume) >> 7; | 
 | 757 | 		datal ^= mask; | 
 | 758 | 		if (stereo) { | 
 | 759 | 			datar = *fp; | 
 | 760 | 			datar = (datar * software_input_volume) >> 7; | 
 | 761 | 			datar ^= mask; | 
 | 762 | 		} | 
 | 763 | 		fp++; | 
 | 764 | 		if (bal < 0) { | 
 | 765 | 			if (put_user(datal, up++)) | 
 | 766 | 				return -EFAULT; | 
 | 767 | 			if (stereo) { | 
 | 768 | 				if (put_user(datar, up++)) | 
 | 769 | 					return -EFAULT; | 
 | 770 | 			} | 
 | 771 | 			userCount--; | 
 | 772 | 			bal += hSpeed; | 
 | 773 | 		} | 
 | 774 | 		frameLeft--; | 
 | 775 | 		bal -= sSpeed; | 
 | 776 | 	} | 
 | 777 | 	expand_read_bal=bal; | 
 | 778 | 	*frameUsed += (ftotal - frameLeft) * 4; | 
 | 779 | 	utotal -= userCount; | 
 | 780 | 	return stereo? utotal * 4: utotal * 2; | 
 | 781 | } | 
 | 782 |  | 
 | 783 |  | 
 | 784 | TRANS transAwacsNormal = { | 
 | 785 | 	.ct_ulaw=	pmac_ct_law, | 
 | 786 | 	.ct_alaw=	pmac_ct_law, | 
 | 787 | 	.ct_s8=		pmac_ct_s8, | 
 | 788 | 	.ct_u8=		pmac_ct_u8, | 
 | 789 | 	.ct_s16be=	pmac_ct_s16, | 
 | 790 | 	.ct_u16be=	pmac_ct_u16, | 
 | 791 | 	.ct_s16le=	pmac_ct_s16, | 
 | 792 | 	.ct_u16le=	pmac_ct_u16, | 
 | 793 | }; | 
 | 794 |  | 
 | 795 | TRANS transAwacsExpand = { | 
 | 796 | 	.ct_ulaw=	pmac_ctx_law, | 
 | 797 | 	.ct_alaw=	pmac_ctx_law, | 
 | 798 | 	.ct_s8=		pmac_ctx_s8, | 
 | 799 | 	.ct_u8=		pmac_ctx_u8, | 
 | 800 | 	.ct_s16be=	pmac_ctx_s16, | 
 | 801 | 	.ct_u16be=	pmac_ctx_u16, | 
 | 802 | 	.ct_s16le=	pmac_ctx_s16, | 
 | 803 | 	.ct_u16le=	pmac_ctx_u16, | 
 | 804 | }; | 
 | 805 |  | 
 | 806 | TRANS transAwacsNormalRead = { | 
 | 807 | 	.ct_s8=		pmac_ct_s8_read, | 
 | 808 | 	.ct_u8=		pmac_ct_u8_read, | 
 | 809 | 	.ct_s16be=	pmac_ct_s16_read, | 
 | 810 | 	.ct_u16be=	pmac_ct_u16_read, | 
 | 811 | 	.ct_s16le=	pmac_ct_s16_read, | 
 | 812 | 	.ct_u16le=	pmac_ct_u16_read, | 
 | 813 | }; | 
 | 814 |  | 
 | 815 | TRANS transAwacsExpandRead = { | 
 | 816 | 	.ct_s8=		pmac_ctx_s8_read, | 
 | 817 | 	.ct_u8=		pmac_ctx_u8_read, | 
 | 818 | 	.ct_s16be=	pmac_ctx_s16_read, | 
 | 819 | 	.ct_u16be=	pmac_ctx_u16_read, | 
 | 820 | 	.ct_s16le=	pmac_ctx_s16_read, | 
 | 821 | 	.ct_u16le=	pmac_ctx_u16_read, | 
 | 822 | }; | 
 | 823 |  | 
 | 824 | /* translation tables */ | 
 | 825 | /* 16 bit mu-law */ | 
 | 826 |  | 
 | 827 | static short dmasound_ulaw2dma16[] = { | 
 | 828 | 	-32124,	-31100,	-30076,	-29052,	-28028,	-27004,	-25980,	-24956, | 
 | 829 | 	-23932,	-22908,	-21884,	-20860,	-19836,	-18812,	-17788,	-16764, | 
 | 830 | 	-15996,	-15484,	-14972,	-14460,	-13948,	-13436,	-12924,	-12412, | 
 | 831 | 	-11900,	-11388,	-10876,	-10364,	-9852,	-9340,	-8828,	-8316, | 
 | 832 | 	-7932,	-7676,	-7420,	-7164,	-6908,	-6652,	-6396,	-6140, | 
 | 833 | 	-5884,	-5628,	-5372,	-5116,	-4860,	-4604,	-4348,	-4092, | 
 | 834 | 	-3900,	-3772,	-3644,	-3516,	-3388,	-3260,	-3132,	-3004, | 
 | 835 | 	-2876,	-2748,	-2620,	-2492,	-2364,	-2236,	-2108,	-1980, | 
 | 836 | 	-1884,	-1820,	-1756,	-1692,	-1628,	-1564,	-1500,	-1436, | 
 | 837 | 	-1372,	-1308,	-1244,	-1180,	-1116,	-1052,	-988,	-924, | 
 | 838 | 	-876,	-844,	-812,	-780,	-748,	-716,	-684,	-652, | 
 | 839 | 	-620,	-588,	-556,	-524,	-492,	-460,	-428,	-396, | 
 | 840 | 	-372,	-356,	-340,	-324,	-308,	-292,	-276,	-260, | 
 | 841 | 	-244,	-228,	-212,	-196,	-180,	-164,	-148,	-132, | 
 | 842 | 	-120,	-112,	-104,	-96,	-88,	-80,	-72,	-64, | 
 | 843 | 	-56,	-48,	-40,	-32,	-24,	-16,	-8,	0, | 
 | 844 | 	32124,	31100,	30076,	29052,	28028,	27004,	25980,	24956, | 
 | 845 | 	23932,	22908,	21884,	20860,	19836,	18812,	17788,	16764, | 
 | 846 | 	15996,	15484,	14972,	14460,	13948,	13436,	12924,	12412, | 
 | 847 | 	11900,	11388,	10876,	10364,	9852,	9340,	8828,	8316, | 
 | 848 | 	7932,	7676,	7420,	7164,	6908,	6652,	6396,	6140, | 
 | 849 | 	5884,	5628,	5372,	5116,	4860,	4604,	4348,	4092, | 
 | 850 | 	3900,	3772,	3644,	3516,	3388,	3260,	3132,	3004, | 
 | 851 | 	2876,	2748,	2620,	2492,	2364,	2236,	2108,	1980, | 
 | 852 | 	1884,	1820,	1756,	1692,	1628,	1564,	1500,	1436, | 
 | 853 | 	1372,	1308,	1244,	1180,	1116,	1052,	988,	924, | 
 | 854 | 	876,	844,	812,	780,	748,	716,	684,	652, | 
 | 855 | 	620,	588,	556,	524,	492,	460,	428,	396, | 
 | 856 | 	372,	356,	340,	324,	308,	292,	276,	260, | 
 | 857 | 	244,	228,	212,	196,	180,	164,	148,	132, | 
 | 858 | 	120,	112,	104,	96,	88,	80,	72,	64, | 
 | 859 | 	56,	48,	40,	32,	24,	16,	8,	0, | 
 | 860 | }; | 
 | 861 |  | 
 | 862 | /* 16 bit A-law */ | 
 | 863 |  | 
 | 864 | static short dmasound_alaw2dma16[] = { | 
 | 865 | 	-5504,	-5248,	-6016,	-5760,	-4480,	-4224,	-4992,	-4736, | 
 | 866 | 	-7552,	-7296,	-8064,	-7808,	-6528,	-6272,	-7040,	-6784, | 
 | 867 | 	-2752,	-2624,	-3008,	-2880,	-2240,	-2112,	-2496,	-2368, | 
 | 868 | 	-3776,	-3648,	-4032,	-3904,	-3264,	-3136,	-3520,	-3392, | 
 | 869 | 	-22016,	-20992,	-24064,	-23040,	-17920,	-16896,	-19968,	-18944, | 
 | 870 | 	-30208,	-29184,	-32256,	-31232,	-26112,	-25088,	-28160,	-27136, | 
 | 871 | 	-11008,	-10496,	-12032,	-11520,	-8960,	-8448,	-9984,	-9472, | 
 | 872 | 	-15104,	-14592,	-16128,	-15616,	-13056,	-12544,	-14080,	-13568, | 
 | 873 | 	-344,	-328,	-376,	-360,	-280,	-264,	-312,	-296, | 
 | 874 | 	-472,	-456,	-504,	-488,	-408,	-392,	-440,	-424, | 
 | 875 | 	-88,	-72,	-120,	-104,	-24,	-8,	-56,	-40, | 
 | 876 | 	-216,	-200,	-248,	-232,	-152,	-136,	-184,	-168, | 
 | 877 | 	-1376,	-1312,	-1504,	-1440,	-1120,	-1056,	-1248,	-1184, | 
 | 878 | 	-1888,	-1824,	-2016,	-1952,	-1632,	-1568,	-1760,	-1696, | 
 | 879 | 	-688,	-656,	-752,	-720,	-560,	-528,	-624,	-592, | 
 | 880 | 	-944,	-912,	-1008,	-976,	-816,	-784,	-880,	-848, | 
 | 881 | 	5504,	5248,	6016,	5760,	4480,	4224,	4992,	4736, | 
 | 882 | 	7552,	7296,	8064,	7808,	6528,	6272,	7040,	6784, | 
 | 883 | 	2752,	2624,	3008,	2880,	2240,	2112,	2496,	2368, | 
 | 884 | 	3776,	3648,	4032,	3904,	3264,	3136,	3520,	3392, | 
 | 885 | 	22016,	20992,	24064,	23040,	17920,	16896,	19968,	18944, | 
 | 886 | 	30208,	29184,	32256,	31232,	26112,	25088,	28160,	27136, | 
 | 887 | 	11008,	10496,	12032,	11520,	8960,	8448,	9984,	9472, | 
 | 888 | 	15104,	14592,	16128,	15616,	13056,	12544,	14080,	13568, | 
 | 889 | 	344,	328,	376,	360,	280,	264,	312,	296, | 
 | 890 | 	472,	456,	504,	488,	408,	392,	440,	424, | 
 | 891 | 	88,	72,	120,	104,	24,	8,	56,	40, | 
 | 892 | 	216,	200,	248,	232,	152,	136,	184,	168, | 
 | 893 | 	1376,	1312,	1504,	1440,	1120,	1056,	1248,	1184, | 
 | 894 | 	1888,	1824,	2016,	1952,	1632,	1568,	1760,	1696, | 
 | 895 | 	688,	656,	752,	720,	560,	528,	624,	592, | 
 | 896 | 	944,	912,	1008,	976,	816,	784,	880,	848, | 
 | 897 | }; |