⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pxa-wm8971.c

📁 声音播放器新片驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCTL1,0x00c0);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCTL2,0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCIN, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LADCIN,0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RADCIN,0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUTM1,0x0150);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUTM2,0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUTM1,0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUTM2,0x0150);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_MOUTM1,0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_MOUTM2, 0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUT2V, 0x0179);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUT2V, 0x0179);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_MOUTV, 0x0079);   /* 		ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LINVOL, 0x0097);		ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RINVOL, 0x0097);		ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUT1V, 0x0040);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUT1V, 0x0040);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LDAC, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RDAC, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUT1V, 0x0179);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUT1V, 0x0179);	//ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCDAC, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_AUDIO, 0x0002);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_SRATE, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LDAC, 0x01e0);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RDAC, 0x01e0);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_BASS, 0x000f);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_TREBLE, 0x000f);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ALC1, 0x007b);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ALC2, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ALC3, 0x0032);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_NGATE, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LADC, 0x00c3);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RADC, 0x00c3);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCTL1, 0x00c0);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCTL2, 0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ADCIN, 0x0100);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LADCIN, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RADCIN, 0x0000);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUTM1, 0x0150);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUTM2, 0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUTM1, 0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUTM2, 0x0150);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_MOUTM1, 0x0050);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_MOUTM2, 0x0150);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUT2V, 0x0179);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUT2V, 0x0179);	ret += wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_MOUTV, 0x0079);	*/out:		return ret != 0 ? -EIO : 0;}

