Subversion Repositories Kolibri OS

Rev

Rev 1692 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1692 Rev 1695
1
#define FORCED_PIO
1
#define FORCED_PIO
2
 
2
 
3
#include 
3
#include 
4
#include "pci.h"
4
#include "pci.h"
5
#include 
5
#include 
6
 
6
 
7
#include "geode.h"
7
#include "geode.h"
8
 
8
 
9
#define DBG(format,...) dbgprintf(format,##__VA_ARGS__)
9
#define DBG(format,...) dbgprintf(format,##__VA_ARGS__)
10
 
10
 
11
#define  BM0_IRQ            0x04
11
#define  BM0_IRQ            0x04
12
#define  BM1_IRQ            0x08
12
#define  BM1_IRQ            0x08
13
#define BITS_8_TO_16(x) ( ( (long) ((unsigned char) x - 128) ) << 8 )
13
#define BITS_8_TO_16(x) ( ( (long) ((unsigned char) x - 128) ) << 8 )
14
 
14
 
15
#define PCI_VENDOR_ID_NS  0x100b
15
#define PCI_VENDOR_ID_NS  0x100b
16
#define PCI_VENDOR_ID_AMD 0x1022
16
#define PCI_VENDOR_ID_AMD 0x1022
17
 
17
 
18
 
18
 
19
#ifndef PCI_DEVICE_ID_NS_CS5535_AUDIO
19
#ifndef PCI_DEVICE_ID_NS_CS5535_AUDIO
20
    #define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e
20
    #define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e
21
#endif
21
#endif
22
#ifndef PCI_DEVICE_ID_AMD_CS5536_AUDIO
22
#ifndef PCI_DEVICE_ID_AMD_CS5536_AUDIO
23
    #define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
23
    #define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
24
#endif
24
#endif
25
 
25
 
26
#define  ID_DEV_1   ((PCI_DEVICE_ID_NS_CS5535_AUDIO  << 16)|PCI_VENDOR_ID_NS)
26
#define  ID_DEV_1   ((PCI_DEVICE_ID_NS_CS5535_AUDIO  << 16)|PCI_VENDOR_ID_NS)
27
#define  ID_DEV_2   ((PCI_DEVICE_ID_AMD_CS5536_AUDIO << 16)|PCI_VENDOR_ID_AMD)
27
#define  ID_DEV_2   ((PCI_DEVICE_ID_AMD_CS5536_AUDIO << 16)|PCI_VENDOR_ID_AMD)
28
 
28
 
29
#define SET                 1
29
#define SET                 1
30
#define	CLEAR				0
30
#define	CLEAR				0
31
 
31
 
32
int __stdcall srv_sound(ioctl_t *io);
32
int __stdcall srv_sound(ioctl_t *io);
33
 
33
 
34
 
34
 
35
PRD_ENTRY __attribute__((aligned(16))) prd_tab[5];
35
PRD_ENTRY __attribute__((aligned(16))) prd_tab[5];
36
 
36
 
37
 
37
 
38
typedef struct
38
typedef struct
39
{
39
{
40
    PCITAG  pciTag;
40
    PCITAG  pciTag;
41
    Bool    is_iomapped;
41
    Bool    is_iomapped;
42
    addr_t  F3BAR0;
42
    addr_t  F3BAR0;
43
 
43
 
44
    Bool    fAD1819A;
44
    Bool    fAD1819A;
45
 
45
 
46
    int     CurrentPowerState;
46
    int     CurrentPowerState;
47
 
47
 
48
    addr_t  buffer;
48
    addr_t  buffer;
49
    addr_t  prd_dma;
49
    addr_t  buffer_dma;
50
 
50
    addr_t  prd_dma;
-
 
51
 
51
    addr_t  irq_line;
52
    addr_t  irq_line;
52
    u32_t   irq_mask;
53
    u32_t   irq_mask;
53
 
54
 
54
    void    __stdcall (*callback)(addr_t buffer);
55
    void    __stdcall (*callback)(addr_t buffer);
55
}geode_t;
56
}geode_t;
56
 
57
 
57
geode_t  geode;
58
geode_t  geode;
58
 
59
 
59
 
60
 
60
static inline void ctrl_write_32(addr_t reg, u32_t data)
61
static inline void ctrl_write_32(addr_t reg, u32_t data)
61
{
62
{
62
    reg+= geode.F3BAR0;
63
    reg+= geode.F3BAR0;
63
 
64
 
64
#ifdef FORCED_PIO
65
#ifdef FORCED_PIO
65
       out32((u16_t)reg, data);
66
       out32((u16_t)reg, data);
66
#else
67
#else
67
    if(geode.is_iomapped)
68
    if(geode.is_iomapped)
68
       out32((u16_t)reg, data);
69
       out32((u16_t)reg, data);
69
    else
70
    else
70
        *(u32_t*)reg = data;
71
        *(u32_t*)reg = data;
71
#endif
72
#endif
72
}
73
}
73
 
74
 
