Blame view
sound/ppc/beep.c
7.08 KB
1a59d1b8e treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 |
/* * Beep using pcm * * Copyright (c) by Takashi Iwai <tiwai@suse.de> |
1da177e4c Linux-2.6.12-rc2 |
6 |
*/ |
6cbbfe1c8 ALSA: Include lin... |
7 |
#include <linux/io.h> |
1da177e4c Linux-2.6.12-rc2 |
8 9 10 11 |
#include <asm/irq.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> |
7bbd82775 [PATCH] ppc64: ve... |
12 13 |
#include <linux/pci.h> #include <linux/dma-mapping.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 |
#include <sound/core.h> #include <sound/control.h> #include "pmac.h" |
65b29f503 [ALSA] Remove xxx... |
17 |
struct pmac_beep { |
5ebdcbc2f [PATCH] Input: co... |
18 19 |
int running; /* boolean */ int volume; /* mixer volume: 0-100 */ |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 |
int volume_play; /* currently playing volume */ int hz; int nsamples; short *buf; /* allocated wave buffer */ |
7bbd82775 [PATCH] ppc64: ve... |
24 |
dma_addr_t addr; /* physical address of buffer */ |
5ebdcbc2f [PATCH] Input: co... |
25 |
struct input_dev *dev; |
1da177e4c Linux-2.6.12-rc2 |
26 27 28 29 30 |
}; /* * stop beep if running */ |
65b29f503 [ALSA] Remove xxx... |
31 |
void snd_pmac_beep_stop(struct snd_pmac *chip) |
1da177e4c Linux-2.6.12-rc2 |
32 |
{ |
65b29f503 [ALSA] Remove xxx... |
33 |
struct pmac_beep *beep = chip->beep; |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 38 39 40 41 42 43 44 |
if (beep && beep->running) { beep->running = 0; snd_pmac_beep_dma_stop(chip); } } /* * Stuff for outputting a beep. The values range from -327 to +327 * so we can multiply by an amplitude in the range 0..100 to get a * signed short value to put in the output buffer. */ |
6e9ef32fa ALSA: ppc: More c... |
45 |
static const short beep_wform[256] = { |
1da177e4c Linux-2.6.12-rc2 |
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 |
0, 40, 79, 117, 153, 187, 218, 245, 269, 288, 304, 316, 323, 327, 327, 324, 318, 310, 299, 288, 275, 262, 249, 236, 224, 213, 204, 196, 190, 186, 183, 182, 182, 183, 186, 189, 192, 196, 200, 203, 206, 208, 209, 209, 209, 207, 204, 201, 197, 193, 188, 183, 179, 174, 170, 166, 163, 161, 160, 159, 159, 160, 161, 162, 164, 166, 168, 169, 171, 171, 171, 170, 169, 167, 163, 159, 155, 150, 144, 139, 133, 128, 122, 117, 113, 110, 107, 105, 103, 103, 103, 103, 104, 104, 105, 105, 105, 103, 101, 97, 92, 86, 78, 68, 58, 45, 32, 18, 3, -11, -26, -41, -55, -68, -79, -88, -95, -100, -102, -102, -99, -93, -85, -75, -62, -48, -33, -16, 0, 16, 33, 48, 62, 75, 85, 93, 99, 102, 102, 100, 95, 88, 79, 68, 55, 41, 26, 11, -3, -18, -32, -45, -58, -68, -78, -86, -92, -97, -101, -103, -105, -105, -105, -104, -104, -103, -103, -103, -103, -105, -107, -110, -113, -117, -122, -128, -133, -139, -144, -150, -155, -159, -163, -167, -169, -170, -171, -171, -171, -169, -168, -166, -164, -162, -161, -160, -159, -159, -160, -161, -163, -166, -170, -174, -179, -183, -188, -193, -197, -201, -204, -207, -209, -209, -209, -208, -206, -203, -200, -196, -192, -189, -186, -183, -182, -182, -183, -186, -190, -196, -204, -213, -224, -236, -249, -262, -275, -288, -299, -310, -318, -324, -327, -327, -323, -316, -304, -288, -269, -245, -218, -187, -153, -117, -79, -40, }; #define BEEP_SRATE 22050 /* 22050 Hz sample rate */ #define BEEP_BUFLEN 512 #define BEEP_VOLUME 15 /* 0 - 100 */ |
65b29f503 [ALSA] Remove xxx... |
83 84 |
static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type, unsigned int code, int hz) |
1da177e4c Linux-2.6.12-rc2 |
85 |
{ |
65b29f503 [ALSA] Remove xxx... |
86 87 |
struct snd_pmac *chip; struct pmac_beep *beep; |
1da177e4c Linux-2.6.12-rc2 |
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
unsigned long flags; int beep_speed = 0; int srate; int period, ncycles, nsamples; int i, j, f; short *p; if (type != EV_SND) return -1; switch (code) { case SND_BELL: if (hz) hz = 1000; case SND_TONE: break; default: return -1; } |
1e2831db0 Input: ppc-beep -... |
103 |
chip = input_get_drvdata(dev); |
1da177e4c Linux-2.6.12-rc2 |
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
if (! chip || (beep = chip->beep) == NULL) return -1; if (! hz) { spin_lock_irqsave(&chip->reg_lock, flags); if (beep->running) snd_pmac_beep_stop(chip); spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } beep_speed = snd_pmac_rate_index(chip, &chip->playback, BEEP_SRATE); srate = chip->freq_table[beep_speed]; if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) hz = 1000; spin_lock_irqsave(&chip->reg_lock, flags); if (chip->playback.running || chip->capture.running || beep->running) { spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } beep->running = 1; spin_unlock_irqrestore(&chip->reg_lock, flags); if (hz == beep->hz && beep->volume == beep->volume_play) { nsamples = beep->nsamples; } else { period = srate * 256 / hz; /* fixed point */ ncycles = BEEP_BUFLEN * 256 / period; nsamples = (period * ncycles) >> 8; f = ncycles * 65536 / nsamples; j = 0; p = beep->buf; for (i = 0; i < nsamples; ++i, p += 2) { p[0] = p[1] = beep_wform[j >> 8] * beep->volume; j = (j + f) & 0xffff; } beep->hz = hz; beep->volume_play = beep->volume; beep->nsamples = nsamples; } spin_lock_irqsave(&chip->reg_lock, flags); snd_pmac_beep_dma_start(chip, beep->nsamples * 4, beep->addr, beep_speed); spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } /* * beep volume mixer */ |
65b29f503 [ALSA] Remove xxx... |
156 157 |
static int snd_pmac_info_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1da177e4c Linux-2.6.12-rc2 |
158 159 160 161 162 163 164 |
{ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 100; return 0; } |
65b29f503 [ALSA] Remove xxx... |
165 166 |
static int snd_pmac_get_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1da177e4c Linux-2.6.12-rc2 |
167 |
{ |
65b29f503 [ALSA] Remove xxx... |
168 |
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
5e246b850 ALSA: Kill snd_as... |
169 170 |
if (snd_BUG_ON(!chip->beep)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
171 172 173 |
ucontrol->value.integer.value[0] = chip->beep->volume; return 0; } |
65b29f503 [ALSA] Remove xxx... |
174 175 |
static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1da177e4c Linux-2.6.12-rc2 |
176 |
{ |
65b29f503 [ALSA] Remove xxx... |
177 |
struct snd_pmac *chip = snd_kcontrol_chip(kcontrol); |
d4079ac49 [ALSA] powermac -... |
178 |
unsigned int oval, nval; |
5e246b850 ALSA: Kill snd_as... |
179 180 |
if (snd_BUG_ON(!chip->beep)) return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
181 |
oval = chip->beep->volume; |
d4079ac49 [ALSA] powermac -... |
182 183 184 185 |
nval = ucontrol->value.integer.value[0]; if (nval > 100) return -EINVAL; chip->beep->volume = nval; |
1da177e4c Linux-2.6.12-rc2 |
186 187 |
return oval != chip->beep->volume; } |
905e46acd ALSA: declare snd... |
188 |
static const struct snd_kcontrol_new snd_pmac_beep_mixer = { |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 192 193 194 195 196 |
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Beep Playback Volume", .info = snd_pmac_info_beep, .get = snd_pmac_get_beep, .put = snd_pmac_put_beep, }; /* Initialize beep stuff */ |
15afafc25 ALSA: ppc: remove... |
197 |
int snd_pmac_attach_beep(struct snd_pmac *chip) |
1da177e4c Linux-2.6.12-rc2 |
198 |
{ |
65b29f503 [ALSA] Remove xxx... |
199 |
struct pmac_beep *beep; |
5ebdcbc2f [PATCH] Input: co... |
200 |
struct input_dev *input_dev; |
f03d68fe3 [ALSA] ppc-beep -... |
201 |
struct snd_kcontrol *beep_ctl; |
5ebdcbc2f [PATCH] Input: co... |
202 203 |
void *dmabuf; int err = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
204 |
|
5ebdcbc2f [PATCH] Input: co... |
205 |
beep = kzalloc(sizeof(*beep), GFP_KERNEL); |
f03d68fe3 [ALSA] ppc-beep -... |
206 207 |
if (! beep) return -ENOMEM; |
5ebdcbc2f [PATCH] Input: co... |
208 209 210 |
dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, &beep->addr, GFP_KERNEL); input_dev = input_allocate_device(); |
f03d68fe3 [ALSA] ppc-beep -... |
211 212 |
if (! dmabuf || ! input_dev) goto fail1; |
1da177e4c Linux-2.6.12-rc2 |
213 214 |
/* FIXME: set more better values */ |
5ebdcbc2f [PATCH] Input: co... |
215 216 217 218 219 220 |
input_dev->name = "PowerMac Beep"; input_dev->phys = "powermac/beep"; input_dev->id.bustype = BUS_ADB; input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; |
7b19ada2e get rid of input ... |
221 222 |
input_dev->evbit[0] = BIT_MASK(EV_SND); input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); |
5ebdcbc2f [PATCH] Input: co... |
223 |
input_dev->event = snd_pmac_beep_event; |
1e2831db0 Input: ppc-beep -... |
224 225 |
input_dev->dev.parent = &chip->pdev->dev; input_set_drvdata(input_dev, chip); |
1da177e4c Linux-2.6.12-rc2 |
226 |
|
5ebdcbc2f [PATCH] Input: co... |
227 228 |
beep->dev = input_dev; beep->buf = dmabuf; |
1da177e4c Linux-2.6.12-rc2 |
229 230 |
beep->volume = BEEP_VOLUME; beep->running = 0; |
5ebdcbc2f [PATCH] Input: co... |
231 |
|
f03d68fe3 [ALSA] ppc-beep -... |
232 233 |
beep_ctl = snd_ctl_new1(&snd_pmac_beep_mixer, chip); err = snd_ctl_add(chip->card, beep_ctl); |
5ebdcbc2f [PATCH] Input: co... |
234 |
if (err < 0) |
f03d68fe3 [ALSA] ppc-beep -... |
235 |
goto fail1; |
1e2831db0 Input: ppc-beep -... |
236 237 |
chip->beep = beep; |
1da177e4c Linux-2.6.12-rc2 |
238 |
|
f03d68fe3 [ALSA] ppc-beep -... |
239 240 241 242 243 244 245 246 247 248 249 |
err = input_register_device(beep->dev); if (err) goto fail2; return 0; fail2: snd_ctl_remove(chip->card, beep_ctl); fail1: input_free_device(input_dev); if (dmabuf) dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, dmabuf, beep->addr); |
5ebdcbc2f [PATCH] Input: co... |
250 251 |
kfree(beep); return err; |
1da177e4c Linux-2.6.12-rc2 |
252 |
} |
65b29f503 [ALSA] Remove xxx... |
253 |
void snd_pmac_detach_beep(struct snd_pmac *chip) |
1da177e4c Linux-2.6.12-rc2 |
254 255 |
{ if (chip->beep) { |
5ebdcbc2f [PATCH] Input: co... |
256 |
input_unregister_device(chip->beep->dev); |
7bbd82775 [PATCH] ppc64: ve... |
257 258 |
dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, chip->beep->buf, chip->beep->addr); |
1da177e4c Linux-2.6.12-rc2 |
259 260 261 262 |
kfree(chip->beep); chip->beep = NULL; } } |