core.h 11.8 KB
Newer Older
Jaroslav Kysela's avatar
Jaroslav Kysela committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#ifndef __SOUND_CORE_H
#define __SOUND_CORE_H

/*
 *  Main header file for the ALSA driver
 *  Copyright (c) 1994-2001 by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   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
 *
 */

25 26 27 28
#ifdef CONFIG_PM
#include <linux/sched.h>		/* wake_up() and struct semaphore */
#endif

Jaroslav Kysela's avatar
Jaroslav Kysela committed
29 30 31 32 33 34 35 36
/* Typedef's */
typedef struct timeval snd_timestamp_t;
typedef struct sndrv_interval snd_interval_t;
typedef enum sndrv_card_type snd_card_type;
typedef struct sndrv_xferi snd_xferi_t;
typedef struct sndrv_xfern snd_xfern_t;
typedef struct sndrv_xferv snd_xferv_t;

37 38 39 40 41
/* forward declarations */
#ifdef CONFIG_PCI
struct pci_dev;
#endif

Jaroslav Kysela's avatar
Jaroslav Kysela committed
42 43 44 45 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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
/* device allocation stuff */

#define SNDRV_DEV_TYPE_RANGE_SIZE		0x1000

typedef enum {
	SNDRV_DEV_TOPLEVEL =		(0*SNDRV_DEV_TYPE_RANGE_SIZE),
	SNDRV_DEV_LOWLEVEL_PRE,
	SNDRV_DEV_LOWLEVEL_NORMAL =	(1*SNDRV_DEV_TYPE_RANGE_SIZE),
	SNDRV_DEV_PCM,
	SNDRV_DEV_RAWMIDI,
	SNDRV_DEV_TIMER,
	SNDRV_DEV_SEQUENCER,
	SNDRV_DEV_HWDEP,
	SNDRV_DEV_LOWLEVEL =		(2*SNDRV_DEV_TYPE_RANGE_SIZE)
} snd_device_type_t;

typedef enum {
	SNDRV_DEV_BUILD = 0,
	SNDRV_DEV_REGISTERED = 1
} snd_device_state_t;

typedef enum {
	SNDRV_DEV_CMD_PRE = 0,
	SNDRV_DEV_CMD_NORMAL = 1,
	SNDRV_DEV_CMD_POST = 2
} snd_device_cmd_t;

typedef struct _snd_card snd_card_t;
typedef struct _snd_device snd_device_t;

typedef int (snd_dev_free_t)(snd_device_t *device);
typedef int (snd_dev_register_t)(snd_device_t *device);
typedef int (snd_dev_unregister_t)(snd_device_t *device);

typedef struct {
	snd_dev_free_t *dev_free;
	snd_dev_register_t *dev_register;
	snd_dev_unregister_t *dev_unregister;
} snd_device_ops_t;

struct _snd_device {
	struct list_head list;		/* list of registered devices */
	snd_card_t *card;		/* card which holds this device */
	snd_device_state_t state;	/* state of the device */
	snd_device_type_t type;		/* device type */
	void *device_data;		/* device structure */
	snd_device_ops_t *ops;		/* operations */
};

#define snd_device(n) list_entry(n, snd_device_t, list)

/* various typedefs */

typedef struct snd_info_entry snd_info_entry_t;
typedef struct _snd_pcm snd_pcm_t;
typedef struct _snd_pcm_str snd_pcm_str_t;
typedef struct _snd_pcm_substream snd_pcm_substream_t;
typedef struct _snd_mixer snd_kmixer_t;
typedef struct _snd_rawmidi snd_rawmidi_t;
typedef struct _snd_ctl_file snd_ctl_file_t;
typedef struct _snd_kcontrol snd_kcontrol_t;
typedef struct _snd_timer snd_timer_t;
typedef struct _snd_timer_instance snd_timer_instance_t;
typedef struct _snd_hwdep snd_hwdep_t;
Jaroslav Kysela's avatar
Jaroslav Kysela committed
106
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
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
typedef struct _snd_oss_mixer snd_mixer_oss_t;
#endif

/* main structure for soundcard */

struct _snd_card {
	int number;			/* number of soundcard (index to snd_cards) */

	char id[16];			/* id string of this card */
	char driver[16];		/* driver name */
	char shortname[32];		/* short name of this soundcard */
	char longname[80];		/* name of this soundcard */
	char mixername[80];		/* mixer name */
	char components[80];		/* card components delimited with space */

	struct module *module;		/* top-level module */

	void *private_data;		/* private data for soundcard */
	void (*private_free) (snd_card_t *card); /* callback for freeing of private data */

	struct list_head devices;	/* devices */

	unsigned int last_numid;	/* last used numeric ID */
	rwlock_t control_rwlock;	/* control list lock */
	rwlock_t control_owner_lock;	/* control list lock */
	int controls_count;		/* count of all controls */
	struct list_head controls;	/* all controls for this card */
	struct list_head ctl_files;	/* active control files */

	snd_info_entry_t *proc_root;	/* root for soundcard specific files */
	snd_info_entry_t *proc_id;	/* the card id */
	struct proc_dir_entry *proc_root_link;	/* number link to real id */

#ifdef CONFIG_PM
	int (*set_power_state) (snd_card_t *card, unsigned int state);
	void *power_state_private_data;
	unsigned int power_state;	/* power state */
144
	struct semaphore power_lock;	/* power lock */
Jaroslav Kysela's avatar
Jaroslav Kysela committed
145 146 147
	wait_queue_head_t power_sleep;
#endif

Jaroslav Kysela's avatar
Jaroslav Kysela committed
148
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
149 150 151 152 153 154
	snd_mixer_oss_t *mixer_oss;
	int mixer_oss_change_count;
#endif
};

#ifdef CONFIG_PM
155
static inline void snd_power_lock(snd_card_t *card)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
156
{
157
	down(&card->power_lock);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
158 159 160 161
}

static inline void snd_power_unlock(snd_card_t *card)
{
162
	up(&card->power_lock);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
163 164
}

165
void snd_power_wait(snd_card_t *card);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
166 167 168 169 170 171 172 173 174 175 176 177

static inline unsigned int snd_power_get_state(snd_card_t *card)
{
	return card->power_state;
}

static inline void snd_power_change_state(snd_card_t *card, unsigned int state)
{
	card->power_state = state;
	wake_up(&card->power_sleep);
}
#else
178
#define snd_power_lock(card) do { ; } while (0)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
179
#define snd_power_unlock(card) do { ; } while (0)
180
#define snd_power_wait(card) do { ; } while (0)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
#define snd_power_get_state(card) SNDRV_CTL_POWER_D0
#define snd_power_change_state(card, state) do { ; } while (0)
#endif

/* device.c */

struct _snd_minor {
	struct list_head list;		/* list of all minors per card */
	int number;			/* minor number */
	int device;			/* device number */
	const char *comment;		/* for /proc/asound/devices */
	snd_info_entry_t *dev;		/* for /proc/asound/dev */
	struct file_operations *f_ops;	/* file operations */
};

typedef struct _snd_minor snd_minor_t;

/* sound.c */

extern int snd_ecards_limit;
extern int snd_device_mode;
extern int snd_device_gid;
extern int snd_device_uid;

void snd_request_card(int card);

int snd_register_device(int type, snd_card_t *card, int dev, snd_minor_t *reg, const char *name);
int snd_unregister_device(int type, snd_card_t *card, int dev);

#ifdef CONFIG_SND_OSSEMUL
int snd_register_oss_device(int type, snd_card_t *card, int dev, snd_minor_t *reg, const char *name);
int snd_unregister_oss_device(int type, snd_card_t *card, int dev);
#endif

int snd_minor_info_init(void);
int snd_minor_info_done(void);

/* sound_oss.c */

#ifdef CONFIG_SND_OSSEMUL

int snd_minor_info_oss_init(void);
int snd_minor_info_oss_done(void);

int snd_oss_init_module(void);
void snd_oss_cleanup_module(void);

#endif

/* memory.c */

#ifdef CONFIG_SND_DEBUG_MEMORY
void snd_memory_init(void);
void snd_memory_done(void);
int snd_memory_info_init(void);
int snd_memory_info_done(void);
void *snd_hidden_kmalloc(size_t size, int flags);
void snd_hidden_kfree(const void *obj);
void *snd_hidden_vmalloc(unsigned long size);
void snd_hidden_vfree(void *obj);
#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
#define kfree(obj) snd_hidden_kfree(obj)
243
#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
244 245
#define vmalloc(size) snd_hidden_vmalloc(size)
#define vfree(obj) snd_hidden_vfree(obj)
246
#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
247 248
#else
#define kfree_nocheck(obj) kfree(obj)
249
#define vfree_nocheck(obj) vfree(obj)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
250 251 252 253 254 255 256
#endif
void *snd_kcalloc(size_t size, int flags);
char *snd_kmalloc_strdup(const char *string, int flags);
void *snd_malloc_pages(unsigned long size, unsigned int dma_flags);
void *snd_malloc_pages_fallback(unsigned long size, unsigned int dma_flags, unsigned long *res_size);
void snd_free_pages(void *ptr, unsigned long size);
#ifdef CONFIG_PCI
257 258 259
void *snd_malloc_pci_pages(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr);
void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
void snd_free_pci_pages(struct pci_dev *pci, unsigned long size, void *ptr, dma_addr_t dma_addr);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
260
#endif
Jaroslav Kysela's avatar
Jaroslav Kysela committed
261 262 263 264 265 266 267 268 269 270 271
#ifdef CONFIG_ISA
#ifdef CONFIG_PCI
#define snd_malloc_isa_pages(size, dma_addr) snd_malloc_pci_pages(NULL, size, dma_addr)
#define snd_malloc_isa_pages_fallback(size, dma_addr, res_size) snd_malloc_pci_pages_fallback(NULL, size, dma_addr, res_size)
#define snd_free_isa_pages(size, ptr, dma_addr) snd_free_pci_pages(NULL, size, ptr, dma_addr)
#else /* !CONFIG_PCI */
void *snd_malloc_isa_pages(unsigned long size, dma_addr_t *dma_addr);
void *snd_malloc_isa_pages_fallback(unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
#define snd_free_isa_pages(size, ptr, dma_addr) snd_free_pages(ptr, size)
#endif /* CONFIG_PCI */
#endif /* CONFIG_ISA */
Jaroslav Kysela's avatar
Jaroslav Kysela committed
272 273 274 275 276 277 278 279
int copy_to_user_fromio(void *dst, unsigned long src, size_t count);
int copy_from_user_toio(unsigned long dst, const void *src, size_t count);

/* init.c */

extern int snd_cards_count;
extern snd_card_t *snd_cards[SNDRV_CARDS];
extern rwlock_t snd_card_rwlock;
Jaroslav Kysela's avatar
Jaroslav Kysela committed
280
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
extern int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int free_flag);
#endif