74
static inline u32_t ctrl_read_32(addr_t reg)
75
static inline u32_t ctrl_read_32(addr_t reg)
75
{
76
{
76
    reg+= geode.F3BAR0;
77
    reg+= geode.F3BAR0;
77
#ifdef FORCED_PIO
78
#ifdef FORCED_PIO
78
        return in32((u16_t)reg);
79
        return in32((u16_t)reg);
79
#else
80
#else
80
    if(geode.is_iomapped)
81
    if(geode.is_iomapped)
81
        return in32((u16_t)reg);
82
        return in32((u16_t)reg);
82
    else
83
    else
83
        return *(u32_t*)reg;
84
        return *(u32_t*)reg;
84
#endif
85
#endif
85
}
86
}
86
 
87
 
87
 
88
 
88
 
89
 
89
Bool snd_hw_WaitForBit(addr_t offset, u32_t Bit,
90
Bool snd_hw_WaitForBit(addr_t offset, u32_t Bit,
90
                              unsigned char Operation,
91
                              unsigned char Operation,
91
                              count_t timeout,
92
                              count_t timeout,
92
                              u32_t *pReturnValue)
93
                              u32_t *pReturnValue)
93
{
94
{
94
    volatile u32_t  tmp;
95
    volatile u32_t  tmp;
95
 
96
 
96
    tmp = ctrl_read_32(offset);
97
    tmp = ctrl_read_32(offset);
97
 
98
 
98
    while (timeout)
99
    while (timeout)
99
    {
100
    {
100
        if (Operation==CLEAR){
101
        if (Operation==CLEAR){
101
            if (!(tmp & Bit))
102
            if (!(tmp & Bit))
102
                break;
103
                break;
103
        } else if (tmp & Bit)
104
        } else if (tmp & Bit)
104
                break;
105
                break;
105
 
106
 
106
        /*If the Bit is not clear yet, we wait for 10 milisecond and try again*/
107
        /*If the Bit is not clear yet, we wait for 10 milisecond and try again*/
107
        delay(10/10);
108
        delay(10/10);
108
 
109
 
109
        tmp = ctrl_read_32(offset);
110
        tmp = ctrl_read_32(offset);
110
 
111
 
111
        timeout--;
112
        timeout--;
112
    };
113
    };
113
 
114
 
114
    if (pReturnValue)
115
    if (pReturnValue)
115
        *pReturnValue=tmp;
116
        *pReturnValue=tmp;
116
 
117
 
117
    if (!timeout)
118
    if (!timeout)
118
        return FALSE;
119
        return FALSE;
119
 
120
 
120
    return TRUE;
121
    return TRUE;
121
}
122
}
122
 
123
 
123
u16_t snd_hw_CodecRead ( u8_t CodecRegister )
124
u16_t snd_hw_CodecRead ( u8_t CodecRegister )
124
{
125
{
125
    u32_t CodecRegister_data = 0;
126
    u32_t CodecRegister_data = 0;
126
    u32_t timeout=10;
127
    u32_t timeout=10;
127
    volatile u32_t val=0;
128
    volatile u32_t val=0;
128
 
129
 
129
    CodecRegister_data  = ((u32_t)CodecRegister)<<24;
130
    CodecRegister_data  = ((u32_t)CodecRegister)<<24;
130
    CodecRegister_data |= 0x80000000;   /* High-bit set (p.106) is a CODEC reg READ.*/
131
    CodecRegister_data |= 0x80000000;   /* High-bit set (p.106) is a CODEC reg READ.*/
131
 
132
 
132
/*  Set the bit.  We are going to access the CODEC...*/
133
/*  Set the bit.  We are going to access the CODEC...*/
133
    CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
134
    CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
134
 
135
 
135
/*Request the data*/
136
/*Request the data*/
136
    ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
137
    ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
137
 
138
 
138
/*  Now we need to wait for BIT_5535_CODEC_COMMAND_NEW of the Codec control register to clear
139
/*  Now we need to wait for BIT_5535_CODEC_COMMAND_NEW of the Codec control register to clear
139
    (For subsequent Reads/Writes)*/
140
    (For subsequent Reads/Writes)*/
140
    if (!snd_hw_WaitForBit (CODEC_CONTROL_REG_5535,
141
    if (!snd_hw_WaitForBit (CODEC_CONTROL_REG_5535,
141
                            BIT_5535_CODEC_COMMAND_NEW, CLEAR, 50, NULL))
142
                            BIT_5535_CODEC_COMMAND_NEW, CLEAR, 50, NULL))
142
        DBG("BIT_5535_CODEC_COMMAND_NEW did not clear!!\n");
143
        DBG("BIT_5535_CODEC_COMMAND_NEW did not clear!!\n");
143
 
144
 
144
/* Wait for CODEC_STATUS_NEW and confirm the read of the requested register*/
145
/* Wait for CODEC_STATUS_NEW and confirm the read of the requested register*/
145
    timeout = 50;
146
    timeout = 50;
146
    do
147
    do
147
    {
148
    {
148
        val = ctrl_read_32(CODEC_STATUS_REG_5535);
149
        val = ctrl_read_32(CODEC_STATUS_REG_5535);
149
        if ((val & BIT_5535_CODEC_STATUS_NEW) &&
150
        if ((val & BIT_5535_CODEC_STATUS_NEW) &&
150
            ((u32_t) CodecRegister == ((0xFF000000 & val)>>24)))
151
            ((u32_t) CodecRegister == ((0xFF000000 & val)>>24)))
151
            break;
152
            break;
152
        else
153
        else
153
            /*Wait for 10 miliseconds and try again*/
154
            /*Wait for 10 miliseconds and try again*/
154
            delay(10/10);
155
            delay(10/10);
155
    } while ( --timeout);
156
    } while ( --timeout);
156
 
157
 
157
    if (!timeout)
158
    if (!timeout)
158
       DBG("Could not read the CODEC!!  Returning what we got.\n");
159
       DBG("Could not read the CODEC!!  Returning what we got.\n");
159
 
160
 
160
    return( (u16_t)val );
161
    return( (u16_t)val );
161
}
162
}
162
 