#if 1static struct wm8971_mixer_t wm8971_mixer;
static int wm8971_mixer_ioctl( struct inode *inode, struct file *file,			unsigned int cmd, unsigned long arg){	int i, val = 0;	if (cmd == SOUND_MIXER_INFO) {		mixer_info info;		strncpy(info.id, wm8971_codec.name, sizeof(info.id));		strncpy(info.name, wm8971_codec.name, sizeof(info.name));		info.modify_counter = wm8971_codec.modcnt;		if (copy_to_user((void *)arg, &info, sizeof(info)))			return -EFAULT;		return 0;	}	if (cmd == SOUND_OLD_MIXER_INFO) {		_old_mixer_info info;		strncpy(info.id, wm8971_codec.name, sizeof(info.id));		strncpy(info.name, wm8971_codec.name, sizeof(info.name));		if (copy_to_user((void *)arg, &info, sizeof(info)))			return -EFAULT;		return 0;	}	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))		return -EINVAL;	if (cmd == OSS_GETVERSION)		return put_user(SOUND_VERSION, (int *)arg);	if (_SIOC_DIR(cmd) == _SIOC_READ) {		switch (_IOC_NR(cmd)) {			case SOUND_MIXER_DEVMASK: /* give them the supported mixers */				val = wm8971_codec.supported_mixers;				break;				//case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */			//	val = wm8971_codec.record_sources;			//	break;				case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */				val = wm8971_codec.stereo_mixers;				break;			case SOUND_MIXER_CAPS:				val = SOUND_CAP_EXCL_INPUT;				break;				default: /* read a specific mixer */				i = _IOC_NR(cmd);					//if (!supported_mixer(&wm8971_codec, i)) 				//	return -EINVAL;				val = wm8971_get_mixer(i);				break;			}			return put_user(val, (int *)arg);		}	if (_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) {		wm8971_codec.modcnt++;		if (get_user(val, (int *)arg))			return -EFAULT;		switch (_IOC_NR(cmd)) {		default: /* write a specific mixer */			i = _IOC_NR(cmd);			//if (!supported_mixer(&wm8971_codec, i)) 			//	return -EINVAL;			return wm8971_set_mixer(i, val);		}	}	return -EINVAL;}	/* ** NOT TESTED ** */		static int wm8971_get_mixer(int cmd){			int val = 0;	u16 r = 0,l = 0;		switch (cmd) {		case SOUND_MIXER_VOLUME: /* OUT1 Volume */			l = wm8971_read_reg_cache(WM8971_LOUT1V) & 0x7f;			r = wm8971_read_reg_cache(WM8971_ROUT1V) & 0x7f;			break;				case SOUND_MIXER_BASS:	/* bass */			l = wm8971_read_reg_cache(WM8971_BASS) & 0x0f;			break;		case SOUND_MIXER_TREBLE:	/* treble */			l = wm8971_read_reg_cache(WM8971_TREBLE) & 0x0f;			break;		case SOUND_MIXER_SYNTH:			break;					case SOUND_MIXER_PCM:			break;					case SOUND_MIXER_SPEAKER: /* OUT2 Volume */			l = wm8971_read_reg_cache(WM8971_LOUT2V) & 0x7f;			r = wm8971_read_reg_cache(WM8971_ROUT2V) & 0x7f;			break;		case SOUND_MIXER_LINE:				break;		case SOUND_MIXER_MIC:			//l = wm8971_read_reg_cache(WM8971_INCTL1) & 0x060;			//r = wm8971_read_reg_cache(WM8971_INCTL1) & 0x180;			break;					case SOUND_MIXER_CD:				break;					case SOUND_MIXER_IMIX:		/* Recording monitor */			break;		case SOUND_MIXER_ALTPCM:			break;					case SOUND_MIXER_RECLEV:	/* Recording level */			break;		case SOUND_MIXER_IGAIN:		/* Input gain */			l = wm8971_read_reg_cache(WM8971_LADC) & 0xff;			r = wm8971_read_reg_cache(WM8971_RADC) & 0xff;			break;		case SOUND_MIXER_OGAIN:		/* Output gain */				l = wm8971_read_reg_cache(WM8971_LDAC) & 0xff;			r = wm8971_read_reg_cache(WM8971_RDAC) & 0xff;						break;		default:			warn("unknown mixer IOCTL");			return -EINVAL;	}		/* mix left and right */	val = ((l << 8) & 0xff00) + (r & 0xff); 	return val;}/* ** NOT TESTED ** */static int wm8971_set_mixer(int cmd, int val){			int ret = 0;	u16 reg;	unsigned int left,right;	/* separate left and right settings */	right = ((val >> 8)  & 0xff) ;	left = (val  & 0xff) ;	if (right > 100) 		right = 100;	if (left > 100) 		left = 100;		switch (cmd) {		case SOUND_MIXER_VOLUME: /* volume OUT1 */			reg = wm8971_read_reg_cache(WM8971_LOUT1V) & 0x180;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUT1V, reg | left);			reg = wm8971_read_reg_cache(WM8971_ROUT1V) & 0x180;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUT1V, reg | right);			break;				case SOUND_MIXER_BASS:	/* bass */			reg = wm8971_read_reg_cache(WM8971_BASS) & 0x1f0;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_BASS, reg | (left & 0x0f));			break;		case SOUND_MIXER_TREBLE:	/* treble */			reg = wm8971_read_reg_cache(WM8971_TREBLE) & 0x1f0;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_TREBLE, reg | (left & 0x0f));			break;		case SOUND_MIXER_SYNTH:			break;					case SOUND_MIXER_PCM:			break;					case SOUND_MIXER_SPEAKER: /* volume OUT2 */			reg = wm8971_read_reg_cache(WM8971_LOUT2V) & 0x180;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LOUT2V, reg | left);			reg = wm8971_read_reg_cache(WM8971_ROUT1V) & 0x180;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_ROUT2V, reg | right);			break;		case SOUND_MIXER_LINE:				break;		case SOUND_MIXER_MIC:			break;					case SOUND_MIXER_CD:				break;					case SOUND_MIXER_IMIX:		/*  Recording monitor  */			break;		case SOUND_MIXER_ALTPCM:			break;					case SOUND_MIXER_RECLEV:	/* Recording level */			break;		case SOUND_MIXER_IGAIN:		/* Input gain LR ADC */			reg = wm8971_read_reg_cache(WM8971_LADC) & 0x100;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LADC, reg | left);			reg = wm8971_read_reg_cache(WM8971_RADC) & 0x100;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RADC, reg | right);			break;		case SOUND_MIXER_OGAIN:		/* Output gain LR DAC*/				reg = wm8971_read_reg_cache(WM8971_LDAC) & 0x100;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_LDAC, reg | left);			reg = wm8971_read_reg_cache(WM8971_RDAC) & 0x100;			wm8971_2w_write(wm8971_codec.wm8971_2w_client, WM8971_RDAC, reg | right);					break;		default:			warn("unknown mixer IOCTL");			ret = -EINVAL;			break;		}	return ret;}static struct file_operations wm8971_mixer_fops = {	ioctl:		wm8971_mixer_ioctl,	llseek:		no_llseek,	owner:		THIS_MODULE};#endifstatic struct file_operations wm8971_pcm_fops = {	open:		wm8971_pcm_open,	owner:		THIS_MODULE};/* WM8971 2 Wire layer */ 
static int __init pxa_wm8971_init(void){	int ret;	char proc_str[64];		printk("Wolfson WM8971 Audio Codec\n");	printk("Victor add audio driver\n", WM8971_VERSION);		/* get Bulverde I2C adapter */	if ((ret = i2c_add_driver(&wm8971_driver)) != 0) {		err("can't add i2c driver");				goto out;	}		/* initialise WM8971 */	if ((ret = wm8971_init()) != 0) {		err("can't initialise WM8971\n");		goto out;	}				/* register audio interfaces with kernel */	wm8971_pcm.dev_dsp = register_sound_dsp(&wm8971_pcm_fops, -1);	wm8971_mixer.dev_mixer = register_sound_mixer(&wm8971_mixer_fops, -1);			#ifdef CONFIG_PROC_FS	/* register proc interface */	sprintf(proc_str, "driver/%s", AUDIO_NAME);	if ((wm8971_codec.ps = create_proc_read_entry (proc_str, 0, NULL,					     wm8971_read_proc, &wm8971_codec)) == 0)		err("could not register proc interface /proc/%s", proc_str);#endif#ifdef CONFIG_PM	/* register with power manager */	if ((wm8971_codec.pm = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, wm8971_pm_event)) == 0)		err("could not register with power management");#endif#if defined (CONFIG_ARCH_MAINSTONE)	/* enable USB on the go MUX so we can use SSPFRM2 */	MST_MSCWR2 |= (1 << 5);	MST_MSCWR2 &= ~(1 << 6);		MST_MSCWR2 &= ~(1 << 2);#endif		return 0;	out:  	return ret;}/*  * unregister interfaces and clean up */static void __exit pxa_wm8971_exit(void){#if defined (CONFIG_ARCH_MAINSTONE)		/* disable USB on the go MUX so we can use ttyS0 */	MST_MSCWR2 &= ~(1 << 5);	MST_MSCWR2 |= (1 << 6);		MST_MSCWR2 |= (1 << 2);#endif	#ifdef CONFIG_PM	pm_unregister (wm8971_codec.pm);#endif	wm8971_power_down();	//unregister_sound_mixer(wm8971_mixer.dev_mixer);	wm8971_detach(wm8971_codec.wm8971_2w_client);	i2c_del_driver(&wm8971_driver);	ssp_exit(&wm8971_codec.ssp);}module_init(pxa_wm8971_init);module_exit(pxa_wm8971_exit);MODULE_DESCRIPTION("WM8971 driver");MODULE_AUTHOR("foxt");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -