]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-2.6.7-8.24-08-04.patch
- obsolete
[packages/kernel.git] / kernel-2.6.7-8.24-08-04.patch
CommitLineData
06f6246e 1diff -urN linux/drivers/bluetooth/hci_usb.c linux.new/drivers/bluetooth/hci_usb.c
2--- linux/drivers/bluetooth/hci_usb.c 2004-08-23 18:46:43.000000000 +0200
3+++ linux.new/drivers/bluetooth/hci_usb.c 2004-08-23 19:22:37.000000000 +0200
4@@ -887,8 +887,12 @@
5
6 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
7 case USB_ENDPOINT_XFER_ISOC:
8- if (ep->desc.wMaxPacketSize < size ||
9- uif->desc.bAlternateSetting > 2)
10+ /* Use only the 9 byte
11+ "One voice channel with 8 bit encoding"
12+ endpoint until there is support for changing
13+ the endpoint dynamically. See
14+ Bluetooth 1.1 Part H:2, section 2.1 */
15+ if (ep->desc.wMaxPacketSize != 9)
16 break;
17 size = ep->desc.wMaxPacketSize;
18
19diff -urN linux/include/sound/asound.h linux.new/include/sound/asound.h
20--- linux/include/sound/asound.h 2004-08-23 18:46:43.000000000 +0200
21+++ linux.new/include/sound/asound.h 2004-08-23 19:22:37.000000000 +0200
22@@ -108,9 +108,10 @@
23 SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */
24 SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */
25 SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */
26+ SNDRV_HWDEP_IFACE_BT_SCO, /* Bluetooth SCO Headset */
27
28 /* Don't forget to change the following: */
29- SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE,
30+ SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_BT_SCO,
31 };
32
33 struct sndrv_hwdep_info {
34@@ -135,7 +136,7 @@
35 struct sndrv_hwdep_dsp_image {
36 unsigned int index; /* W: DSP index */
37 unsigned char name[64]; /* W: ID (e.g. file name) */
38- unsigned char __user *image; /* W: binary image */
39+ unsigned char __user *image;/* W: binary image */
40 size_t length; /* W: size of image in bytes */
41 unsigned long driver_data; /* W: driver-specific data */
42 };
43diff -urN linux/include/sound/btsco.h linux.new/include/sound/btsco.h
44--- linux/include/sound/btsco.h 1970-01-01 01:00:00.000000000 +0100
45+++ linux.new/include/sound/btsco.h 2004-07-19 19:56:20.000000000 +0200
46@@ -0,0 +1,5 @@
47+#ifndef __SOUND_BT_SCO_H
48+#define __SOUND_BT_SCO_H
49+
50+#define SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET _IOW ('H', 0x10, int)
51+#endif /* __SOUND_BT_SCO_H */
52diff -urN linux/include/sound/sndmagic.h linux.new/include/sound/sndmagic.h
53--- linux/include/sound/sndmagic.h 2004-08-23 18:46:43.000000000 +0200
54+++ linux.new/include/sound/sndmagic.h 2004-08-23 19:22:37.000000000 +0200
55@@ -201,6 +201,8 @@
56 #define snd_card_harmony_t_magic 0xa15a4300
57 #define bt87x_t_magic 0xa15a4400
58 #define pdacf_t_magic 0xa15a4500
59+#define snd_card_bt_sco_t_magic 0xa15a4600
60+#define snd_card_bt_sco_pcm_t_magic 0xa15a4601
61 #define vortex_t_magic 0xa15a4601
62 #define atiixp_t_magic 0xa15a4701
63 #define amd7930_t_magic 0xa15a4801
64diff -urN linux/sound/bluetooth/btsco.c linux.new/sound/bluetooth/btsco.c
65--- linux/sound/bluetooth/btsco.c 1970-01-01 01:00:00.000000000 +0100
66+++ linux.new/sound/bluetooth/btsco.c 2004-07-19 19:56:20.000000000 +0200
67@@ -0,0 +1,1023 @@
68+/*
69+ * Bluetooth SCO soundcard
70+ * Copyright (c) 2003, 2004 by Jonathan Paisley <jp@dcs.gla.ac.uk>
71+ *
72+ * Based on dummy.c which is
73+ * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
74+ *
75+ * This program is free software; you can redistribute it and/or modify
76+ * it under the terms of the GNU General Public License as published by
77+ * the Free Software Foundation; either version 2 of the License, or
78+ * (at your option) any later version.
79+ *
80+ * This program is distributed in the hope that it will be useful,
81+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
82+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
83+ * GNU General Public License for more details.
84+ *
85+ * You should have received a copy of the GNU General Public License
86+ * along with this program; if not, write to the Free Software
87+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
88+ *
89+ */
90+
91+#define chip_t snd_card_bt_sco_t
92+
93+#include <sound/driver.h>
94+#include <linux/version.h>
95+#include <linux/init.h>
96+#include <linux/jiffies.h>
97+#include <linux/slab.h>
98+#include <linux/time.h>
99+#include <linux/wait.h>
100+#include <linux/socket.h>
101+#include <linux/file.h>
102+#include <linux/completion.h>
103+#include <linux/smp_lock.h>
104+#include <net/sock.h>
105+#include <net/bluetooth/bluetooth.h>
106+
107+#include <sound/btsco.h>
108+#include <sound/core.h>
109+#include <sound/control.h>
110+#include <sound/pcm.h>
111+#include <sound/rawmidi.h>
112+#include <sound/hwdep.h>
113+#define SNDRV_GET_ID
114+#include <sound/initval.h>
115+
116+MODULE_AUTHOR("Jonathan Paisley <jp@dcs.gla.ac.uk>");
117+MODULE_DESCRIPTION("Bluetooth SCO Headset Soundcard");
118+MODULE_LICENSE("GPL");
119+MODULE_CLASSES("{sound}");
120+MODULE_DEVICES("{{ALSA,Bluetooth SCO Soundcard}}");
121+
122+static char *mod_revision = "$Revision$";
123+
124+#undef dprintk
125+#if 1
126+#define dprintk(fmt...) printk(KERN_INFO "snd-bt-sco: " fmt)
127+#else
128+#define dprintk(fmt...) do {} while(0)
129+#endif
130+
131+#define MAX_BUFFER_SIZE (32*1024)
132+
133+#define MIXER_ADDR_MASTER 0
134+#define MIXER_ADDR_MIC 1
135+#define MIXER_ADDR_LAST 1
136+
137+#define MIXER_MASK_MASTER 1
138+#define MIXER_MASK_MIC 2
139+
140+#define MIXER_MIN_VOLUME 1
141+#define MIXER_MAX_VOLUME 15
142+
143+struct snd_card_bt_sco_pcm;
144+
145+typedef struct snd_card_bt_sco {
146+ snd_card_t *card;
147+ spinlock_t mixer_lock;
148+ int mixer_volume[MIXER_ADDR_LAST + 1];
149+ snd_kcontrol_t *mixer_controls[MIXER_ADDR_LAST + 2]; /* also loopback */
150+ volatile int loopback;
151+
152+ spinlock_t mixer_changed_lock;
153+ volatile int mixer_changed;
154+ wait_queue_head_t hwdep_wait;
155+
156+ int thread_pid;
157+ struct completion thread_done;
158+
159+ volatile int thread_exit;
160+ struct semaphore thread_sem;
161+
162+ volatile struct socket *sco_sock;
163+ struct semaphore sock_sem;
164+ wait_queue_head_t wait;
165+
166+ struct semaphore playback_sem;
167+ struct snd_card_bt_sco_pcm *playback;
168+ struct semaphore capture_sem;
169+ struct snd_card_bt_sco_pcm *capture;
170+} snd_card_bt_sco_t;
171+
172+typedef struct snd_card_bt_sco_pcm {
173+ snd_card_bt_sco_t *bt_sco;
174+ spinlock_t lock;
175+ unsigned int pcm_size;
176+ unsigned int pcm_count;
177+ unsigned int pcm_bps; /* bytes per second */
178+ unsigned int pcm_irq_pos; /* IRQ position */
179+ unsigned int pcm_buf_pos; /* position in buffer */
180+ snd_pcm_substream_t *substream;
181+} snd_card_bt_sco_pcm_t;
182+
183+static snd_card_t *snd_bt_sco_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
184+
185+static int snd_card_bt_sco_playback_trigger(snd_pcm_substream_t *
186+ substream, int cmd)
187+{
188+ snd_pcm_runtime_t *runtime = substream->runtime;
189+ snd_card_bt_sco_pcm_t *bspcm =
190+ snd_magic_cast(snd_card_bt_sco_pcm_t, runtime->private_data,
191+ return -ENXIO);
192+ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream);
193+
194+ dprintk("playback_trigger %d\n", cmd);
195+
196+ if (cmd == SNDRV_PCM_TRIGGER_START) {
197+ bt_sco->playback = bspcm;
198+ dprintk("setting playback to bspcm\n");
199+ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
200+ bt_sco->playback = NULL;
201+ dprintk("setting playback to NULL\n");
202+ } else {
203+ return -EINVAL;
204+ }
205+ return 0;
206+}
207+
208+static int snd_card_bt_sco_capture_trigger(snd_pcm_substream_t *
209+ substream, int cmd)
210+{
211+ snd_pcm_runtime_t *runtime = substream->runtime;
212+ snd_card_bt_sco_pcm_t *bspcm =
213+ snd_magic_cast(snd_card_bt_sco_pcm_t, runtime->private_data,
214+ return -ENXIO);
215+ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream);
216+
217+ dprintk("capture_trigger %d\n", cmd);
218+
219+ if (cmd == SNDRV_PCM_TRIGGER_START) {
220+ bt_sco->capture = bspcm;
221+ dprintk("setting capture to bspcm\n");
222+ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
223+ bt_sco->capture = NULL;
224+ dprintk("setting capture to NULL\n");
225+ } else {
226+ return -EINVAL;
227+ }
228+ return 0;
229+}
230+
231+static int snd_card_bt_sco_pcm_prepare(snd_pcm_substream_t * substream)
232+{
233+ snd_pcm_runtime_t *runtime = substream->runtime;
234+ snd_card_bt_sco_pcm_t *bspcm =
235+ snd_magic_cast(snd_card_bt_sco_pcm_t, runtime->private_data,
236+ return -ENXIO);
237+ unsigned int bps;
238+
239+ bps = runtime->rate * runtime->channels;
240+ bps *= snd_pcm_format_width(runtime->format);
241+ bps /= 8;
242+ if (bps <= 0)
243+ return -EINVAL;
244+ bspcm->pcm_bps = bps;
245+ bspcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
246+ bspcm->pcm_count = snd_pcm_lib_period_bytes(substream);
247+ bspcm->pcm_irq_pos = 0;
248+ bspcm->pcm_buf_pos = 0;
249+ dprintk(
250+ "prepare ok bps: %d size: %d count: %d\n",
251+ bspcm->pcm_bps, bspcm->pcm_size,
252+ bspcm->pcm_count);
253+ return 0;
254+}
255+
256+static int snd_card_bt_sco_playback_prepare(snd_pcm_substream_t *
257+ substream)
258+{
259+ return snd_card_bt_sco_pcm_prepare(substream);
260+}
261+
262+static int snd_card_bt_sco_capture_prepare(snd_pcm_substream_t *
263+ substream)
264+{
265+ dprintk("capture_prepare\n");
266+ return snd_card_bt_sco_pcm_prepare(substream);
267+}
268+
269+static void snd_card_bt_sco_pcm_receive(snd_card_bt_sco_pcm_t * bspcm,
270+ unsigned char *data,
271+ unsigned int len)
272+{
273+ unsigned long flags;
274+ unsigned int oldptr;
275+
276+ spin_lock_irqsave(&bspcm->lock, flags);
277+ oldptr = bspcm->pcm_buf_pos;
278+ bspcm->pcm_irq_pos += len;
279+ bspcm->pcm_buf_pos += len;
280+ bspcm->pcm_buf_pos %= bspcm->pcm_size;
281+ spin_unlock_irqrestore(&bspcm->lock, flags);
282+ /* copy a data chunk */
283+ if (oldptr + len > bspcm->pcm_size) {
284+ unsigned int cnt = bspcm->pcm_size - oldptr;
285+ memcpy(bspcm->substream->runtime->dma_area + oldptr, data,
286+ cnt);
287+ memcpy(bspcm->substream->runtime->dma_area, data + cnt,
288+ len - cnt);
289+ } else {
290+ memcpy(bspcm->substream->runtime->dma_area + oldptr, data,
291+ len);
292+ }
293+ /* update the pointer, call callback if necessary */
294+ spin_lock_irqsave(&bspcm->lock, flags);
295+ if (bspcm->pcm_irq_pos >= bspcm->pcm_count) {
296+ bspcm->pcm_irq_pos %= bspcm->pcm_count;
297+ spin_unlock_irqrestore(&bspcm->lock, flags);
298+ snd_pcm_period_elapsed(bspcm->substream);
299+ } else
300+ spin_unlock_irqrestore(&bspcm->lock, flags);
301+
302+}
303+
304+static void snd_card_bt_sco_pcm_send(snd_card_bt_sco_pcm_t * bspcm,
305+ unsigned char *data,
306+ unsigned int len)
307+{
308+ unsigned long flags;
309+ unsigned int oldptr;
310+
311+ spin_lock_irqsave(&bspcm->lock, flags);
312+ oldptr = bspcm->pcm_buf_pos;
313+ bspcm->pcm_irq_pos += len;
314+ bspcm->pcm_buf_pos += len;
315+ bspcm->pcm_buf_pos %= bspcm->pcm_size;
316+ spin_unlock_irqrestore(&bspcm->lock, flags);
317+ /* copy a data chunk */
318+ if (oldptr + len > bspcm->pcm_size) {
319+ unsigned int cnt = bspcm->pcm_size - oldptr;
320+ memcpy(data, bspcm->substream->runtime->dma_area + oldptr,
321+ cnt);
322+ memcpy(data + cnt, bspcm->substream->runtime->dma_area,
323+ len - cnt);
324+ } else {
325+ memcpy(data, bspcm->substream->runtime->dma_area + oldptr,
326+ len);
327+ }
328+ /* update the pointer, call callback if necessary */
329+ spin_lock_irqsave(&bspcm->lock, flags);
330+ if (bspcm->pcm_irq_pos >= bspcm->pcm_count) {
331+ bspcm->pcm_irq_pos %= bspcm->pcm_count;
332+ spin_unlock_irqrestore(&bspcm->lock, flags);
333+ snd_pcm_period_elapsed(bspcm->substream);
334+ } else
335+ spin_unlock_irqrestore(&bspcm->lock, flags);
336+}
337+
338+static snd_pcm_uframes_t
339+snd_card_bt_sco_playback_pointer(snd_pcm_substream_t * substream)
340+{
341+ snd_pcm_runtime_t *runtime = substream->runtime;
342+ snd_card_bt_sco_pcm_t *bspcm =
343+ snd_magic_cast(snd_card_bt_sco_pcm_t, runtime->private_data,
344+ return -ENXIO);
345+
346+ return bytes_to_frames(runtime, bspcm->pcm_buf_pos);
347+}
348+
349+static snd_pcm_uframes_t
350+snd_card_bt_sco_capture_pointer(snd_pcm_substream_t * substream)
351+{
352+ snd_pcm_runtime_t *runtime = substream->runtime;
353+ snd_card_bt_sco_pcm_t *bspcm =
354+ snd_magic_cast(snd_card_bt_sco_pcm_t, runtime->private_data,
355+ return -ENXIO);
356+
357+ return bytes_to_frames(runtime, bspcm->pcm_buf_pos);
358+}
359+
360+static snd_pcm_hardware_t snd_card_bt_sco_playback = {
361+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
362+ SNDRV_PCM_INFO_MMAP_VALID),
363+ .formats = SNDRV_PCM_FMTBIT_S8 /* | SNDRV_PCM_FMTBIT_S16_LE */ ,
364+ .rates = SNDRV_PCM_RATE_8000,
365+ .rate_min = 8000,
366+ .rate_max = 8000,
367+ .channels_min = 1,
368+ .channels_max = 1,
369+ .buffer_bytes_max = MAX_BUFFER_SIZE,
370+ .period_bytes_min = 24,
371+ .period_bytes_max = MAX_BUFFER_SIZE,
372+ .periods_min = 1,
373+ .periods_max = 4*8000/24,
374+ .fifo_size = 0,
375+};
376+
377+static snd_pcm_hardware_t snd_card_bt_sco_capture = {
378+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
379+ SNDRV_PCM_INFO_MMAP_VALID),
380+ .formats = SNDRV_PCM_FMTBIT_S8 /* | SNDRV_PCM_FMTBIT_S16_LE */ ,
381+ .rates = SNDRV_PCM_RATE_8000,
382+ .rate_min = 8000,
383+ .rate_max = 8000,
384+ .channels_min = 1,
385+ .channels_max = 1,
386+ .buffer_bytes_max = MAX_BUFFER_SIZE,
387+ .period_bytes_min = 24,
388+ .period_bytes_max = MAX_BUFFER_SIZE,
389+ .periods_min = 1,
390+ .periods_max = 4*8000/24,
391+ .fifo_size = 0,
392+};
393+
394+static void snd_card_bt_sco_runtime_free(snd_pcm_runtime_t * runtime)
395+{
396+ snd_card_bt_sco_pcm_t *bspcm =
397+ snd_magic_cast(snd_card_bt_sco_pcm_t, runtime->private_data,
398+ return);
399+ snd_magic_kfree(bspcm);
400+}
401+
402+static int snd_card_bt_sco_playback_open(snd_pcm_substream_t *
403+ substream)
404+{
405+ snd_pcm_runtime_t *runtime = substream->runtime;
406+ snd_card_bt_sco_pcm_t *bspcm;
407+
408+ dprintk("playback_open\n");
409+
410+ bspcm = snd_magic_kcalloc(snd_card_bt_sco_pcm_t, 0, GFP_KERNEL);
411+ if (bspcm == NULL)
412+ return -ENOMEM;
413+ if ((runtime->dma_area =
414+ snd_malloc_pages_fallback(MAX_BUFFER_SIZE, GFP_KERNEL,
415+ &runtime->dma_bytes)) == NULL) {
416+ snd_magic_kfree(bspcm);
417+ return -ENOMEM;
418+ }
419+ spin_lock_init(&bspcm->lock);
420+ bspcm->substream = substream;
421+ runtime->private_data = bspcm;
422+ runtime->private_free = snd_card_bt_sco_runtime_free;
423+ runtime->hw = snd_card_bt_sco_playback;
424+ return 0;
425+}
426+
427+static int snd_card_bt_sco_capture_open(snd_pcm_substream_t * substream)
428+{
429+ snd_pcm_runtime_t *runtime = substream->runtime;
430+ snd_card_bt_sco_pcm_t *bspcm;
431+
432+ dprintk("capture_open\n");
433+
434+ bspcm = snd_magic_kcalloc(snd_card_bt_sco_pcm_t, 0, GFP_KERNEL);
435+ if (bspcm == NULL)
436+ return -ENOMEM;
437+ if ((runtime->dma_area =
438+ snd_malloc_pages_fallback(MAX_BUFFER_SIZE, GFP_KERNEL,
439+ &runtime->dma_bytes)) == NULL) {
440+ snd_magic_kfree(bspcm);
441+ return -ENOMEM;
442+ }
443+ memset(runtime->dma_area, 0, runtime->dma_bytes);
444+ spin_lock_init(&bspcm->lock);
445+ bspcm->substream = substream;
446+ runtime->private_data = bspcm;
447+ runtime->private_free = snd_card_bt_sco_runtime_free;
448+ runtime->hw = snd_card_bt_sco_capture;
449+ return 0;
450+}
451+
452+static int snd_card_bt_sco_playback_close(snd_pcm_substream_t *
453+ substream)
454+{
455+ snd_pcm_runtime_t *runtime = substream->runtime;
456+ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream);
457+
458+ snd_assert(bt_sco->playback == NULL, ;);
459+
460+ /* Ensure any references to this in our thread have finished */
461+ down(&bt_sco->playback_sem);
462+ up(&bt_sco->playback_sem);
463+
464+ snd_free_pages(runtime->dma_area, runtime->dma_bytes);
465+ return 0;
466+}
467+
468+static int snd_card_bt_sco_capture_close(snd_pcm_substream_t *
469+ substream)
470+{
471+ snd_pcm_runtime_t *runtime = substream->runtime;
472+ struct snd_card_bt_sco *bt_sco = (struct snd_card_bt_sco *) substream->private_data;
473+
474+ snd_assert(bt_sco->capture == NULL, ;);
475+
476+ /* Ensure any references to this in our thread have finished */
477+ down(&bt_sco->capture_sem);
478+ up(&bt_sco->capture_sem);
479+
480+ snd_free_pages(runtime->dma_area, runtime->dma_bytes);
481+ return 0;
482+}
483+
484+static snd_pcm_ops_t snd_card_bt_sco_playback_ops = {
485+ .open = snd_card_bt_sco_playback_open,
486+ .close = snd_card_bt_sco_playback_close,
487+ .ioctl = snd_pcm_lib_ioctl,
488+ .prepare = snd_card_bt_sco_playback_prepare,
489+ .trigger = snd_card_bt_sco_playback_trigger,
490+ .pointer = snd_card_bt_sco_playback_pointer,
491+};
492+
493+static snd_pcm_ops_t snd_card_bt_sco_capture_ops = {
494+ .open = snd_card_bt_sco_capture_open,
495+ .close = snd_card_bt_sco_capture_close,
496+ .ioctl = snd_pcm_lib_ioctl,
497+ .prepare = snd_card_bt_sco_capture_prepare,
498+ .trigger = snd_card_bt_sco_capture_trigger,
499+ .pointer = snd_card_bt_sco_capture_pointer,
500+};
501+
502+static int __init snd_card_bt_sco_pcm(snd_card_bt_sco_t * bt_sco)
503+{
504+ snd_pcm_t *pcm;
505+ int err;
506+
507+ if ((err =
508+ snd_pcm_new(bt_sco->card, "Bluetooth SCO PCM", 0, 1, 1,
509+ &pcm)) < 0)
510+ return err;
511+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
512+ &snd_card_bt_sco_playback_ops);
513+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
514+ &snd_card_bt_sco_capture_ops);
515+ pcm->private_data = bt_sco;
516+ pcm->info_flags = 0;
517+ strcpy(pcm->name, "BT SCO PCM");
518+ return 0;
519+}
520+
521+#define BT_SCO_VOLUME(xname, xindex, addr) \
522+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
523+ .info = snd_bt_sco_volume_info, \
524+ .get = snd_bt_sco_volume_get, .put = snd_bt_sco_volume_put, \
525+ .private_value = addr }
526+
527+static int snd_bt_sco_volume_info(snd_kcontrol_t * kcontrol,
528+ snd_ctl_elem_info_t * uinfo)
529+{
530+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
531+ uinfo->count = 1;
532+ uinfo->value.integer.min = MIXER_MIN_VOLUME;
533+ uinfo->value.integer.max = MIXER_MAX_VOLUME;
534+ return 0;
535+}
536+
537+static int snd_bt_sco_volume_get(snd_kcontrol_t * kcontrol,
538+ snd_ctl_elem_value_t * ucontrol)
539+{
540+ snd_card_bt_sco_t *bt_sco = _snd_kcontrol_chip(kcontrol);
541+ unsigned long flags;
542+ int addr = kcontrol->private_value;
543+
544+ spin_lock_irqsave(&bt_sco->mixer_lock, flags);
545+ ucontrol->value.integer.value[0] = bt_sco->mixer_volume[addr];
546+ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags);
547+ return 0;
548+}
549+
550+static int snd_bt_sco_volume_put(snd_kcontrol_t * kcontrol,
551+ snd_ctl_elem_value_t * ucontrol)
552+{
553+ snd_card_bt_sco_t *bt_sco = _snd_kcontrol_chip(kcontrol);
554+ unsigned long flags;
555+ int changed, addr = kcontrol->private_value;
556+ int vol;
557+
558+ vol = ucontrol->value.integer.value[0];
559+ if (vol < MIXER_MIN_VOLUME)
560+ vol =MIXER_MIN_VOLUME;
561+ if (vol > MIXER_MAX_VOLUME)
562+ vol = MIXER_MAX_VOLUME;
563+ spin_lock_irqsave(&bt_sco->mixer_lock, flags);
564+ changed = bt_sco->mixer_volume[addr] != vol;
565+ bt_sco->mixer_volume[addr] = vol;
566+ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags);
567+ if (changed) {
568+ spin_lock_irqsave(&bt_sco->mixer_changed_lock, flags);
569+ bt_sco->mixer_changed = 1;
570+ spin_unlock_irqrestore(&bt_sco->mixer_changed_lock, flags);
571+ wake_up(&bt_sco->hwdep_wait);
572+ }
573+ return changed;
574+}
575+
576+static int snd_bt_sco_boolean_info(snd_kcontrol_t *kcontrol,
577+ snd_ctl_elem_info_t *uinfo)
578+{
579+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
580+ uinfo->count = 1;
581+ uinfo->value.integer.min = 0;
582+ uinfo->value.integer.max = 1;
583+ return 0;
584+}
585+
586+static int snd_bt_sco_loopback_get(snd_kcontrol_t * kcontrol,
587+ snd_ctl_elem_value_t * ucontrol)
588+{
589+ snd_card_bt_sco_t *bt_sco = _snd_kcontrol_chip(kcontrol);
590+ unsigned long flags;
591+
592+ spin_lock_irqsave(&bt_sco->mixer_lock, flags);
593+ ucontrol->value.integer.value[0] = bt_sco->loopback;
594+ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags);
595+ return 0;
596+}
597+
598+static int snd_bt_sco_loopback_put(snd_kcontrol_t * kcontrol,
599+ snd_ctl_elem_value_t * ucontrol)
600+{
601+ snd_card_bt_sco_t *bt_sco = _snd_kcontrol_chip(kcontrol);
602+ unsigned long flags;
603+ int changed;
604+ int loopback;
605+
606+ loopback = !!ucontrol->value.integer.value[0];
607+
608+ spin_lock_irqsave(&bt_sco->mixer_lock, flags);
609+ changed = bt_sco->loopback != loopback;
610+ bt_sco->loopback = loopback;
611+ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags);
612+ return changed;
613+}
614+
615+#define BT_SCO_CONTROLS (sizeof(snd_bt_sco_controls)/sizeof(snd_kcontrol_new_t))
616+
617+static snd_kcontrol_new_t snd_bt_sco_controls[] = {
618+ BT_SCO_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
619+ BT_SCO_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
620+ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
621+ .name = "Loopback Switch",
622+ .index = 0,
623+ .info = snd_bt_sco_boolean_info,
624+ .get = snd_bt_sco_loopback_get,
625+ .put = snd_bt_sco_loopback_put,
626+ }
627+};
628+
629+int __init snd_card_bt_sco_new_mixer(snd_card_bt_sco_t *bt_sco)
630+{
631+ snd_card_t *card = bt_sco->card;
632+
633+ unsigned int idx;
634+ int err;
635+
636+ snd_assert(bt_sco != NULL, return -EINVAL);
637+ spin_lock_init(&bt_sco->mixer_lock);
638+ strcpy(card->mixername, "BT Headset Mixer");
639+
640+ for (idx = 0; idx < BT_SCO_CONTROLS; idx++) {
641+ bt_sco->mixer_controls[idx] =
642+ snd_ctl_new1(&snd_bt_sco_controls[idx],bt_sco);
643+
644+ if ((err = snd_ctl_add(card,bt_sco->mixer_controls[idx])) < 0)
645+ return err;
646+ }
647+ return 0;
648+}
649+
650+static int snd_card_bt_open(snd_hwdep_t * hw, struct file *file)
651+{
652+ return 0;
653+}
654+
655+static int snd_card_bt_release(snd_hwdep_t * hw, struct file *file)
656+{
657+ return 0;
658+}
659+
660+
661+static int snd_card_bt_ioctl(snd_hwdep_t * hw, struct file *file,
662+ unsigned int cmd, unsigned long arg)
663+{
664+ snd_card_bt_sco_t *bt_sco =
665+ snd_magic_cast(snd_card_bt_sco_t,hw->card->private_data,return -ENXIO);
666+ struct socket *sock;
667+ int err = -EINVAL;
668+ int fd = arg;
669+
670+ switch (cmd) {
671+ case SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET:
672+ err = 0;
673+ /* Interrupt any socket operations, so that we may
674+ * change the socket */
675+ down(&bt_sco->sock_sem);
676+ kill_proc(bt_sco->thread_pid, SIGINT, 1);
677+ if (bt_sco->sco_sock) {
678+ dprintk("Disposing of previous socket count %d\n",file_count(bt_sco->sco_sock->file));
679+ /* Extra brackets needed here since sockfd_put is a poorly implemented macro */
680+ sockfd_put(((struct socket*) bt_sco->sco_sock));
681+
682+ bt_sco->sco_sock = NULL;
683+ }
684+
685+ if (fd>=0) {
686+ err = -EINVAL;
687+ sock = sockfd_lookup(fd, &err);
688+ if (sock) {
689+ if (sock->sk->sk_family == PF_BLUETOOTH &&
690+ sock->sk->sk_protocol == BTPROTO_SCO) {
691+ bt_sco->sco_sock = sock;
692+ wake_up(&bt_sco->wait);
693+ err = 0;
694+ } else {
695+ dprintk("Not a bluetooth SCO socket %d:%d\n",
696+ sock->sk->sk_family,
697+ sock->sk->sk_protocol);
698+ sockfd_put(sock);
699+ }
700+ }
701+ }
702+ up(&bt_sco->sock_sem);
703+ break;
704+ }
705+ return err;
706+}
707+
708+static long snd_card_bt_write(snd_hwdep_t * hw, const char *buf, long count,
709+ loff_t * offset)
710+{
711+ snd_card_bt_sco_t *bt_sco =
712+ snd_magic_cast(snd_card_bt_sco_t,hw->card->private_data,return -ENXIO);
713+ int mixer_volume[MIXER_ADDR_LAST + 1];
714+ int retval;
715+ int i;
716+
717+ if (count != sizeof(mixer_volume))
718+ return -EINVAL;
719+
720+ if (copy_from_user(mixer_volume,buf,sizeof(mixer_volume)))
721+ return -EFAULT;
722+
723+ retval = sizeof(mixer_volume);
724+
725+ spin_lock_irq(&bt_sco->mixer_lock);
726+ for (i=0;i<=MIXER_ADDR_LAST;i++) {
727+ int vol = mixer_volume[i];
728+ if (vol>MIXER_MAX_VOLUME)
729+ vol = MIXER_MAX_VOLUME;
730+ if (vol<MIXER_MIN_VOLUME)
731+ vol = MIXER_MIN_VOLUME;
732+ if (bt_sco->mixer_volume[i] != vol) {
733+ bt_sco->mixer_volume[i] = vol;
734+ snd_ctl_notify(bt_sco->card,
735+ SNDRV_CTL_EVENT_MASK_VALUE,
736+ &bt_sco->mixer_controls[i]->id);
737+ }
738+ }
739+ spin_unlock_irq(&bt_sco->mixer_lock);
740+
741+ return retval;
742+}
743+
744+static long snd_card_bt_read(snd_hwdep_t * hw, char *buf, long count,
745+ loff_t * offset)
746+{
747+ snd_card_bt_sco_t *bt_sco =
748+ snd_magic_cast(snd_card_bt_sco_t,hw->card->private_data,return -ENXIO);
749+ DECLARE_WAITQUEUE(wait, current);
750+ ssize_t retval;
751+
752+ if (count != sizeof(bt_sco->mixer_volume))
753+ return -EINVAL;
754+
755+ add_wait_queue(&bt_sco->hwdep_wait, &wait);
756+ current->state = TASK_INTERRUPTIBLE;
757+ do {
758+ int changed;
759+ spin_lock_irq(&bt_sco->mixer_changed_lock);
760+ changed = bt_sco->mixer_changed;
761+ bt_sco->mixer_changed = 0;
762+ spin_unlock_irq(&bt_sco->mixer_changed_lock);
763+
764+ if (changed != 0)
765+ break;
766+
767+ if (signal_pending(current)) {
768+ retval = -ERESTARTSYS;
769+ goto out;
770+ }
771+ schedule();
772+ } while (1);
773+ if (copy_to_user(buf, bt_sco->mixer_volume, sizeof(bt_sco->mixer_volume)))
774+ retval = -EFAULT;
775+ else retval = sizeof(bt_sco->mixer_volume);
776+
777+ out:
778+ current->state = TASK_RUNNING;
779+ remove_wait_queue(&bt_sco->hwdep_wait, &wait);
780+ return retval;
781+}
782+
783+static unsigned int snd_card_bt_poll(snd_hwdep_t * hw,
784+ struct file *file,
785+ poll_table * wait)
786+{
787+ snd_card_bt_sco_t *bt_sco =
788+ snd_magic_cast(snd_card_bt_sco_t,hw->card->private_data,return 0);
789+ int changed;
790+
791+ poll_wait(file, &bt_sco->hwdep_wait, wait);
792+
793+ spin_lock_irq(&bt_sco->mixer_changed_lock);
794+ changed = bt_sco->mixer_changed;
795+ spin_unlock_irq(&bt_sco->mixer_changed_lock);
796+
797+ if (changed != 0)
798+ return POLLIN | POLLRDNORM;
799+ return 0;
800+}
801+
802+static int snd_card_bt_sco_thread(void *data)
803+{
804+ snd_card_t *card = (snd_card_t *) data;
805+ snd_card_bt_sco_t *bt_sco =
806+ snd_magic_cast(snd_card_bt_sco_t,card->private_data,return 0);
807+ struct socket *sock;
808+ int len;
809+#define BUF_SIZE 256
810+ unsigned char buf[BUF_SIZE];
811+ struct msghdr msg;
812+ struct iovec iov;
813+ sigset_t unblocked;
814+
815+ lock_kernel();
816+
817+ daemonize("snd-bt-scod");
818+ sigemptyset(&unblocked);
819+ sigaddset(&unblocked,SIGINT);
820+ sigaddset(&unblocked,SIGTERM);
821+ sigprocmask(SIG_UNBLOCK, &unblocked, NULL);
822+
823+ /* Pretend so that copy_to_user and friends work */
824+ set_fs(KERNEL_DS);
825+
826+ dprintk("snd-bt-scod thread starting\n");
827+ up(&bt_sco->thread_sem);
828+
829+ do {
830+ if (signal_pending(current))
831+ flush_signals(current);
832+
833+ /* This may be woken up by a wake_up() when
834+ * a new socket is installed, or by a signal.
835+ * Signals are sent to terminate the thread,
836+ * in which case thread_exit is set, and to force
837+ * recvmesg() to wake up (from the ioctl handler)
838+ */
839+ wait_event_interruptible(bt_sco->wait,
840+ bt_sco->sco_sock!=0);
841+ if (bt_sco->thread_exit)
842+ break;
843+
844+ down(&bt_sco->sock_sem);
845+ sock = (struct socket*) bt_sco->sco_sock;
846+ if (sock)
847+ get_file(sock->file);
848+ up(&bt_sco->sock_sem);
849+
850+ if (!sock)
851+ continue;
852+
853+ /* We have a socket, let's read from it and write to it... */
854+
855+ memset(&msg,0,sizeof(msg));
856+ msg.msg_iov = &iov;
857+ iov.iov_base = buf;
858+ iov.iov_len = BUF_SIZE;
859+
860+ /* This will block until we receive data or a signal */
861+ len = sock_recvmsg(sock, &msg, BUF_SIZE, 0);
862+ if (len > 0) {
863+
864+ down(&bt_sco->capture_sem);
865+ if (bt_sco->capture) {
866+ snd_card_bt_sco_pcm_receive
867+ (bt_sco->capture,
868+ buf, len);
869+ }
870+ up(&bt_sco->capture_sem);
871+
872+ down(&bt_sco->playback_sem);
873+
874+ if (bt_sco->playback || !bt_sco->loopback) {
875+ memset(buf, 0, len);
876+#if 0
877+ /* fill with tone instead of silence */
878+ int i;
879+
880+ for (i=0;i<len/2;i++) {
881+ buf[i] = 0;
882+ }
883+ for (i=len/2;i<len;i++) {
884+ buf[i] = 127;
885+ }
886+#endif
887+ }
888+ if (bt_sco->playback) {
889+ snd_card_bt_sco_pcm_send
890+ (bt_sco->playback,
891+ buf, len);
892+
893+ /* Strangely, when the device is open but no audio is
894+ being written by the app, there's an occasional glitch
895+ in the silence data. This hack eliminates it. */
896+
897+ int i;
898+ int notzero=-1;
899+ for (i=0;i<len;i++) {
900+ if (buf[i]!=0) {
901+ if (notzero>=0)
902+ break;
903+ notzero = i;
904+ }
905+ }
906+ if (notzero>=0 && i>=len) {
907+ buf[notzero] = 0;
908+ }
909+ }
910+ up(&bt_sco->playback_sem);
911+
912+#if 0
913+ /* This chunk of code lets us record (using arecord)
914+ what data alsa is sending out.
915+
916+ e.g., when idle, we'd expect something like:
917+
918+ 8080 8080 8080 8080 8483 8281 8182 8384
919+ 8080 8080 8080 8080 8080 8080 8080 8080
920+ 8080 8080 8080 8080 8483 8281 8182 8384
921+ 8080 8080 8080 8080 8080 8080 8080 8080
922+
923+ (this is from 'xxd' of a wav file, that data in
924+ which is unsigned, whereas we are dealing with signed).
925+ */
926+
927+ down(&bt_sco->capture_sem);
928+ if (bt_sco->capture) {
929+ snd_card_bt_sco_pcm_receive
930+ (bt_sco->capture,
931+ "\001\002\003\004", 4);
932+ snd_card_bt_sco_pcm_receive
933+ (bt_sco->capture,
934+ buf, len);
935+ snd_card_bt_sco_pcm_receive
936+ (bt_sco->capture,
937+ "\004\003\002\001", 4);
938+ }
939+ up(&bt_sco->capture_sem);
940+#endif
941+ msg.msg_flags = 0;
942+ msg.msg_iov = &iov;
943+ iov.iov_base = buf;
944+ iov.iov_len = BUF_SIZE;
945+ sock_sendmsg(sock, &msg, len);
946+ }
947+
948+ /* Expect this to be 3 because we (this thead) have a copy,
949+ the driver process keeps one, and the app has the socket open.
950+ */
951+ if (file_count(sock->file) != 3) {
952+ dprintk("file_count is %d (expected 3)\n",file_count(sock->file));
953+ }
954+ fput(sock->file);
955+
956+ schedule();
957+ } while (!bt_sco->thread_exit);
958+
959+ dprintk("thread exiting\n");
960+
961+ unlock_kernel();
962+ complete_and_exit(&bt_sco->thread_done, 0);
963+}
964+
965+static void snd_card_bt_private_free(snd_card_t * card)
966+{
967+ snd_card_bt_sco_t *bt_sco = snd_magic_cast(snd_card_bt_sco_t,card->private_data,return);
968+
969+ dprintk("private_free, killing thread\n");
970+ bt_sco->thread_exit = 1;
971+ kill_proc(bt_sco->thread_pid, SIGTERM, 1);
972+ wait_for_completion(&bt_sco->thread_done);
973+ dprintk("private_free, thread exited\n");
974+
975+ if (bt_sco->sco_sock) {
976+ dprintk("shutdown: freeing socket count %d\n",file_count(bt_sco->sco_sock->file));
977+
978+ sockfd_put(((struct socket*) bt_sco->sco_sock));
979+ }
980+
981+ snd_magic_kfree(bt_sco);
982+}
983+
984+static int __init snd_card_bt_sco_probe(int dev)
985+{
986+ snd_card_t *card;
987+ snd_card_bt_sco_t *bt_sco;
988+ int err;
989+ snd_hwdep_t *hw;
990+
991+ card =
992+ snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
993+ THIS_MODULE, 0);
994+ if (card == NULL)
995+ return -ENOMEM;
996+
997+ bt_sco = snd_magic_kcalloc(snd_card_bt_sco_t, 0, GFP_KERNEL);
998+ card->private_data = bt_sco;
999+ card->private_free = snd_card_bt_private_free;
1000+
1001+ bt_sco->card = card;
1002+
1003+ init_completion(&bt_sco->thread_done);
1004+ init_MUTEX_LOCKED(&bt_sco->thread_sem);
1005+ init_MUTEX(&bt_sco->sock_sem);
1006+ init_MUTEX(&bt_sco->capture_sem);
1007+ init_MUTEX(&bt_sco->playback_sem);
1008+ init_waitqueue_head(&bt_sco->wait);
1009+ init_waitqueue_head(&bt_sco->hwdep_wait);
1010+ spin_lock_init(&bt_sco->mixer_changed_lock);
1011+
1012+ /* These clone flags copied from some other driver.
1013+ Not sure that they're really correct... */
1014+ bt_sco->thread_pid =
1015+ kernel_thread(snd_card_bt_sco_thread, card, CLONE_KERNEL);
1016+ if (bt_sco->thread_pid < 0) {
1017+ err = bt_sco->thread_pid;
1018+ goto __nodev;
1019+ }
1020+
1021+ down(&bt_sco->thread_sem);
1022+
1023+ if ((err = snd_card_bt_sco_pcm(bt_sco)) < 0)
1024+ goto __nodev;
1025+ if ((err = snd_card_bt_sco_new_mixer(bt_sco)) < 0)
1026+ goto __nodev;
1027+ strcpy(card->driver, "Bluetooth SCO");
1028+ strcpy(card->shortname, "BT Headset");
1029+ sprintf(card->longname, "BT Headset %i", dev + 1);
1030+
1031+ err = snd_hwdep_new(card, "BTSCO", 0, &hw);
1032+ if (err < 0)
1033+ goto __nodev;
1034+
1035+ sprintf(hw->name, "BTSCO");
1036+ hw->iface = SNDRV_HWDEP_IFACE_BT_SCO;
1037+ hw->ops.open = snd_card_bt_open;
1038+ hw->ops.ioctl = snd_card_bt_ioctl;
1039+ hw->ops.release = snd_card_bt_release;
1040+ hw->ops.read = snd_card_bt_read;
1041+ hw->ops.write = snd_card_bt_write;
1042+ hw->ops.poll = snd_card_bt_poll;
1043+
1044+ if ((err = snd_card_register(card)) == 0) {
1045+ snd_bt_sco_cards[dev] = card;
1046+ return 0;
1047+ }
1048+ __nodev:
1049+ snd_card_free(card);
1050+ return err;
1051+}
1052+
1053+static int __init alsa_card_bt_sco_init(void)
1054+{
1055+ printk(KERN_INFO "snd-bt-sco revision %s\n",mod_revision+11);
1056+
1057+ if (snd_card_bt_sco_probe(0) < 0) {
1058+#ifdef MODULE
1059+ printk(KERN_ERR
1060+ "Bluetooth SCO soundcard not found or device busy\n");
1061+#endif
1062+ return -ENODEV;
1063+ }
1064+ return 0;
1065+}
1066+
1067+static void __exit alsa_card_bt_sco_exit(void)
1068+{
1069+ int idx;
1070+
1071+ for (idx = 0; idx < SNDRV_CARDS; idx++)
1072+ snd_card_free(snd_bt_sco_cards[idx]);
1073+}
1074+
1075+module_init(alsa_card_bt_sco_init)
1076+ module_exit(alsa_card_bt_sco_exit)
1077+#ifndef MODULE
1078+static int __init alsa_card_bt_sco_setup(char *str)
1079+{
1080+ static unsigned __initdata nr_dev = 0;
1081+
1082+ if (nr_dev >= SNDRV_CARDS)
1083+ return 0;
1084+ nr_dev++;
1085+ return 1;
1086+}
1087+
1088+__setup("snd-bt-sco=", alsa_card_bt_sco_setup);
1089+
1090+#endif /* ifndef MODULE */
1091diff -urN linux/sound/bluetooth/Kconfig linux.new/sound/bluetooth/Kconfig
1092--- linux/sound/bluetooth/Kconfig 1970-01-01 01:00:00.000000000 +0100
1093+++ linux.new/sound/bluetooth/Kconfig 2004-08-23 18:41:39.000000000 +0200
1094@@ -0,0 +1,20 @@
1095+# ALSA USB drivers
1096+
1097+menu "ALSA Bluetooth device"
1098+ depends on SND!=n && USB!=n
1099+
1100+config SND_BT_SCO
1101+ tristate "USB Bluetooth Alsa driver"
1102+ depends on SND && USB
1103+ select SND_HWDEP
1104+ select SND_USB_AUDIO
1105+ help
1106+ Say 'Y' or 'M' to include support for USB Bluetooth audio devices.
1107+ This will allow you to use a Bluetooth headset. The driver has to
1108+ be used with the btsco client program and will then create a new
1109+ ALSA device you can normally acces through plughw:Headset (see
1110+ README). You can get the client app and the driver patch from
1111+ http://www.gargan.org/linux/snd-bt-sco or maybe later from
1112+ sourceforge.
1113+
1114+endmenu
1115diff -urN linux/sound/bluetooth/Makefile linux.new/sound/bluetooth/Makefile
1116--- linux/sound/bluetooth/Makefile 1970-01-01 01:00:00.000000000 +0100
1117+++ linux.new/sound/bluetooth/Makefile 2004-07-28 13:39:50.000000000 +0200
1118@@ -0,0 +1,26 @@
1119+#
1120+# Makefile for ALSA
1121+#
1122+
1123+snd-bt-sco-objs := btsco.o
1124+
1125+# Toplevel Module Dependency
1126+obj-$(CONFIG_SND_BT_SCO) += snd-bt-sco.o
1127+
1128+#ifndef SND_TOPDIR
1129+#SND_TOPDIR=..
1130+#endif
1131+
1132+#include $(SND_TOPDIR)/toplevel.config
1133+#include $(SND_TOPDIR)/Makefile.conf
1134+
1135+#obj-$(CONFIG_SND_BT_SCO) += snd-bt-sco.o
1136+#include $(SND_TOPDIR)/alsa-kernel/bluetooth/Makefile
1137+#
1138+#EXTRA_CFLAGS += -I$(SND_TOPDIR)/alsa-kernel/bluetooth
1139+#
1140+#include $(SND_TOPDIR)/Rules.make
1141+#
1142+#snd-bt-sco-objs := btsco.o
1143+#
1144+#btsco.o: ../alsa-kernel/bluetooth/btsco.c
1145diff -urN linux/sound/Kconfig linux.new/sound/Kconfig
1146--- linux/sound/Kconfig 2004-08-23 18:46:43.000000000 +0200
1147+++ linux.new/sound/Kconfig 2004-08-23 18:36:41.000000000 +0200
1148@@ -59,6 +59,8 @@
1149 # here assuming USB is defined before ALSA
1150 source "sound/usb/Kconfig"
1151
1152+source "sound/bluetooth/Kconfig"
1153+
1154 # the following will depenend on the order of config.
1155 # here assuming PCMCIA is defined before ALSA
1156 source "sound/pcmcia/Kconfig"
1157diff -urN linux/sound/Makefile linux.new/sound/Makefile
1158--- linux/sound/Makefile 2004-08-23 18:46:43.000000000 +0200
1159+++ linux.new/sound/Makefile 2004-08-23 19:22:46.000000000 +0200
1160@@ -4,7 +4,7 @@
1161 obj-$(CONFIG_SOUND) += soundcore.o
1162 obj-$(CONFIG_SOUND_PRIME) += oss/
1163 obj-$(CONFIG_DMASOUND) += oss/
1164-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/
1165+obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ bluetooth/
1166
1167 ifeq ($(CONFIG_SND),y)
1168 obj-y += last.o
This page took 0.392512 seconds and 4 git commands to generate.