163
 
163
void snd_hw_CodecWrite( u8_t CodecRegister, u16_t CodecData  )
164
void snd_hw_CodecWrite( u8_t CodecRegister, u16_t CodecData  )
164
{
165
{
165
    u32_t CodecRegister_data;
166
    u32_t CodecRegister_data;
166
    u32_t Temp, timeout;
167
    u32_t Temp, timeout;
167
 
168
 
168
    CodecRegister_data = ((u32_t) CodecRegister)<<24;
169
    CodecRegister_data = ((u32_t) CodecRegister)<<24;
169
    CodecRegister_data |= (u32_t) CodecData;
170
    CodecRegister_data |= (u32_t) CodecData;
170
    CodecRegister_data &= CODEC_COMMAND_MASK;
171
    CodecRegister_data &= CODEC_COMMAND_MASK;
171
 
172
 
172
    /*Set the bit.  We are going to access the CODEC...*/
173
    /*Set the bit.  We are going to access the CODEC...*/
173
    CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
174
    CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
174
 
175
 
175
    /*Write the data*/
176
    /*Write the data*/
176
    ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
177
    ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
177
    //OS_DbgMsg("Writing: %08X\n", CodecRegister_data);
178
    //OS_DbgMsg("Writing: %08X\n", CodecRegister_data);
178
 
179
 
179
    /*We need to wait for bit16 of the Codec control register to clear*/
180
    /*We need to wait for bit16 of the Codec control register to clear*/
180
    Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
181
    Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
181
 
182
 
182
    timeout = 50;
183
    timeout = 50;
183
 
184
 
184
    while ((Temp & BIT_5535_CODEC_COMMAND_NEW) && timeout-- )
185
    while ((Temp & BIT_5535_CODEC_COMMAND_NEW) && timeout-- )
185
        Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
186
        Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
186
 
187
 
187
    if (!timeout)
188
    if (!timeout)
188
        DBG("Could not Write the CODEC!!\n"
189
        DBG("Could not Write the CODEC!!\n"
189
                  "BIT_5535_CODEC_COMMAND_NEW did not clear!\n");
190
                  "BIT_5535_CODEC_COMMAND_NEW did not clear!\n");
190
}
191
}
191
 
192
 
192
 
193
 
193
void snd_hw_SetCodecRate(u32_t SampleRate)
194
void snd_hw_SetCodecRate(u32_t SampleRate)
194
{
195
{
195
    u16_t val;
196
    u16_t val;
196
 
197
 
197
    DBG("Rate: %d\n", SampleRate);
198
    DBG("Rate: %d\n", SampleRate);
198
 
199
 
199
    /*If Double-Rate is supported (Bit 2 on register 28h)...*/
200
    /*If Double-Rate is supported (Bit 2 on register 28h)...*/
200
    val=snd_hw_CodecRead(EXTENDED_AUDIO_ID);
201
    val=snd_hw_CodecRead(EXTENDED_AUDIO_ID);
201
 
202
 
202
    if (val & 0x02)
203
    if (val & 0x02)
203
    {
204
    {
204
        DBG("Codec supports Double rate.\n");
205
        DBG("Codec supports Double rate.\n");
205
        val=snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT);
206
        val=snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT);
206
 
207
 
207
        if (SampleRate>48000)
208
        if (SampleRate>48000)
208
        {
209
        {
209
            snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val|0x0002));
210
            snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val|0x0002));
210
            SampleRate/=2;
211
            SampleRate/=2;
211
        }
212
        }
212
        else
213
        else
213
            snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val&0xFFFD));
214
            snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val&0xFFFD));
214
    }
215
    }
215
    if (geode.fAD1819A)
216
    if (geode.fAD1819A)
216
    {
217
    {
217
        DBG("AD1819...\n");
218
        DBG("AD1819...\n");
218
        snd_hw_CodecWrite(AD1819A_PCM_SR0,(u16_t)SampleRate);
219
        snd_hw_CodecWrite(AD1819A_PCM_SR0,(u16_t)SampleRate);
219
    }
220
    }
220
    else
221
    else