snd_card_t *snd_card_new(int idx, const char *id,
			 struct module *module, int extra_size);
int snd_card_free(snd_card_t *card);
int snd_card_register(snd_card_t *card);
int snd_card_info_init(void);
int snd_card_info_done(void);
int snd_component_add(snd_card_t *card, const char *component);

/* device.c */

int snd_device_new(snd_card_t *card, snd_device_type_t type,
		   void *device_data, snd_device_ops_t *ops);
int snd_device_register(snd_card_t *card, void *device_data);
int snd_device_register_all(snd_card_t *card);
int snd_device_free(snd_card_t *card, void *device_data);
int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd);

/* isadma.c */

#define DMA_MODE_NO_ENABLE	0x0100

305
void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
306 307 308 309 310 311
void snd_dma_disable(unsigned long dma);
unsigned int snd_dma_residue(unsigned long dma);

/* misc.c */

int snd_task_name(struct task_struct *task, char *name, size_t size);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
312
#ifdef CONFIG_SND_VERBOSE_PRINTK
313 314 315 316 317 318 319
void snd_verbose_printk(const char *file, int line, const char *format, ...);
#endif
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
void snd_verbose_printd(const char *file, int line, const char *format, ...);
#endif
#if defined(CONFIG_SND_DEBUG) && !defined(CONFIG_SND_VERBOSE_PRINTK)
void snd_printd(const char *format, ...);
Jaroslav Kysela's avatar
Jaroslav Kysela committed
320
#endif
Jaroslav Kysela's avatar
Jaroslav Kysela committed
321 322 323

/* --- */

Jaroslav Kysela's avatar
Jaroslav Kysela committed
324
#ifdef CONFIG_SND_VERBOSE_PRINTK
Linus Torvalds's avatar
Linus Torvalds committed
325 326
#define snd_printk(fmt, args...) \
	snd_verbose_printk(__FILE__, __LINE__, fmt ,##args)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
327
#else
Linus Torvalds's avatar
Linus Torvalds committed
328 329
#define snd_printk(fmt, args...) \
	printk(fmt ,##args)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
330
#endif
Jaroslav Kysela's avatar
Jaroslav Kysela committed
331 332 333 334 335

#ifdef CONFIG_SND_DEBUG

#define __ASTRING__(x) #x

336
#ifdef CONFIG_SND_VERBOSE_PRINTK
Linus Torvalds's avatar
Linus Torvalds committed
337 338
#define snd_printd(fmt, args...) \
	snd_verbose_printd(__FILE__, __LINE__, fmt ,##args)
339
#endif
Jaroslav Kysela's avatar
Jaroslav Kysela committed
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
#define snd_assert(expr, args...) do {\
	if (!(expr)) {\
		snd_printk("BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
		args;\
	}\
} while (0)
#define snd_runtime_check(expr, args...) do {\
	if (!(expr)) {\
		snd_printk("ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
		args;\
	}\
} while (0)

#else /* !CONFIG_SND_DEBUG */

Linus Torvalds's avatar
Linus Torvalds committed
355
#define snd_printd(fmt, args...)	/* nothing */
356
#define snd_assert(expr, args...)	(void)(expr)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
357 358 359 360 361
#define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0)

#endif /* CONFIG_SND_DEBUG */

#ifdef CONFIG_SND_DEBUG_DETECT
Linus Torvalds's avatar
Linus Torvalds committed
362
#define snd_printdd(format, args...) snd_printk(format, ##args)
Jaroslav Kysela's avatar
Jaroslav Kysela committed
363
#else
Linus Torvalds's avatar
Linus Torvalds committed
364
#define snd_printdd(format, args...) /* nothing */
Jaroslav Kysela's avatar
Jaroslav Kysela committed
365 366 367 368 369 370 371 372 373 374 375 376
#endif

#define snd_BUG() snd_assert(0, )


#define snd_timestamp_now(tstamp) do_gettimeofday(tstamp)
#define snd_timestamp_zero(tstamp) do { (tstamp)->tv_sec = 0; (tstamp)->tv_usec = 0; } while (0)
#define snd_timestamp_null(tstamp) ((tstamp)->tv_sec == 0 && (tstamp)->tv_usec ==0)

#define SNDRV_OSS_VERSION         ((3<<16)|(8<<8)|(1<<4)|(0))	/* 3.8.1a */

#endif /* __SOUND_CORE_H */