PXA310音频(4)
来源:互联网 发布:投影机画面测试软件 编辑:程序博客网 时间:2024/04/28 21:13
上面已经创建了codec 结构
接下来就要 register pcms 了。
snd_soc_new_pcms
首先创建snd_card
snd_card_new 位于sound/core/init.c 中
创建和初试化一个snd_card 结构体
struct snd_card *snd_card_new(int idx, const char *xid,
struct module *module, int extra_size)
{
struct snd_card *card;
int err;
if (extra_size < 0)
extra_size = 0;
card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
if (card == NULL)
return NULL;
分配了结构体
if (xid) {
if (!snd_info_check_reserved_words(xid))
goto __error;
strlcpy(card->id, xid, sizeof(card->id));
}
err = 0;
mutex_lock(&snd_card_mutex);
if (idx < 0) {
int idx2;
for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++)
/* idx == -1 == 0xffff means: take any free slot */
if (~snd_cards_lock & idx & 1<<idx2) {
idx = idx2;
if (idx >= snd_ecards_limit)
snd_ecards_limit = idx + 1;
break;
}
} else {
if (idx < snd_ecards_limit) {
if (snd_cards_lock & (1 << idx))
err = -EBUSY; /* invalid */
} else {
if (idx < SNDRV_CARDS)
snd_ecards_limit = idx + 1; /* increase the limit */
else
err = -ENODEV;
}
}
注意上面的按位与操作
理论上可以有32个snd_card,找空闲的snd_card,如果能找到就说明是成功的
if (idx < 0 || err < 0) {
mutex_unlock(&snd_card_mutex);
snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d/n",
idx, snd_ecards_limit - 1, err);
goto __error;
}
snd_cards_lock |= 1 << idx; /* lock it */
将选card锁上
mutex_unlock(&snd_card_mutex);
card->number = idx;
card->module = module;
INIT_LIST_HEAD(&card->devices);
init_rwsem(&card->controls_rwsem);
rwlock_init(&card->ctl_files_rwlock);
INIT_LIST_HEAD(&card->controls);
INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock);
init_waitqueue_head(&card->shutdown_sleep);
#ifdef CONFIG_PM
mutex_init(&card->power_lock);
init_waitqueue_head(&card->power_sleep);
#endif
/* the control interface cannot be accessed from the user space until */
/* snd_cards_bitmask and snd_cards are set with snd_card_register */
if ((err = snd_ctl_create(card)) < 0) {
snd_printd("unable to register control minors/n");
goto __error;
}
对snd_card 进行
if ((err = snd_info_card_create(card)) < 0) {
snd_printd("unable to create card info/n");
goto __error_ctl;
}
分配了一个声音控制设置串到snd_card的device链表中去
这个控制设备提供了一些方法
static struct snd_device_ops ops = {
.dev_free = snd_ctl_dev_free,
.dev_register = snd_ctl_dev_register,
.dev_disconnect = snd_ctl_dev_disconnect,
};
关注一下提供的注册方法,这个在后面会被调用
static int snd_ctl_dev_register(struct snd_device *device)
{
struct snd_card *card = device->device_data;
int err, cardnum;
char name[16];
snd_assert(card != NULL, return -ENXIO);
cardnum = card->number;
snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
sprintf(name, "controlC%i", cardnum);
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
&snd_ctl_f_ops, card, name)) < 0)
return err;
return 0;
}
接下来要进行真正的注册
int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
const struct file_operations *f_ops,
void *private_data,
const char *name, struct device *device)
{
int minor;
struct snd_minor *preg;
snd_assert(name, return -EINVAL);
preg = kmalloc(sizeof *preg, GFP_KERNEL);
if (preg == NULL)
return -ENOMEM;
preg->type = type;
preg->card = card ? card->number : -1;
preg->device = dev;
preg->f_ops = f_ops;
preg->private_data = private_data;
mutex_lock(&sound_mutex);
#ifdef CONFIG_SND_DYNAMIC_MINORS
minor = snd_find_free_minor();
#else
minor = snd_kernel_minor(type, card, dev);
if (minor >= 0 && snd_minors[minor])
minor = -EBUSY;
#endif
if (minor < 0) {
mutex_unlock(&sound_mutex);
kfree(preg);
return minor;
}
snd_minors[minor] = preg;
在sound.c 中维护了如下数组
static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
上面的代码 首先创建了一个snd_minor,封装了相应的方法和数据
preg->dev = device_create(sound_class, device, MKDEV(major, minor),
"%s", name);
if (preg->dev)
dev_set_drvdata(preg->dev, private_data);
接下来真正的创建这个设备
mutex_unlock(&sound_mutex);
return 0;
}
if (extra_size > 0)
card->private_data = (char *)card + sizeof(struct snd_card);
return card;
__error_ctl:
snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
__error:
kfree(card);
return NULL;
}
不过,register的时机还没有到,当前只是创建了一个控制设备结构体,将他串到了card上。
接着在proc 文件系统中创建card节点了
Card 有了 ,pcm呢?
Pcm的创建根据dai接口的数量来创建,pxa310 中有2个dai
也就是调用2次soc_new_pcm
首先分配runtime结构 snd_soc_pcm_runtime
Cpu dai的类型就ac97 i2s pcm 等
分配一个snd_pcm_t 结构体
为snd_pcm_t 下的播放流和采集流下的子流设置各种方法
接下来调用 platform的pcm_new方法 ,预先分配dmabuffer
到这里我们已经创建了2个pcm了
然后我们为card添加了一些控制设备
注册的时候将card上的所有设备一起注册了
以上就是probe 中操作的大致内容
- PXA310音频(4)
- Pxa310音频(1)
- PXA310音频(2)
- PXA310音频(3)
- PXA310音频(5)
- pxa310 u2d
- PXA310系统电源管理
- PXA310核心板
- PXA310之I2C
- Marvel Pxa310 Video横屏竖屏切换
- PXA310的电源管理(1)
- pxa310 开发环境安装(1)
- PXA310的电源管理(2)
- PXA310的电源管理(3)
- directshow+wince6.0+pxa310+双camera
- directshow+wince6.0+pxa310+双camera
- directshow+wince6.0+pxa310+双camera
- 音频
- Linux date命令
- Basic Elements of Oracle SQL 之 Literals
- 每天学一点flash(68) 新闻列表制作(2)
- 如何在Linux上安装SourceInsight?
- W3C 中关于JavaScript Ajax跨域请求的草案
- PXA310音频(4)
- 传智Struts2笔记(四)Action中result的各种转发类型
- 设计师应该关注的41个英文网站
- spring 的aop控制事务
- Basic Elements of Oracle SQL 之 Nulls
- 怎样的金融IT公司才算好公司
- S3C DMA使用方法,2410-2440 dma介绍
- apache ---weblogic 的重起
- 学习