221
        snd_hw_CodecWrite(PCM_FRONT_DAC_RATE,(u16_t)SampleRate);
222
        snd_hw_CodecWrite(PCM_FRONT_DAC_RATE,(u16_t)SampleRate);
222
}
223
}
223
 
224
 
224
Bool init_device()
225
Bool init_device()
225
{
226
{
226
    u32_t io_base = pciReadLong(geode.pciTag, 0x10);
227
    u32_t io_base = pciReadLong(geode.pciTag, 0x10);
227
 
228
 
228
    if( PCI_MAP_IS_IO(io_base))
229
    if( PCI_MAP_IS_IO(io_base))
229
    {
230
    {
230
        geode.is_iomapped = TRUE;
231
        geode.is_iomapped = TRUE;
231
        geode.F3BAR0 = PCIGETIO(io_base);
232
        geode.F3BAR0 = PCIGETIO(io_base);
232
        DBG("io mapped F3BAR0 %x\n", geode.F3BAR0);
233
        DBG("io mapped F3BAR0 %x\n", geode.F3BAR0);
233
    }
234
    }
234
    else if(PCI_MAP_IS_MEM(io_base))
235
    else if(PCI_MAP_IS_MEM(io_base))
235
    {
236
    {
236
        geode.is_iomapped = FALSE;
237
        geode.is_iomapped = FALSE;
237
        io_base = PCIGETMEMORY(io_base);
238
        io_base = PCIGETMEMORY(io_base);
238
        geode.F3BAR0 = MapIoMem(io_base, 128, PG_SW+PG_NOCACHE);
239
        geode.F3BAR0 = MapIoMem(io_base, 128, PG_SW+PG_NOCACHE);
239
        DBG("memory mapped F3BAR0 %x\n", geode.F3BAR0);
240
        DBG("memory mapped F3BAR0 %x\n", geode.F3BAR0);
240
    }
241
    }
241
 
242
 
242
    geode.buffer = KernelAlloc(64*1024);
243
    geode.buffer = KernelAlloc(64*1024);
243
 
244
 
244
    addr_t buffer = geode.buffer;
245
    addr_t buffer = geode.buffer;
245
    addr_t dma = GetPgAddr(geode.buffer);
246
    addr_t dma = GetPgAddr(geode.buffer);
246
 
247
    geode.buffer_dma = dma;
247
    geode.prd_dma  = (((addr_t)prd_tab) & 4095) + GetPgAddr((void*)prd_tab);
248
 
-
 
249
    geode.prd_dma  = (((addr_t)prd_tab) & 4095) + GetPgAddr((void*)prd_tab);
248
 
250
 
249
    prd_tab[0].ulPhysAddr = dma;
251
    prd_tab[0].ulPhysAddr = dma;
250
    prd_tab[0].SizeFlags = 16384 | PRD_EOP_BIT ;
252
    prd_tab[0].SizeFlags = 16384 | PRD_EOP_BIT ;
251
 
253
 
252
    prd_tab[1].ulPhysAddr = dma + 16384;
254
    prd_tab[1].ulPhysAddr = dma + 16384;
253
    prd_tab[1].SizeFlags = 16384 | PRD_EOP_BIT ;
255
    prd_tab[1].SizeFlags = 16384 | PRD_EOP_BIT ;
254
 
256
 
255
    prd_tab[2].ulPhysAddr = dma + 16384*2;
257
    prd_tab[2].ulPhysAddr = dma + 16384*2;
256
    prd_tab[2].SizeFlags = 16384 | PRD_EOP_BIT ;
258
    prd_tab[2].SizeFlags = 16384 | PRD_EOP_BIT ;
257
 
259
 
258
    prd_tab[3].ulPhysAddr = dma + 16384*3;
260
    prd_tab[3].ulPhysAddr = dma + 16384*3;
259
    prd_tab[3].SizeFlags = 16384 | PRD_EOP_BIT ;
261
    prd_tab[3].SizeFlags = 16384 | PRD_EOP_BIT ;
260
 
262
 
261
    prd_tab[4].ulPhysAddr = geode.prd_dma;
263
    prd_tab[4].ulPhysAddr = geode.prd_dma;
262
    prd_tab[4].SizeFlags = PRD_JMP_BIT ;
264
    prd_tab[4].SizeFlags = PRD_JMP_BIT ;
263
 
265
 
264
    ctrl_write_32(0x24, geode.prd_dma);
266
    ctrl_write_32(0x24, geode.prd_dma);
265
 
267
 
266
    __clear((void*)buffer,64*1024);
268
    __clear((void*)buffer,64*1024);
267
//    u32_t tmp = ctrl_read_32(0x24);
269
//    u32_t tmp = ctrl_read_32(0x24);
268
 
270
 
269
//    dbgprintf("Create primary buffer at %x dma at %x\n", geode.buffer, dma );
271
//    dbgprintf("Create primary buffer at %x dma at %x\n", geode.buffer, dma );
270
 
272
 
271
//    dbgprintf("Set prd dma %x, read prd dma %x\n", geode.prd_dma, tmp);
273
//    dbgprintf("Set prd dma %x, read prd dma %x\n", geode.prd_dma, tmp);
272
 
274
 
273
    geode.irq_line = pciReadLong(geode.pciTag, 0x3C) & 0xFF;
275
    geode.irq_line = pciReadLong(geode.pciTag, 0x3C) & 0xFF;
274
    geode.irq_mask = ~(1<
276
    geode.irq_mask = ~(1<
275
 
277
 
276
    DBG("Irq line %d, mask %x\n", geode.irq_line, geode.irq_mask);
278
    DBG("Irq line %d, mask %x\n", geode.irq_line, geode.irq_mask);
277
 
279
 
278
 
280
 
279
/*
281
/*
280
    geode.CommandRegister  = geode.F3BAR0+0x20;
282
    geode.CommandRegister  = geode.F3BAR0+0x20;
281
    geode.PRDTableAddress  = geode.F3BAR0+0x24;
283
    geode.PRDTableAddress  = geode.F3BAR0+0x24;
282
    geode.DMAPointer       = geode.F3BAR0+0x60;
284
    geode.DMAPointer       = geode.F3BAR0+0x60;
283
 
285
 
284
    geode.IRQControlRegister        = geode.F3BAR0+0x1C;
286
    geode.IRQControlRegister        = geode.F3BAR0+0x1C;
285
    geode.InternalIRQEnableRegister = geode.F3BAR0+0x1A;
287
    geode.InternalIRQEnableRegister = geode.F3BAR0+0x1A;
286
    geode.SMI_StatusRegister        = geode.F3BAR0+0x21;
288
    geode.SMI_StatusRegister        = geode.F3BAR0+0x21;
287
*/
289
*/
288
 
290
 
289
 
291
 
290
 
292
 
291
/*CODEC - RESET and volumes initalization.*/
293
/*CODEC - RESET and volumes initalization.*/
292
/*Set the Warm RESET and CODEC_COMMAND_NEW bits.*/
294
/*Set the Warm RESET and CODEC_COMMAND_NEW bits.*/
293
 
295
 
294
    DBG("reset codec...\n");
296
    DBG("reset codec...\n");
295
 
297
 
296
    ctrl_write_32(CODEC_CONTROL_REG_5535, 0x00030000 );
298
    ctrl_write_32(CODEC_CONTROL_REG_5535, 0x00030000 );
297
 
299
 
298
    if (!snd_hw_WaitForBit (CODEC_STATUS_REG_5535, BIT_CODEC_READY, SET, 40, NULL))
300
    if (!snd_hw_WaitForBit (CODEC_STATUS_REG_5535, BIT_CODEC_READY, SET, 40, NULL))
299
    {
301
    {
300
       DBG("Primary Codec NOT Ready...Aborting\n");
302
       DBG("Primary Codec NOT Ready...Aborting\n");
301
       return FALSE;
303
       return FALSE;
302
    }
304
    }
303
 
305
 
304
    u16_t id7c, id7e;
306
    u16_t id7c, id7e;
305
 
307
 
306
    id7c = snd_hw_CodecRead(AD1819A_VENDORID1);
308
    id7c = snd_hw_CodecRead(AD1819A_VENDORID1);
307
    id7e = snd_hw_CodecRead(AD1819A_VENDORID2);
309
    id7e = snd_hw_CodecRead(AD1819A_VENDORID2);
308
 
310
 
309
    dbgprintf("codec id 0x7C %x  0x7E %x\n", id7c, id7e);
311
    dbgprintf("codec id 0x7C %x  0x7E %x\n", id7c, id7e);
310
 
312
 
311
    /*Check which codec is being used */
313
    /*Check which codec is being used */
312
    if ( (id7c == 0x4144) &&
314
    if ( (id7c == 0x4144) &&
313
         (id7e == 0x5303) )
315
         (id7e == 0x5303) )
314
    {
316
    {
315
        geode.fAD1819A = TRUE;
317
        geode.fAD1819A = TRUE;
316
        /*  Enable non-48kHz sample rates. */
318
        /*  Enable non-48kHz sample rates. */
317
        snd_hw_CodecWrite (AD1819A_SER_CONF,
319
        snd_hw_CodecWrite (AD1819A_SER_CONF,
318
                           snd_hw_CodecRead(AD1819A_SER_CONF>>8) |
320
                           snd_hw_CodecRead(AD1819A_SER_CONF>>8) |
319
                           AD1819A_SER_CONF_DRQEN);
321
                           AD1819A_SER_CONF_DRQEN);
320
        DBG("detect AD1819A audio codec\n");
322
        DBG("detect AD1819A audio codec\n");
321
    }
323
    }
322
    else
324
    else
323
    {
325
    {
324
        geode.fAD1819A = FALSE;
326
        geode.fAD1819A = FALSE;
325
        snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT,
327
        snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT,
326
        (snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT) | 0x0001));
328
        (snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT) | 0x0001));
327
        /* set the VRA bit to ON*/
329
        /* set the VRA bit to ON*/
328
    }
330
    }
329
 
331
 
330
    /* set default volume*/
332
    /* set default volume*/
331
    snd_hw_CodecWrite( MASTER_VOLUME,       0x0909);
333
    snd_hw_CodecWrite( MASTER_VOLUME,       0x0909);
332
    snd_hw_CodecWrite( PCM_OUT_VOL,         0x0606);
334
    snd_hw_CodecWrite( PCM_OUT_VOL,         0x0606);
333
    snd_hw_CodecWrite( PC_BEEP_VOLUME,      0x0000);
335
    snd_hw_CodecWrite( PC_BEEP_VOLUME,      0x0000);
334
    snd_hw_CodecWrite( PHONE_VOLUME,        0x0606);
336
    snd_hw_CodecWrite( PHONE_VOLUME,        0x0606);
335
    snd_hw_CodecWrite( MIC_VOLUME,          0x8048);
337
    snd_hw_CodecWrite( MIC_VOLUME,          0x8048);
336
    snd_hw_CodecWrite( LINE_IN_VOLUME,      0x0808);
338
    snd_hw_CodecWrite( LINE_IN_VOLUME,      0x0808);
337
    snd_hw_CodecWrite( CD_VOLUME,           0x8000);
339
    snd_hw_CodecWrite( CD_VOLUME,           0x8000);
