예제 #1
0
int rt5640_update_eqmode(
	struct snd_soc_codec *codec, int mode)
{
	struct rt56xx_ops *ioctl_ops = rt56xx_get_ioctl_ops();
	int i;
	static int eqmode;

	if(codec == NULL ||  mode >= RT5640_HWEQ_LEN)
		return -EINVAL;

	dev_dbg(codec->dev, "%s(): mode=%d\n", __func__, mode);
	if(mode == eqmode)
		return 0;

	for(i = 0; i <= EQ_REG_NUM; i++) {
		if(hweq_param[mode].reg[i])
			ioctl_ops->index_write(codec, hweq_param[mode].reg[i],
					hweq_param[mode].value[i]);
		else
			break;
	}
	snd_soc_update_bits(codec, RT5640_EQ_CTRL2, RT5640_EQ_CTRL_MASK,
					hweq_param[mode].ctrl);
	snd_soc_update_bits(codec, RT5640_EQ_CTRL1,
		RT5640_EQ_UPD, RT5640_EQ_UPD);
	snd_soc_update_bits(codec, RT5640_EQ_CTRL1, RT5640_EQ_UPD, 0);
	
	eqmode = mode;

	return 0;
}
예제 #2
0
int rt5640_update_eqmode(
	struct snd_soc_codec *codec, int mode, int set_custom_eqmode)
{
	struct rt56xx_ops *ioctl_ops = rt56xx_get_ioctl_ops();
	int i;
	static int current_eqmode = NORMAL;
	static int custom_eqmode = NORMAL;

	if(codec == NULL ||  mode >= RT5640_HWEQ_LEN)
		return -EINVAL;

	dev_dbg(codec->dev, "%s(): mode=%d set_custom_eqmode=%d\n", __func__, mode, set_custom_eqmode);

	if (set_custom_eqmode) {
		custom_eqmode = mode;
		if (!(snd_soc_read(codec, RT5640_PWR_DIG1) & (RT5640_PWR_DAC_L1 | RT5640_PWR_DAC_R1)))
			return 0;
	}

	if (mode == SPK || mode == HP)
		if (custom_eqmode != NORMAL)
			mode = custom_eqmode;

	if(mode == current_eqmode)
		return 0;

	for(i = 0; i < EQ_REG_NUM; i++) {
		if(hweq_param[mode].reg[i])
			ioctl_ops->index_write(codec, hweq_param[mode].reg[i],
					hweq_param[mode].value[i]);
		else
			break;
	}
	snd_soc_update_bits(codec, RT5640_EQ_CTRL2, RT5640_EQ_CTRL_MASK,
					hweq_param[mode].ctrl);
	snd_soc_update_bits(codec, RT5640_EQ_CTRL1,
		RT5640_EQ_UPD, RT5640_EQ_UPD);
	snd_soc_update_bits(codec, RT5640_EQ_CTRL1, RT5640_EQ_UPD, 0);
	
	current_eqmode = mode;

