File: sndvolmix.c

package info (click to toggle)
powerpc-utils 1.1.3-19
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 276 kB
  • ctags: 381
  • sloc: ansic: 2,793; makefile: 166; sh: 58
file content (127 lines) | stat: -rw-r--r-- 3,340 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/mman.h>

#include "awacs_defs.h"

static inline void eieio( void )
{
    asm volatile("eieio" : :);
}

static inline unsigned ld_rev(volatile unsigned *addr)
{
    unsigned val;

    asm volatile("lwbrx %0,0,%1" : "=r" (val) : "r" (addr));
    return val;
}

static inline void st_rev(volatile unsigned *addr, unsigned val)
{
    asm volatile("stwbrx %0,0,%1" : : "r" (val), "r" (addr) : "memory");
}

unsigned *awacs;

static inline void busy_wait( void )
{
    eieio();
    while ((ld_rev(&awacs[4]) & 0x1000000) != 0)
        ;
}

int main(int ac, char **av)
{
    int fd, i;
    int l, r;
    int hflag = 0, aflag = 0, cflag = 1, mflag = 0, testflag = 0;
	int mux_mask = MASK_ADDR_MUX;
	
    while ((i = getopt(ac, av, "hacmt")) != -1)
    {
        switch (i)
        {
            case 'h':
                hflag = 1;
                break;
            case 'a':
                aflag = 1;
                mux_mask |= MASK_MUX_AUDIN;
                break;
            case 'c':
                cflag = 1;
                mux_mask |= MASK_MUX_CD;
                break;
            case 'm':
                mflag = 1;
                mux_mask |= MASK_MUX_MIC;
                break;
            case 't':
                aflag = cflag = mflag = 0;
                testflag = 1;
                break;
            default:
                (void) fprintf(stderr, "Usage: %s [-hacm] [vol | lvol rvol]\n", av[0]);
                (void) fprintf(stderr, "\t-h       mute headphones\n");
                (void) fprintf(stderr, "\t-a       activate Audio In playthrough\n");
                (void) fprintf(stderr, "\t-c       activate Cdrom playthrough\n");
                (void) fprintf(stderr, "\t-m       activate Microphone playthrough\n");
                (void) fprintf(stderr, "\tvol      Master Volume\n");
                (void) fprintf(stderr, "\tlvol     Left Master Volume\n");
                (void) fprintf(stderr, "\trvol     Right Master Volume\n");
                exit(EXIT_FAILURE);
        }
    }

    if ((fd = open("/dev/mem", O_RDWR)) < 0)
    {
        perror("/dev/mem");
        exit(EXIT_FAILURE);
    }

    awacs = (unsigned *)
        mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (int) AUD_CONT);

    if ((long)awacs == -1)
    {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

	mux_mask |= GAINRIGHT(4) | GAINLEFT(4);
	
    st_rev(&awacs[4], mux_mask);
    busy_wait();
    st_rev(&awacs[4], mux_mask | MASK_GAINLINE);
    busy_wait();
    
    st_rev(&awacs[4], (hflag? MASK_HDMUTE: 0) | MASK_ADDR1 | MASK_LOOPTHRU | MASK_PAROUT);
    busy_wait();

    if (optind < ac)
    {
        l = r = atoi(av[optind]) & 0xf;
        
        if (optind + 1 < ac)
            r = atoi(av[optind+1]) & 0xf;
        
        if (l == 0 && r == 0) {
            st_rev(&awacs[4], MASK_ADDR1 | MASK_HDMUTE | MASK_SPKMUTE | MASK_LOOPTHRU | MASK_RECALIBRATE);                /* mute the output */
            busy_wait();
        }
        else
        {
		    st_rev(&awacs[4], MASK_ADDR_VOLSPK | VOLLEFT(l) | VOLRIGHT(r));
    		busy_wait();
    		
    		st_rev(&awacs[4], MASK_ADDR_VOLHD | VOLLEFT(l) | VOLRIGHT(r));
    		busy_wait();
        }
    }

    exit(EXIT_SUCCESS);
}