Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
m68k
amiga
amisound.c
Go to the documentation of this file.
1
/*
2
* linux/arch/m68k/amiga/amisound.c
3
*
4
* amiga sound driver for Linux/m68k
5
*
6
* This file is subject to the terms and conditions of the GNU General Public
7
* License. See the file COPYING in the main directory of this archive
8
* for more details.
9
*/
10
11
#include <
linux/jiffies.h
>
12
#include <
linux/timer.h
>
13
#include <
linux/init.h
>
14
#include <linux/string.h>
15
#include <linux/module.h>
16
17
#include <
asm/amigahw.h
>
18
19
static
unsigned
short
*snd_data;
20
static
const
signed
char
sine_data[] = {
21
0, 39, 75, 103, 121, 127, 121, 103, 75, 39,
22
0, -39, -75, -103, -121, -127, -121, -103, -75, -39
23
};
24
#define DATA_SIZE ARRAY_SIZE(sine_data)
25
26
#define custom amiga_custom
27
28
/*
29
* The minimum period for audio may be modified by the frame buffer
30
* device since it depends on htotal (for OCS/ECS/AGA)
31
*/
32
33
volatile
unsigned
short
amiga_audio_min_period
= 124;
/* Default for pre-OCS */
34
EXPORT_SYMBOL
(
amiga_audio_min_period
);
35
36
#define MAX_PERIOD (65535)
37
38
39
/*
40
* Current period (set by dmasound.c)
41
*/
42
43
unsigned
short
amiga_audio_period
=
MAX_PERIOD
;
44
EXPORT_SYMBOL
(
amiga_audio_period
);
45
46
static
unsigned
long
clock_constant;
47
48
void
__init
amiga_init_sound
(
void
)
49
{
50
static
struct
resource
beep_res = { .
name
=
"Beep"
};
51
52
snd_data =
amiga_chip_alloc_res
(
sizeof
(sine_data), &beep_res);
53
if
(!snd_data) {
54
printk
(
KERN_CRIT
"amiga init_sound: failed to allocate chipmem\n"
);
55
return
;
56
}
57
memcpy
(snd_data, sine_data,
sizeof
(sine_data));
58
59
/* setup divisor */
60
clock_constant = (
amiga_colorclock
+
DATA_SIZE
/2)/
DATA_SIZE
;
61
62
/* without amifb, turn video off and enable high quality sound */
63
#ifndef CONFIG_FB_AMIGA
64
amifb_video_off();
65
#endif
66
}
67
68
static
void
nosound(
unsigned
long
ignored
);
69
static
DEFINE_TIMER
(sound_timer, nosound, 0, 0);
70
71
void
amiga_mksound
(
unsigned
int
hz,
unsigned
int
ticks
)
72
{
73
unsigned
long
flags
;
74
75
if
(!snd_data)
76
return
;
77
78
local_irq_save
(flags);
79
del_timer
( &sound_timer );
80
81
if
(hz > 20 && hz < 32767) {
82
unsigned
long
period
= (clock_constant / hz);
83
84
if
(period <
amiga_audio_min_period
)
85
period =
amiga_audio_min_period
;
86
if
(period >
MAX_PERIOD
)
87
period =
MAX_PERIOD
;
88
89
/* setup pointer to data, period, length and volume */
90
custom
.aud[2].audlc = snd_data;
91
custom
.aud[2].audlen =
sizeof
(sine_data)/2;
92
custom
.aud[2].audper = (
unsigned
short
)period;
93
custom
.aud[2].audvol = 32;
/* 50% of maxvol */
94
95
if
(ticks) {
96
sound_timer.expires =
jiffies
+
ticks
;
97
add_timer
( &sound_timer );
98
}
99
100
/* turn on DMA for audio channel 2 */
101
custom
.dmacon =
DMAF_SETCLR
|
DMAF_AUD2
;
102
103
}
else
104
nosound( 0 );
105
106
local_irq_restore
(flags);
107
}
108
109
110
static
void
nosound(
unsigned
long
ignored
)
111
{
112
/* turn off DMA for audio channel 2 */
113
custom
.dmacon =
DMAF_AUD2
;
114
/* restore period to previous value after beeping */
115
custom
.aud[2].audper =
amiga_audio_period
;
116
}
Generated on Thu Jan 10 2013 13:07:28 for Linux Kernel by
1.8.2