	return 0;
}
예제 #3
0
int rt5640_ioctl_common(struct snd_hwdep *hw, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct snd_soc_codec *codec = hw->private_data;
	struct rt56xx_cmd __user *_rt56xx = (struct rt56xx_cmd *)arg;
	struct rt56xx_cmd rt56xx;
	struct rt56xx_ops *ioctl_ops = rt56xx_get_ioctl_ops();
	int *buf, mask1 = 0, mask2 = 0;
	static int eq_mode;

	if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx))) {
		dev_err(codec->dev,"copy_from_user faild\n");
		return -EFAULT;
	}
	dev_dbg(codec->dev, "%s(): rt56xx.number=%d, cmd=%d\n",
			__func__, rt56xx.number, cmd);
	buf = kmalloc(sizeof(*buf) * rt56xx.number, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;
	if (copy_from_user(buf, rt56xx.buf, sizeof(*buf) * rt56xx.number)) {
		goto err;
	}
	
	switch (cmd) {
	case RT_SET_CODEC_HWEQ_IOCTL:
		if (eq_mode == *buf)
			break;
		eq_mode = *buf;
		rt5640_update_eqmode(codec, eq_mode);
		break;

	case RT_GET_CODEC_ID:
		*buf = snd_soc_read(codec, RT5640_VENDOR_ID2);
		if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_SET_CODEC_SPK_VOL_IOCTL:
		if(*(buf) <= 0x27) {
			snd_soc_update_bits(codec, RT5640_SPK_VOL,
				RT5640_L_VOL_MASK | RT5640_R_VOL_MASK,
				*(buf) << RT5640_L_VOL_SFT |
				*(buf) << RT5640_R_VOL_SFT);
		}
		break;

	case RT_SET_CODEC_MIC_GAIN_IOCTL:
		if(*(buf) <= 0x8) {
			snd_soc_update_bits(codec, RT5640_IN1_IN2,
				RT5640_BST_MASK1, *(buf) << RT5640_BST_SFT1);
			snd_soc_update_bits(codec, RT5640_IN3_IN4,
				RT5640_BST_MASK2, *(buf) << RT5640_BST_SFT2);
		}
		break;

	case RT_SET_CODEC_3D_SPK_IOCTL:
		if(rt56xx.number < 4)
			break;
		if (NULL == ioctl_ops->index_update_bits)
			break;

		mask1 = 0;
		if(*buf != -1)
			mask1 |= RT5640_3D_SPK_MASK;
		if(*(buf + 1) != -1)
			mask1 |= RT5640_3D_SPK_M_MASK;
		if(*(buf + 2) != -1)
			mask1 |= RT5640_3D_SPK_CG_MASK;
		if(*(buf + 3) != -1)
			mask1 |= RT5640_3D_SPK_SG_MASK;
		ioctl_ops->index_update_bits(codec, RT5640_3D_SPK, mask1,
			*(buf) << RT5640_3D_SPK_SFT |
			*(buf + 1) << RT5640_3D_SPK_M_SFT |
			*(buf + 2) << RT5640_3D_SPK_CG_SFT |
			*(buf + 3) << RT5640_3D_SPK_SG_SFT);
		break;

	case RT_SET_CODEC_MP3PLUS_IOCTL:
		if(rt56xx.number < 5)
			break;
		mask1 = mask2 = 0;
		if(*buf != -1)
			mask1 |= RT5640_M_MP3_MASK;
		if(*(buf + 1) != -1)
			mask1 |= RT5640_EG_MP3_MASK;
		if(*(buf + 2) != -1)
			mask2 |= RT5640_OG_MP3_MASK;
		if(*(buf + 3) != -1)
			mask2 |= RT5640_HG_MP3_MASK;
		if(*(buf + 4) != -1)
			mask2 |= RT5640_MP3_WT_MASK;
		
		snd_soc_update_bits(codec, RT5640_MP3_PLUS1, mask1,
			*(buf) << RT5640_M_MP3_SFT |
			*(buf + 1) << RT5640_EG_MP3_SFT);
		snd_soc_update_bits(codec, RT5640_MP3_PLUS2, mask2,
			*(buf + 2) << RT5640_OG_MP3_SFT |
			*(buf + 3) << RT5640_HG_MP3_SFT |
			*(buf + 4) << RT5640_MP3_WT_SFT);
		break;
	case RT_SET_CODEC_3D_HEADPHONE_IOCTL:
		if(rt56xx.number < 4)
			break;
		if (NULL == ioctl_ops->index_update_bits)
			break;

		mask1 = 0;
		if(*buf != -1)
			mask1 |= RT5640_3D_HP_MASK;
		if(*(buf + 1) != -1)
			mask1 |= RT5640_3D_BT_MASK;
		if(*(buf + 2) != -1)
			mask1 |= RT5640_3D_1F_MIX_MASK;
		if(*(buf + 3) != -1)
			mask1 |= RT5640_3D_HP_M_MASK;

		snd_soc_update_bits(codec, RT5640_3D_HP, mask1,
			*(buf)<<RT5640_3D_HP_SFT |
			*(buf + 1) << RT5640_3D_BT_SFT |
			*(buf + 2) << RT5640_3D_1F_MIX_SFT |
			*(buf + 3) << RT5640_3D_HP_M_SFT);
		if(*(buf + 4) != -1)
			ioctl_ops->index_update_bits(codec,
					0x59, 0x1f, *(buf+4));
		break;

	case RT_SET_CODEC_BASS_BACK_IOCTL:
		if(rt56xx.number < 3)
			break;
		mask1 = 0;
		if(*buf != -1)
			mask1 |= RT5640_BB_MASK;
		if(*(buf + 1) != -1)
			mask1 |= RT5640_BB_CT_MASK;
		if(*(buf + 2) != -1)
			mask1 |= RT5640_G_BB_BST_MASK;
		
		snd_soc_update_bits(codec, RT5640_BASE_BACK, mask1,
			*(buf) << RT5640_BB_SFT |
			*(buf + 1) << RT5640_BB_CT_SFT |
			*(buf + 2) << RT5640_G_BB_BST_SFT);
		break;

	case RT_SET_CODEC_DIPOLE_SPK_IOCTL:
		if(rt56xx.number < 2)
			break;
		if (NULL == ioctl_ops->index_update_bits)
			break;

		mask1 = 0;
		if(*buf != -1)
			mask1 |= RT5640_DP_SPK_MASK;
		if(*(buf + 1) != -1)
			mask1 |= RT5640_DP_ATT_MASK;
		
		ioctl_ops->index_update_bits(codec, RT5640_DIP_SPK_INF,
			mask1, *(buf) << RT5640_DP_SPK_SFT |
			*(buf + 1) << RT5640_DP_ATT_SFT );
		break;

	case RT_SET_CODEC_DRC_AGC_ENABLE_IOCTL:
		if(rt56xx.number < 2)
			break;
		set_drc_agc_enable(codec, *(buf), *(buf + 1));
		break;

	case RT_SET_CODEC_DRC_AGC_PAR_IOCTL:
		if(rt56xx.number < 4)
			break;
		set_drc_agc_parameters(codec, *(buf), *(buf + 1),
				*(buf + 2), *(buf + 3));
		break;

	case RT_SET_CODEC_DIGI_BOOST_GAIN_IOCTL:
		if(rt56xx.number < 2)
			break;
		set_digital_boost_gain(codec, *(buf), *(buf + 1));
		break;

	case RT_SET_CODEC_NOISE_GATE_IOCTL:
		if(rt56xx.number < 4)
			break;
		set_noise_gate(codec, *(buf), *(buf + 1),
				*(buf + 2), *(buf + 3));
		break;

	case RT_SET_CODEC_DRC_AGC_COMP_IOCTL:
		if(rt56xx.number < 2)
			break;
		set_drc_agc_compression(codec, *(buf), *(buf + 1));
		break;

	case RT_SET_CODEC_WNR_ENABLE_IOCTL:
		if (NULL == ioctl_ops->index_update_bits)
			break;

		ioctl_ops->index_update_bits(codec, RT5640_WND_1,
			RT5640_WND_MASK, *(buf) << RT5640_WND_SFT );
		break;

	case RT_GET_CODEC_DRC_AGC_ENABLE_IOCTL:
		if(rt56xx.number < 2)
			break;
		get_drc_agc_enable(codec, (buf), (buf + 1));
		if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_GET_CODEC_DRC_AGC_PAR_IOCTL:
		if(rt56xx.number < 4)
			break;
		get_drc_agc_parameters(codec, (buf), (buf + 1),
				(buf + 2), (buf + 3));
		if (copy_to_user(rt56xx.buf, buf,
			sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_GET_CODEC_DIGI_BOOST_GAIN_IOCTL:
		if(rt56xx.number < 2)
			break;
		get_digital_boost_gain(codec, (buf), (buf + 1));
		if (copy_to_user(rt56xx.buf, buf,
			sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_GET_CODEC_NOISE_GATE_IOCTL:
		if(rt56xx.number < 4)
			break;
		get_noise_gate(codec, (buf), (buf + 1), (buf + 2), (buf + 3));
		if (copy_to_user(rt56xx.buf, buf,
			sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_GET_CODEC_DRC_AGC_COMP_IOCTL:
		if(rt56xx.number < 2)
			break;
		get_drc_agc_compression(codec, (buf), (buf + 1));
		if (copy_to_user(rt56xx.buf, buf,
			sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_GET_CODEC_SPK_VOL_IOCTL:
		*buf = (snd_soc_read(codec, RT5640_SPK_VOL) & RT5640_L_VOL_MASK)
			>> RT5640_L_VOL_SFT;
		if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number))
			goto err;
		break;

	case RT_GET_CODEC_MIC_GAIN_IOCTL:
		*buf = (snd_soc_read(codec, RT5640_IN1_IN2) & RT5640_BST_MASK1)
			>> RT5640_BST_SFT1;
		if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number))
			goto err;
		break;
#if defined(CONFIG_SND_SOC_RT5642_MODULE) || defined(CONFIG_SND_SOC_RT5642)
	case RT_READ_CODEC_DSP_IOCTL:
	case RT_WRITE_CODEC_DSP_IOCTL:
	case RT_GET_CODEC_DSP_MODE_IOCTL:
		return rt56xx_dsp_ioctl_common(hw, file, cmd, arg);
#endif
	case RT_GET_CODEC_HWEQ_IOCTL:
	case RT_GET_CODEC_3D_SPK_IOCTL:
	case RT_GET_CODEC_MP3PLUS_IOCTL:
	case RT_GET_CODEC_3D_HEADPHONE_IOCTL:
	case RT_GET_CODEC_BASS_BACK_IOCTL:
	case RT_GET_CODEC_DIPOLE_SPK_IOCTL:
	default:
		break;
	}

	kfree(buf);
	return 0;

err:
	kfree(buf);
	return -EFAULT;
}