338
    snd_hw_CodecWrite( VIDEO_VOLUME,        0x8000);
340
    snd_hw_CodecWrite( VIDEO_VOLUME,        0x8000);
339
    snd_hw_CodecWrite( TV_VOLUME,           0x8000);
341
    snd_hw_CodecWrite( TV_VOLUME,           0x8000);
340
    snd_hw_CodecWrite( RECORD_SELECT,       0x0000);
342
    snd_hw_CodecWrite( RECORD_SELECT,       0x0000);
341
    snd_hw_CodecWrite( RECORD_GAIN,         0x0a0a);
343
    snd_hw_CodecWrite( RECORD_GAIN,         0x0a0a);
342
    snd_hw_CodecWrite( GENERAL_PURPOSE,     0x0200);
344
    snd_hw_CodecWrite( GENERAL_PURPOSE,     0x0200);
343
    snd_hw_CodecWrite( MASTER_VOLUME_MONO,  0x0000);
345
    snd_hw_CodecWrite( MASTER_VOLUME_MONO,  0x0000);
344
 
346
 
345
    snd_hw_SetCodecRate(48000);
347
    snd_hw_SetCodecRate(48000);
346
    /*Set all the power state bits to 0 (Reg 26h)*/
348
    /*Set all the power state bits to 0 (Reg 26h)*/
347
    snd_hw_CodecWrite (POWERDOWN_CTRL_STAT, 0x0000);
349
    snd_hw_CodecWrite (POWERDOWN_CTRL_STAT, 0x0000);
348
    geode.CurrentPowerState = GEODEAUDIO_D0;
350
    geode.CurrentPowerState = GEODEAUDIO_D0;
349
//    OS_DbgMsg("<--snd_hw_InitAudioRegs\n");
351
//    OS_DbgMsg("<--snd_hw_InitAudioRegs\n");
350
 
352
 
351
 
353
 
352
    return TRUE;
354
    return TRUE;
353
}
355
}
354
 
356
 
355
static int snd_StartDMA ()
357
static int snd_StartDMA ()
356
{
358
{
357
 
359
 
358
#ifdef FORCED_PIO
360
#ifdef FORCED_PIO
359
        out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
361
        out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
360
#else
362
#else
361
    if (geode.is_iomapped)
363
    if (geode.is_iomapped)
362
        out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
364
        out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
363
    else
365
    else
364
        *(u8_t*)(geode.F3BAR0+0x20)= PCI_READS | ENABLE_BUSMASTER;
366
        *(u8_t*)(geode.F3BAR0+0x20)= PCI_READS | ENABLE_BUSMASTER;
365
#endif
367
#endif
366
    return 0;
368
    return 0;
367
};
369
};
368
 
370
 
369
static u8_t snd_hw_InterruptID ()
371
static u8_t snd_hw_InterruptID ()
370
{
372
{
371
    volatile u8_t *TempInterruptID, ID;
373
    volatile u8_t *TempInterruptID, ID;
372
 
374
 
373
#ifdef FORCED_PIO
375
#ifdef FORCED_PIO
374
        ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
376
        ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
375
#else
377
#else
376
    if (geode.is_iomapped)
378
    if (geode.is_iomapped)
377
        ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
379
        ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
378
    else
380
    else
379
    {
381
    {
380
        TempInterruptID=(u8_t*)(geode.F3BAR0 + 0x12);
382
        TempInterruptID=(u8_t*)(geode.F3BAR0 + 0x12);
381
        ID=*TempInterruptID;
383
        ID=*TempInterruptID;
382
    }
384
    }
383
#endif
385
#endif
384
    return (ID);
386
    return (ID);
385
}
387
}
386
 
388
 
387
 
389
 
