JZ2440笔记:声卡驱动

vi s3c-wm8976.c

在s3c2410-uda1341.c修改驱动,修改硬件部分的控制接口,I2S部分通用不用修改。

1、增加写寄存器操作函数wm8976_write_reg

static void wm8976_write_reg(unsigned char reg, unsigned int data)
{
	int i;
	unsigned long flags;
	unsigned short val = (reg << 9) | (data & 0x1ff);

	s3c2410_gpio_setpin(S3C2410_GPB2,1);
	s3c2410_gpio_setpin(S3C2410_GPB3,1);
	s3c2410_gpio_setpin(S3C2410_GPB4,1);

	local_irq_save(flags);

	for (i = 0; i < 16; i++){
		if (val & (1<<15))
		{
			s3c2410_gpio_setpin(S3C2410_GPB4,0);
			s3c2410_gpio_setpin(S3C2410_GPB3,1);
			udelay(1);
			s3c2410_gpio_setpin(S3C2410_GPB4,1);			
		}
		else
		{
			s3c2410_gpio_setpin(S3C2410_GPB4,0);
			s3c2410_gpio_setpin(S3C2410_GPB3,0);
			udelay(1);
			s3c2410_gpio_setpin(S3C2410_GPB4,1);			
		}

		val = val << 1;
	}

	s3c2410_gpio_setpin(S3C2410_GPB2,0);	
	udelay(1);
	s3c2410_gpio_setpin(S3C2410_GPB2,1);
	s3c2410_gpio_setpin(S3C2410_GPB3,1);
	s3c2410_gpio_setpin(S3C2410_GPB4,1);
	
	local_irq_restore(flags);	
}

2、修改控制器初始化函数init_wm8976

static void init_wm8976(void)
{
	uda1341_volume = 57;
	uda1341_boost = 0;

	wm8976_write_reg(0, 0);
	wm8976_write_reg(0x3, 0x6f);
	
	wm8976_write_reg(0x1, 0x1f);
	wm8976_write_reg(0x2, 0x185);

	wm8976_write_reg(0x6, 0x0);
	wm8976_write_reg(0x4, 0x10);		
	wm8976_write_reg(0x2B,0x10);  
	wm8976_write_reg(0x9, 0x50);
	wm8976_write_reg(0xD, 0x21);
	wm8976_write_reg(0x7, 0x01);
}

3、修改音量uda1341_volume相关设置smdk2410_mixer_ioctl

static int smdk2410_mixer_ioctl(struct inode *inode, struct file *file,
				unsigned int cmd, unsigned long arg)
{
	int ret;
	long val = 0;

	switch (cmd) {
		case SOUND_MIXER_INFO:
		{
			mixer_info info;
			strncpy(info.id, "UDA1341", sizeof(info.id));
			strncpy(info.name,"Philips UDA1341", sizeof(info.name));
			info.modify_counter = audio_mix_modcnt;
			return copy_to_user((void *)arg, &info, sizeof(info));
		}

		case SOUND_OLD_MIXER_INFO:
		{
			_old_mixer_info info;
			strncpy(info.id, "UDA1341", sizeof(info.id));
			strncpy(info.name,"Philips UDA1341", sizeof(info.name));
			return copy_to_user((void *)arg, &info, sizeof(info));
		}

		case SOUND_MIXER_READ_STEREODEVS:
			return put_user(0, (long *) arg);

		case SOUND_MIXER_READ_CAPS:
			val = SOUND_CAP_EXCL_INPUT;
			return put_user(val, (long *) arg);

		case SOUND_MIXER_WRITE_VOLUME:
			ret = get_user(val, (long *) arg);
			if (ret)
				return ret;

			uda1341_volume = (((val & 0xff) + 1) * 63) / 100;
			wm8976_write_reg(52, (1<<8)|uda1341_volume);
			wm8976_write_reg(53, (1<<8)|uda1341_volume);
			//uda1341_l3_address(UDA1341_REG_DATA0);
			//uda1341_l3_data(uda1341_volume);
			break;

		case SOUND_MIXER_READ_VOLUME:
			val = (uda1341_volume * 100) / 63;
			return put_user(val, (long *) arg);

		case SOUND_MIXER_READ_IGAIN:
			val = ((31- mixer_igain) * 100) / 31;
			return put_user(val, (int *) arg);

		case SOUND_MIXER_WRITE_IGAIN:
			ret = get_user(val, (int *) arg);
			if (ret)
				return ret;
			mixer_igain = 31 - (val * 31 / 100);
			/* use mixer gain channel 1*/
			//uda1341_l3_address(UDA1341_REG_DATA0);
			//uda1341_l3_data(EXTADDR(EXT0));
			//uda1341_l3_data(EXTDATA(EXT0_CH1_GAIN(mixer_igain)));
			break;

		default:
			DPRINTK("mixer ioctl %u unknown\n", cmd);
			return -ENOSYS;
	}

	audio_mix_modcnt++;
	return 0;
}

测试驱动:确认内核已经配置了I2S驱动,同时将s3c-wm8976.c编译到uImage里。

# ls -l /dev/dsp /dev/mixer
crw-rw----    1 0        0         14,   3 May 31 17:45 /dev/dsp
crw-rw----    1 0        0         14,   0 May 31 17:45 /dev/mixer
# cat Alarm01.wav > /dev/dsp
s3c2410-uda1341-superlp: audio_set_dsp_speed:44100 prescaler:66
# cat Alarm01.wav > /dev/dsp
s3c2410-uda1341-superlp: audio_set_dsp_speed:44100 prescaler:66
# cat /dev/dsp > good.bin
s3c2410-uda1341-superlp: audio_set_dsp_speed:44100 prescaler:66

# ls
Alarm01.wav      good.bin
# cat good.bin > /dev/dsp
s3c2410-uda1341-superlp: audio_set_dsp_speed:44100 prescaler:66
 

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值