LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
sound.c
Go to the documentation of this file.
1#include <pci/io.h>
2#include <string.h>
5#include <ppc/cache.h>
6
7extern int xenos_is_hdmi;
8
9static int snd_base = 0xea001600, wptr, buffer_len;
10
11// those 2 must be in the first 32MB of physical memory it seems...
12static uint8_t buffer[65536] __attribute__ ((section(".bss.beginning.lower"),aligned (256)));
13static uint32_t descr[0x20*2] __attribute__ ((section(".bss.beginning.lower"),aligned (256)));
14
16{
17 // reset DAC (init from scratch)
18 xenon_gpio_control(5,0x1000,0x1000);
19 xenon_gpio_control(0,0x1000,0x1000);
20 xenon_gpio_control(4,0x1000,0x1000);
21
22 if(xenos_is_hdmi){
23 // HDMI audio enable
24 xenon_smc_i2c_write(0x0214, 0x11);
25 xenon_smc_i2c_write(0x0202, 0x03);
26 xenon_smc_i2c_write(0x0203, 0x00);
27 xenon_smc_i2c_write(0x0204, 0x18);
28 xenon_smc_i2c_write(0x0205, 0x00);
29 xenon_smc_i2c_write(0x021d, 0x40);
30 xenon_smc_i2c_write(0x0221, 0x02);
31 xenon_smc_i2c_write(0x0222, 0x2b);
32
33 xenon_smc_i2c_write(0x022f,0x01);
34 xenon_smc_i2c_write(0x023e,0x3f);
35
36 xenon_smc_i2c_write(0x02df,0x10);// Av mute ?
37 }
38
39 static unsigned char smc_snd[32] = {0x8d, 1, 1};
41
42 unsigned int descr_base = ((unsigned int)descr) & 0x1fffffff;
43
44 buffer_len = sizeof(buffer);
45 memset(buffer, 0, buffer_len);
46 memdcbst(buffer, buffer_len);
47
48 unsigned int buffer_base = ((unsigned int)buffer) & 0x1fffffff;
49
50 int i;
51 for (i = 0; i < 0x20; ++i)
52 {
53 descr[i * 2] = __builtin_bswap32(buffer_base + (buffer_len/0x20) * i);
54 descr[i * 2 + 1] = __builtin_bswap32(0x80000000 | (buffer_len/0x20));
55 }
56
57 memdcbf(descr, sizeof(descr));
58
59 write32(snd_base + 8, 0);
60 write32(snd_base + 8, 0x2000000);
61 write32(snd_base + 0, descr_base);
62 write32(snd_base + 8, 0x1d08001c);
63 write32(snd_base + 0xC, 0x1c);
64
65 wptr = 0;
66}
67
68void xenon_sound_submit(void *data, int len)
69{
70 int i = 0;
71 while (len)
72 {
73 int av = buffer_len - wptr;
74 if (av > len)
75 av = len;
76
77 memcpy(buffer + wptr, data + i, av);
78 memdcbst(buffer + wptr, av);
79
80 i += av;
81 wptr += av;
82 len -= av;
83 if (wptr == buffer_len)
84 wptr = 0;
85 }
86 int cur_descr = (wptr / (buffer_len/0x20) -1) & 0x1f;
87
88 write32(snd_base + 4, cur_descr << 8);
89 write32(snd_base + 8, read32(snd_base) | 0x1000000);
90}
91
93{
94 uint32_t reg = read32(snd_base + 4);
95
96 int rptr_descr = reg & 0x1f;
97 int last_valid_descr = (reg & 0x1f00) >> 8;
98 int cur_len = (reg >> 16) & 0xFFFF;
99
100 if (rptr_descr == last_valid_descr && !cur_len)
101 return buffer_len;
102
103 int rptr = rptr_descr * (buffer_len/0x20);
104 int av = rptr - wptr;
105 if (av < 0)
106 av += buffer_len;
107 return av;
108}
109
111{
112 uint32_t reg = read32(snd_base + 4);
113
114 int rptr_descr = reg & 0x1f;
115 int last_valid_descr = (reg & 0x1f00) >> 8;
116 int cur_len = (reg >> 16) & 0xFFFF;
117
118 int l = last_valid_descr - rptr_descr;
119 if (l < 0)
120 l += 0x20;
121 l *= (buffer_len/0x20);
122 l += cur_len;
123
124 return l;
125}
void memdcbf(void *addr, int len)
void memdcbst(void *addr, int len)
u32 uint32_t
Definition: libfdt_env.h:11
u8 uint8_t
Definition: libfdt_env.h:9
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
Definition: mf-runtime.h:34
int xenon_sound_get_free(void)
Definition: sound.c:92
void xenon_sound_init(void)
Definition: sound.c:15
int xenos_is_hdmi
Definition: xenos.c:22
void xenon_sound_submit(void *data, int len)
Definition: sound.c:68
int xenon_sound_get_unplayed(void)
Definition: sound.c:110
void xenon_gpio_control(uint32_t reg, uint32_t clear, uint32_t set)
Definition: xenon_gpio.c:6
void xenon_smc_send_message(const unsigned char *msg)
Definition: xenon_smc.c:20
int xenon_smc_i2c_write(uint16_t addr, uint8_t val)
Definition: xenon_smc.c:192
union @15 data