388
static u8_t snd_hw_ClearStat(int Channel)
390
static u8_t snd_hw_ClearStat(int Channel)
389
{
391
{
390
    volatile u8_t status;      /*Volatile to force read-to-clear.*/
392
    volatile u8_t status;      /*Volatile to force read-to-clear.*/
391
 
393
 
392
    /*Read to clear*/
394
    /*Read to clear*/
393
 
395
 
394
#ifdef FORCED_PIO
396
#ifdef FORCED_PIO
395
        status = in8((u16_t) geode.F3BAR0 + 0x21);
397
        status = in8((u16_t) geode.F3BAR0 + 0x21);
396
#else
398
#else
397
    if (geode.is_iomapped)
399
    if (geode.is_iomapped)
398
        status = in8((u16_t) geode.F3BAR0 + 0x21);
400
        status = in8((u16_t) geode.F3BAR0 + 0x21);
399
    else
401
    else
400
        status = *((u8_t*)geode.F3BAR0 + 0x21);
402
        status = *((u8_t*)geode.F3BAR0 + 0x21);
401
#endif
403
#endif
402
    return status;
404
    return status;
403
}
405
}
404
 
406
 
405
 
407
 
406
void snd_interrupt()
408
void snd_interrupt()
407
{
409
{
408
    u8_t IntID;
410
    u8_t IntID;
409
 
411
 
410
    IntID = snd_hw_InterruptID();
412
    IntID = snd_hw_InterruptID();
411
 
413
 
412
//    dbgprintf("IRQ id %x\n", IntID);
414
//    dbgprintf("IRQ id %x\n", IntID);
413
 
415
 
414
    snd_hw_ClearStat(CHANNEL0_PLAYBACK);
416
    snd_hw_ClearStat(CHANNEL0_PLAYBACK);
415
//    snd_hw_ClearStat(CHANNEL1_RECORD);
417
//    snd_hw_ClearStat(CHANNEL1_RECORD);
416
 
418
 
417
    if(IntID & BM0_IRQ)
419
    if(IntID & BM0_IRQ)
418
    {
420
    {
419
      addr_t prd, offset, base;
421
      addr_t prd, offset, base;
420
 
422
 
421
      prd = ctrl_read_32(0x24);
423
      prd = ctrl_read_32(0x24);
422
      offset = (1 + (prd - geode.prd_dma)>>3) & 3;
424
      offset = (1 + (prd - geode.prd_dma)>>3) & 3;
423
 
425
 
424
      base = geode.buffer + 16384*offset;
426
      base = geode.buffer + 16384*offset;
425
 
427
 
426
      geode.callback(base);
428
      geode.callback(base);
427
      __asm__ volatile("":::"ebx","esi","edi");
429
      __asm__ volatile("":::"ebx","esi","edi");
428
 
430
 
429
//      dbgprintf(">>BM0_IRQ prd %x offset %x base %x\n", prd, offset, base);
431
//      dbgprintf(">>BM0_IRQ prd %x offset %x base %x\n", prd, offset, base);
430
    };
432
    };
431
};
433
};
432
 
434
 
433
Bool FindPciDevice()
435
Bool FindPciDevice()
434
{
436
{
435
    u32_t bus, last_bus;
437
    u32_t bus, last_bus;
436
    PCITAG tag;
438
    PCITAG tag;
437
 
439
 
438
    if( (last_bus = PciApi(1))==-1)
440
    if( (last_bus = PciApi(1))==-1)
439
        return FALSE;
441
        return FALSE;
440
 
442
 
441
    for(bus=0;bus<=last_bus;bus++)
443
    for(bus=0;bus<=last_bus;bus++)
442
    {
444
    {
443
        u32_t devfn;
445
        u32_t devfn;
444
 
446
 
445
        for(devfn=0;devfn<256;devfn++)
447
        for(devfn=0;devfn<256;devfn++)
446
        {
448
        {
447
            u32_t pciId=0;
449
            u32_t pciId=0;
448
 
450
 
449
            pciId = PciRead32(bus,devfn, 0);
451
            pciId = PciRead32(bus,devfn, 0);
450
 
452
 
451
            if( (pciId == ID_DEV_1) ||
453
            if( (pciId == ID_DEV_1) ||
452
                (pciId == ID_DEV_2) )
454
                (pciId == ID_DEV_2) )
453
            {
455
            {
454
                DBG("detect companion audio device %x\n", pciId);
456
                DBG("detect companion audio device %x\n", pciId);
455
                geode.pciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
457
                geode.pciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
456
                return TRUE;
458
                return TRUE;
457
            };
459
            };
458
        };
460
        };
459
    };
461
    };
460
    return FALSE;
462
    return FALSE;
461
};
463
};
462
 
464
 
463
 
465
 
