Blame view
sound/core/device.c
6.59 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * Device management routines |
c1017a4cd [ALSA] Changed Ja... |
3 |
* Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ |
1da177e4c Linux-2.6.12-rc2 |
21 22 |
#include <linux/slab.h> #include <linux/time.h> |
d81a6d717 sound: Add export... |
23 |
#include <linux/export.h> |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 27 28 29 |
#include <linux/errno.h> #include <sound/core.h> /** * snd_device_new - create an ALSA device component * @card: the card instance |
a3352f01e [ALSA] Fix two ty... |
30 |
* @type: the device type, SNDRV_DEV_XXX |
1da177e4c Linux-2.6.12-rc2 |
31 32 33 34 35 36 37 38 39 40 41 42 |
* @device_data: the data pointer of this device * @ops: the operator table * * Creates a new device component for the given data pointer. * The device will be assigned to the card and managed together * by the card. * * The data pointer plays a role as the identifier, too, so the * pointer address must be unique and unchanged. * * Returns zero if successful, or a negative error code on failure. */ |
512bbd6a8 [ALSA] Remove xxx... |
43 44 |
int snd_device_new(struct snd_card *card, snd_device_type_t type, void *device_data, struct snd_device_ops *ops) |
1da177e4c Linux-2.6.12-rc2 |
45 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
46 |
struct snd_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
47 |
|
7eaa943c8 ALSA: Kill snd_as... |
48 49 |
if (snd_BUG_ON(!card || !device_data || !ops)) return -ENXIO; |
ca2c09665 [ALSA] Replace wi... |
50 |
dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
73e77ba02 [ALSA] Add error ... |
51 52 53 |
if (dev == NULL) { snd_printk(KERN_ERR "Cannot allocate device "); |
1da177e4c Linux-2.6.12-rc2 |
54 |
return -ENOMEM; |
73e77ba02 [ALSA] Add error ... |
55 |
} |
1da177e4c Linux-2.6.12-rc2 |
56 57 58 59 60 61 62 63 |
dev->card = card; dev->type = type; dev->state = SNDRV_DEV_BUILD; dev->device_data = device_data; dev->ops = ops; list_add(&dev->list, &card->devices); /* add to the head of list */ return 0; } |
c0d3fb39e [ALSA] Clean up E... |
64 |
EXPORT_SYMBOL(snd_device_new); |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 69 70 |
/** * snd_device_free - release the device from the card * @card: the card instance * @device_data: the data pointer to release * * Removes the device from the list on the card and invokes the |
c461482c8 [ALSA] Unregister... |
71 |
* callbacks, dev_disconnect and dev_free, corresponding to the state. |
1da177e4c Linux-2.6.12-rc2 |
72 73 74 75 76 |
* Then release the device. * * Returns zero if successful, or a negative error code on failure or if the * device not found. */ |
512bbd6a8 [ALSA] Remove xxx... |
77 |
int snd_device_free(struct snd_card *card, void *device_data) |
1da177e4c Linux-2.6.12-rc2 |
78 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
79 |
struct snd_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
80 |
|
7eaa943c8 ALSA: Kill snd_as... |
81 82 |
if (snd_BUG_ON(!card || !device_data)) return -ENXIO; |
9244b2c30 [ALSA] alsa core:... |
83 |
list_for_each_entry(dev, &card->devices, list) { |
1da177e4c Linux-2.6.12-rc2 |
84 85 86 87 |
if (dev->device_data != device_data) continue; /* unlink */ list_del(&dev->list); |
c461482c8 [ALSA] Unregister... |
88 89 90 91 92 93 94 95 96 97 |
if (dev->state == SNDRV_DEV_REGISTERED && dev->ops->dev_disconnect) if (dev->ops->dev_disconnect(dev)) snd_printk(KERN_ERR "device disconnect failure "); if (dev->ops->dev_free) { if (dev->ops->dev_free(dev)) snd_printk(KERN_ERR "device free failure "); |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 101 |
} kfree(dev); return 0; } |
76a4d10e5 ALSA: Print funct... |
102 103 |
snd_printd("device free %p (from %pF), not found ", device_data, |
512bbd6a8 [ALSA] Remove xxx... |
104 |
__builtin_return_address(0)); |
1da177e4c Linux-2.6.12-rc2 |
105 106 |
return -ENXIO; } |
c0d3fb39e [ALSA] Clean up E... |
107 |
EXPORT_SYMBOL(snd_device_free); |
1da177e4c Linux-2.6.12-rc2 |
108 |
/** |
a3352f01e [ALSA] Fix two ty... |
109 |
* snd_device_disconnect - disconnect the device |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 114 115 116 117 118 119 120 |
* @card: the card instance * @device_data: the data pointer to disconnect * * Turns the device into the disconnection state, invoking * dev_disconnect callback, if the device was already registered. * * Usually called from snd_card_disconnect(). * * Returns zero if successful, or a negative error code on failure or if the * device not found. */ |
512bbd6a8 [ALSA] Remove xxx... |
121 |
int snd_device_disconnect(struct snd_card *card, void *device_data) |
1da177e4c Linux-2.6.12-rc2 |
122 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
123 |
struct snd_device *dev; |
a3352f01e [ALSA] Fix two ty... |
124 |
|
7eaa943c8 ALSA: Kill snd_as... |
125 126 |
if (snd_BUG_ON(!card || !device_data)) return -ENXIO; |
9244b2c30 [ALSA] alsa core:... |
127 |
list_for_each_entry(dev, &card->devices, list) { |
1da177e4c Linux-2.6.12-rc2 |
128 129 |
if (dev->device_data != device_data) continue; |
512bbd6a8 [ALSA] Remove xxx... |
130 131 |
if (dev->state == SNDRV_DEV_REGISTERED && dev->ops->dev_disconnect) { |
1da177e4c Linux-2.6.12-rc2 |
132 133 134 135 136 137 138 |
if (dev->ops->dev_disconnect(dev)) snd_printk(KERN_ERR "device disconnect failure "); dev->state = SNDRV_DEV_DISCONNECTED; } return 0; } |
76a4d10e5 ALSA: Print funct... |
139 140 |
snd_printd("device disconnect %p (from %pF), not found ", device_data, |
512bbd6a8 [ALSA] Remove xxx... |
141 |
__builtin_return_address(0)); |
1da177e4c Linux-2.6.12-rc2 |
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
return -ENXIO; } /** * snd_device_register - register the device * @card: the card instance * @device_data: the data pointer to register * * Registers the device which was already created via * snd_device_new(). Usually this is called from snd_card_register(), * but it can be called later if any new devices are created after * invocation of snd_card_register(). * * Returns zero if successful, or a negative error code on failure or if the * device not found. */ |
512bbd6a8 [ALSA] Remove xxx... |
158 |
int snd_device_register(struct snd_card *card, void *device_data) |
1da177e4c Linux-2.6.12-rc2 |
159 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
160 |
struct snd_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
161 |
int err; |
a3352f01e [ALSA] Fix two ty... |
162 |
|
7eaa943c8 ALSA: Kill snd_as... |
163 164 |
if (snd_BUG_ON(!card || !device_data)) return -ENXIO; |
9244b2c30 [ALSA] alsa core:... |
165 |
list_for_each_entry(dev, &card->devices, list) { |
1da177e4c Linux-2.6.12-rc2 |
166 167 168 169 170 171 172 173 |
if (dev->device_data != device_data) continue; if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) { if ((err = dev->ops->dev_register(dev)) < 0) return err; dev->state = SNDRV_DEV_REGISTERED; return 0; } |
73e77ba02 [ALSA] Add error ... |
174 175 |
snd_printd("snd_device_register busy "); |
1da177e4c Linux-2.6.12-rc2 |
176 177 178 179 180 |
return -EBUSY; } snd_BUG(); return -ENXIO; } |
c0d3fb39e [ALSA] Clean up E... |
181 |
EXPORT_SYMBOL(snd_device_register); |
1da177e4c Linux-2.6.12-rc2 |
182 183 184 185 |
/* * register all the devices on the card. * called from init.c */ |
512bbd6a8 [ALSA] Remove xxx... |
186 |
int snd_device_register_all(struct snd_card *card) |
1da177e4c Linux-2.6.12-rc2 |
187 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
188 |
struct snd_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
189 190 |
int err; |
7eaa943c8 ALSA: Kill snd_as... |
191 192 |
if (snd_BUG_ON(!card)) return -ENXIO; |
9244b2c30 [ALSA] alsa core:... |
193 |
list_for_each_entry(dev, &card->devices, list) { |
1da177e4c Linux-2.6.12-rc2 |
194 195 196 197 198 199 200 201 202 203 204 205 206 |
if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) { if ((err = dev->ops->dev_register(dev)) < 0) return err; dev->state = SNDRV_DEV_REGISTERED; } } return 0; } /* * disconnect all the devices on the card. * called from init.c */ |
512bbd6a8 [ALSA] Remove xxx... |
207 |
int snd_device_disconnect_all(struct snd_card *card) |
1da177e4c Linux-2.6.12-rc2 |
208 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
209 |
struct snd_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
210 |
int err = 0; |
7eaa943c8 ALSA: Kill snd_as... |
211 212 |
if (snd_BUG_ON(!card)) return -ENXIO; |
9244b2c30 [ALSA] alsa core:... |
213 |
list_for_each_entry(dev, &card->devices, list) { |
1da177e4c Linux-2.6.12-rc2 |
214 215 216 217 218 219 220 221 222 223 |
if (snd_device_disconnect(card, dev->device_data) < 0) err = -ENXIO; } return err; } /* * release all the devices on the card. * called from init.c */ |
512bbd6a8 [ALSA] Remove xxx... |
224 |
int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd) |
1da177e4c Linux-2.6.12-rc2 |
225 |
{ |
512bbd6a8 [ALSA] Remove xxx... |
226 |
struct snd_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
227 |
int err; |
fea952e5c ALSA: core: spars... |
228 |
unsigned int range_low, range_high, type; |
1da177e4c Linux-2.6.12-rc2 |
229 |
|
7eaa943c8 ALSA: Kill snd_as... |
230 231 |
if (snd_BUG_ON(!card)) return -ENXIO; |
fea952e5c ALSA: core: spars... |
232 |
range_low = (__force unsigned int)cmd * SNDRV_DEV_TYPE_RANGE_SIZE; |
1da177e4c Linux-2.6.12-rc2 |
233 234 |
range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1; __again: |
9244b2c30 [ALSA] alsa core:... |
235 |
list_for_each_entry(dev, &card->devices, list) { |
fea952e5c ALSA: core: spars... |
236 237 |
type = (__force unsigned int)dev->type; if (type >= range_low && type <= range_high) { |
1da177e4c Linux-2.6.12-rc2 |
238 239 240 241 242 243 244 |
if ((err = snd_device_free(card, dev->device_data)) < 0) return err; goto __again; } } return 0; } |