0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/io.h>
0009 #include <asm/irq.h>
0010 #include <linux/init.h>
0011 #include <linux/slab.h>
0012 #include <linux/input.h>
0013 #include <linux/pci.h>
0014 #include <linux/dma-mapping.h>
0015 #include <sound/core.h>
0016 #include <sound/control.h>
0017 #include "pmac.h"
0018
0019 struct pmac_beep {
0020 int running;
0021 int volume;
0022 int volume_play;
0023 int hz;
0024 int nsamples;
0025 short *buf;
0026 dma_addr_t addr;
0027 struct input_dev *dev;
0028 };
0029
0030
0031
0032
0033 void snd_pmac_beep_stop(struct snd_pmac *chip)
0034 {
0035 struct pmac_beep *beep = chip->beep;
0036 if (beep && beep->running) {
0037 beep->running = 0;
0038 snd_pmac_beep_dma_stop(chip);
0039 }
0040 }
0041
0042
0043
0044
0045
0046
0047 static const short beep_wform[256] = {
0048 0, 40, 79, 117, 153, 187, 218, 245,
0049 269, 288, 304, 316, 323, 327, 327, 324,
0050 318, 310, 299, 288, 275, 262, 249, 236,
0051 224, 213, 204, 196, 190, 186, 183, 182,
0052 182, 183, 186, 189, 192, 196, 200, 203,
0053 206, 208, 209, 209, 209, 207, 204, 201,
0054 197, 193, 188, 183, 179, 174, 170, 166,
0055 163, 161, 160, 159, 159, 160, 161, 162,
0056 164, 166, 168, 169, 171, 171, 171, 170,
0057 169, 167, 163, 159, 155, 150, 144, 139,
0058 133, 128, 122, 117, 113, 110, 107, 105,
0059 103, 103, 103, 103, 104, 104, 105, 105,
0060 105, 103, 101, 97, 92, 86, 78, 68,
0061 58, 45, 32, 18, 3, -11, -26, -41,
0062 -55, -68, -79, -88, -95, -100, -102, -102,
0063 -99, -93, -85, -75, -62, -48, -33, -16,
0064 0, 16, 33, 48, 62, 75, 85, 93,
0065 99, 102, 102, 100, 95, 88, 79, 68,
0066 55, 41, 26, 11, -3, -18, -32, -45,
0067 -58, -68, -78, -86, -92, -97, -101, -103,
0068 -105, -105, -105, -104, -104, -103, -103, -103,
0069 -103, -105, -107, -110, -113, -117, -122, -128,
0070 -133, -139, -144, -150, -155, -159, -163, -167,
0071 -169, -170, -171, -171, -171, -169, -168, -166,
0072 -164, -162, -161, -160, -159, -159, -160, -161,
0073 -163, -166, -170, -174, -179, -183, -188, -193,
0074 -197, -201, -204, -207, -209, -209, -209, -208,
0075 -206, -203, -200, -196, -192, -189, -186, -183,
0076 -182, -182, -183, -186, -190, -196, -204, -213,
0077 -224, -236, -249, -262, -275, -288, -299, -310,
0078 -318, -324, -327, -327, -323, -316, -304, -288,
0079 -269, -245, -218, -187, -153, -117, -79, -40,
0080 };
0081
0082 #define BEEP_SRATE 22050
0083 #define BEEP_BUFLEN 512
0084 #define BEEP_VOLUME 15
0085
0086 static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
0087 unsigned int code, int hz)
0088 {
0089 struct snd_pmac *chip;
0090 struct pmac_beep *beep;
0091 unsigned long flags;
0092 int beep_speed = 0;
0093 int srate;
0094 int period, ncycles, nsamples;
0095 int i, j, f;
0096 short *p;
0097
0098 if (type != EV_SND)
0099 return -1;
0100
0101 switch (code) {
0102 case SND_BELL: if (hz) hz = 1000; break;
0103 case SND_TONE: break;
0104 default: return -1;
0105 }
0106
0107 chip = input_get_drvdata(dev);
0108 if (!chip)
0109 return -1;
0110 beep = chip->beep;
0111 if (!beep)
0112 return -1;
0113
0114 if (! hz) {
0115 spin_lock_irqsave(&chip->reg_lock, flags);
0116 if (beep->running)
0117 snd_pmac_beep_stop(chip);
0118 spin_unlock_irqrestore(&chip->reg_lock, flags);
0119 return 0;
0120 }
0121
0122 beep_speed = snd_pmac_rate_index(chip, &chip->playback, BEEP_SRATE);
0123 srate = chip->freq_table[beep_speed];
0124
0125 if (hz <= srate / BEEP_BUFLEN || hz > srate / 2)
0126 hz = 1000;
0127
0128 spin_lock_irqsave(&chip->reg_lock, flags);
0129 if (chip->playback.running || chip->capture.running || beep->running) {
0130 spin_unlock_irqrestore(&chip->reg_lock, flags);
0131 return 0;
0132 }
0133 beep->running = 1;
0134 spin_unlock_irqrestore(&chip->reg_lock, flags);
0135
0136 if (hz == beep->hz && beep->volume == beep->volume_play) {
0137 nsamples = beep->nsamples;
0138 } else {
0139 period = srate * 256 / hz;
0140 ncycles = BEEP_BUFLEN * 256 / period;
0141 nsamples = (period * ncycles) >> 8;
0142 f = ncycles * 65536 / nsamples;
0143 j = 0;
0144 p = beep->buf;
0145 for (i = 0; i < nsamples; ++i, p += 2) {
0146 p[0] = p[1] = beep_wform[j >> 8] * beep->volume;
0147 j = (j + f) & 0xffff;
0148 }
0149 beep->hz = hz;
0150 beep->volume_play = beep->volume;
0151 beep->nsamples = nsamples;
0152 }
0153
0154 spin_lock_irqsave(&chip->reg_lock, flags);
0155 snd_pmac_beep_dma_start(chip, beep->nsamples * 4, beep->addr, beep_speed);
0156 spin_unlock_irqrestore(&chip->reg_lock, flags);
0157 return 0;
0158 }
0159
0160
0161
0162
0163
0164 static int snd_pmac_info_beep(struct snd_kcontrol *kcontrol,
0165 struct snd_ctl_elem_info *uinfo)
0166 {
0167 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0168 uinfo->count = 1;
0169 uinfo->value.integer.min = 0;
0170 uinfo->value.integer.max = 100;
0171 return 0;
0172 }
0173
0174 static int snd_pmac_get_beep(struct snd_kcontrol *kcontrol,
0175 struct snd_ctl_elem_value *ucontrol)
0176 {
0177 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0178 if (snd_BUG_ON(!chip->beep))
0179 return -ENXIO;
0180 ucontrol->value.integer.value[0] = chip->beep->volume;
0181 return 0;
0182 }
0183
0184 static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol,
0185 struct snd_ctl_elem_value *ucontrol)
0186 {
0187 struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
0188 unsigned int oval, nval;
0189 if (snd_BUG_ON(!chip->beep))
0190 return -ENXIO;
0191 oval = chip->beep->volume;
0192 nval = ucontrol->value.integer.value[0];
0193 if (nval > 100)
0194 return -EINVAL;
0195 chip->beep->volume = nval;
0196 return oval != chip->beep->volume;
0197 }
0198
0199 static const struct snd_kcontrol_new snd_pmac_beep_mixer = {
0200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0201 .name = "Beep Playback Volume",
0202 .info = snd_pmac_info_beep,
0203 .get = snd_pmac_get_beep,
0204 .put = snd_pmac_put_beep,
0205 };
0206
0207
0208 int snd_pmac_attach_beep(struct snd_pmac *chip)
0209 {
0210 struct pmac_beep *beep;
0211 struct input_dev *input_dev;
0212 struct snd_kcontrol *beep_ctl;
0213 void *dmabuf;
0214 int err = -ENOMEM;
0215
0216 beep = kzalloc(sizeof(*beep), GFP_KERNEL);
0217 if (! beep)
0218 return -ENOMEM;
0219 dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
0220 &beep->addr, GFP_KERNEL);
0221 input_dev = input_allocate_device();
0222 if (! dmabuf || ! input_dev)
0223 goto fail1;
0224
0225
0226 input_dev->name = "PowerMac Beep";
0227 input_dev->phys = "powermac/beep";
0228 input_dev->id.bustype = BUS_ADB;
0229 input_dev->id.vendor = 0x001f;
0230 input_dev->id.product = 0x0001;
0231 input_dev->id.version = 0x0100;
0232
0233 input_dev->evbit[0] = BIT_MASK(EV_SND);
0234 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
0235 input_dev->event = snd_pmac_beep_event;
0236 input_dev->dev.parent = &chip->pdev->dev;
0237 input_set_drvdata(input_dev, chip);
0238
0239 beep->dev = input_dev;
0240 beep->buf = dmabuf;
0241 beep->volume = BEEP_VOLUME;
0242 beep->running = 0;
0243
0244 beep_ctl = snd_ctl_new1(&snd_pmac_beep_mixer, chip);
0245 err = snd_ctl_add(chip->card, beep_ctl);
0246 if (err < 0)
0247 goto fail1;
0248
0249 chip->beep = beep;
0250
0251 err = input_register_device(beep->dev);
0252 if (err)
0253 goto fail2;
0254
0255 return 0;
0256
0257 fail2: snd_ctl_remove(chip->card, beep_ctl);
0258 fail1: input_free_device(input_dev);
0259 if (dmabuf)
0260 dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
0261 dmabuf, beep->addr);
0262 kfree(beep);
0263 return err;
0264 }
0265
0266 void snd_pmac_detach_beep(struct snd_pmac *chip)
0267 {
0268 if (chip->beep) {
0269 input_unregister_device(chip->beep->dev);
0270 dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
0271 chip->beep->buf, chip->beep->addr);
0272 kfree(chip->beep);
0273 chip->beep = NULL;
0274 }
0275 }