464
u32_t drvEntry(int action, char *cmdline)
466
u32_t drvEntry(int action, char *cmdline)
465
{
467
{
466
    u32_t retval;
468
    u32_t retval;
467
 
469
 
468
    int i;
470
    int i;
469
 
471
 
470
    if(action != 1)
472
    if(action != 1)
471
        return 0;
473
        return 0;
472
 
474
 
473
    if(!dbg_open("/rd/1/drivers/geode.log"))
475
    if(!dbg_open("/rd/1/drivers/geode.log"))
474
    {
476
    {
475
        printf("Can't open /rd/1/drivers/geode.log\nExit\n");
477
        printf("Can't open /rd/1/drivers/geode.log\nExit\n");
476
        return 0;
478
        return 0;
477
    }
479
    }
478
 
480
 
479
    if( FindPciDevice() == FALSE)
481
    printf("AMD Geode CS5536 audio driver\n");
-
 
482
 
-
 
483
    if( FindPciDevice() == FALSE)
480
    {
484
    {
481
        dbgprintf("Device not found\n");
485
        dbgprintf("Device not found\n");
482
        return 0;
486
        return 0;
483
    };
487
    };
484
 
488
 
485
    init_device();
489
    init_device();
486
 
490
 
487
    retval = RegService("SOUND", srv_sound);
491
    retval = RegService("SOUND", srv_sound);
488
 
492
 
489
    AttachIntHandler(geode.irq_line, snd_interrupt, 0);
493
    AttachIntHandler(geode.irq_line, snd_interrupt, 0);
490
 
494
 
491
    DBG("reg service %s as: %x\n", "SOUND", retval);
495
    DBG("reg service %s as: %x\n", "SOUND", retval);
492
 
496
 
493
    return retval;
497
    return retval;
494
};
498
};
495
 
499
 
496
 
500
 
497
#define API_VERSION     0x01000100
501
#define API_VERSION     0x01000100
498
 
502
 
499
#define SRV_GETVERSION         0
503
#define SRV_GETVERSION         0
500
#define DEV_PLAY               1
504
#define DEV_PLAY               1
501
#define DEV_STOP               2
505
#define DEV_STOP               2
502
#define DEV_CALLBACK           3
506
#define DEV_CALLBACK           3
503
#define DEV_SET_BUFF           4
507
#define DEV_SET_BUFF           4
504
#define DEV_NOTIFY             5
508
#define DEV_NOTIFY             5
505
#define DEV_SET_MASTERVOL      6
509
#define DEV_SET_MASTERVOL      6
506
#define DEV_GET_MASTERVOL      7
510
#define DEV_GET_MASTERVOL      7
507
#define DEV_GET_INFO           8
511
#define DEV_GET_INFO           8
508
#define DEV_GET_POS            9
512
#define DEV_GET_POS            9
509
 
513
 
510
int __stdcall srv_sound(ioctl_t *io)
514
int __stdcall srv_sound(ioctl_t *io)
511
{
515
{
512
    u32_t *inp;
516
    u32_t *inp;
513
    u32_t *outp;
517
    u32_t *outp;
514
 
518
 
515
    inp = io->input;
519
    inp = io->input;
516
    outp = io->output;
520
    outp = io->output;
517
 
521
 
518
    switch(io->io_code)
522
    switch(io->io_code)
519
    {
523
    {
520
        case SRV_GETVERSION:
524
        case SRV_GETVERSION:
521
            if(io->out_size==4)
525
            if(io->out_size==4)
522
            {
526
            {
523
                *outp = API_VERSION;
527
                *outp = API_VERSION;
524
                return 0;
528
                return 0;
525
            }
529
            }
526
            break;
530
            break;
527
 
531
 
528
        case DEV_PLAY:
532
        case DEV_PLAY:
529
                return snd_StartDMA();
533
                return snd_StartDMA();
530
            break;
534
            break;
531
 
535
 
532
        case DEV_STOP:
536
        case DEV_STOP:
533
            break;
537
            break;
534
 
538
 
535
        case DEV_CALLBACK:
539
        case DEV_CALLBACK:
536
            if(io->inp_size==4)
540
            if(io->inp_size==4)
537
            {
541
            {
538
                geode.callback = (void*)(*inp);
542
                geode.callback = (void*)(*inp);
539
                return 0;
543
                return 0;
540
            }
544
            }
541
            break;
545
            break;
542
 
546
 
543
        case DEV_GET_POS:
547
        case DEV_GET_POS:
544
            if(io->out_size==4)
548
            if(io->out_size==4)
545
            {
549
            {
546
                *outp = ctrl_read_32(0x60)>>2;
550
                u32_t  dma;
547
                return 0;
551
                dma = ctrl_read_32(0x60);
-
 
552
                dma-= geode.buffer_dma;
548
            }
553
                *outp = (dma & 16383)>>2;
-
 
554
                return 0;
-
 
555
            }
549
            break;
556
            break;
550
 
557
 
551
    default:
558
    default:
552
      return ERR_PARAM;
559
      return ERR_PARAM;
553
  };
560
  };
554
  return ERR_PARAM;
561
  return ERR_PARAM;
555
}
562
}
556
>
563
>
557
>
564
>
558
 
565
 
559
 
566
 
560
>
567
>
561
 
568
 
562
>
569
>
563
 
570
 
564
>
571
>
565
>
572
>
566
>
573
>
567
>
574
>
568
>
575
>