Beispiel #1
0
static int rt3261_dsp_patch_2(struct snd_soc_codec *codec)
{
	struct rt3261_dsp_param param;
	int ret, i;

	param.cmd_fmt = 0x0090;
	param.addr = 0x0064;
	param.data = 0x0000;
	param.cmd = RT3261_DSP_CMD_RW;
	ret = rt3261_dsp_write(codec, &param);
	if (ret < 0) {
		dev_err(codec->dev,
			"Fail to set DSP 2 bytes patch entrance: %d\n", ret);
		goto patch_err;
	}

	param.cmd_fmt = 0x00e0;
	param.cmd = RT3261_DSP_CMD_MW;
	for(i = 0; i < RT3261_DSP_PATCH2_NUM; i++) {
		param.addr = rt3261_dsp_p2_tab[i][0];
		param.data = rt3261_dsp_p2_tab[i][1];
		ret = rt3261_dsp_write(codec, &param);
		if (ret < 0) {
			dev_err(codec->dev, "Fail to patch Dsp: %d\n", ret);
			goto patch_err;
		}
	}

	return 0;

patch_err:

	return ret;
}
/**
 * rt3261_dsp_set_mode - Set DSP mode parameters.
 *
 * @codec: SoC audio codec device.
 * @mode: DSP mode.
 *
 * Set parameters of mode to DSP.
 * There are three modes which includes " mic AEC + NS + FENS",
 * "HFBF" and "Far-field pickup".
 *
 * Returns 0 for success or negative error code.
 */
static int rt3261_dsp_set_mode(struct snd_soc_codec *codec, int mode)
{
	struct rt3261_dsp_param param;
	int ret, i;
/*
	unsigned short (*mode_tab)[2];

	switch (mode) {
	case RT3261_DSP_AEC_NS_FENS:
		dev_info(codec->dev, "AEC\n");
		mode_tab = rt3261_dsp_aec_ns_fens;
		tab_num = RT3261_DSP_AEC_NUM;
		break;

	case RT3261_DSP_HFBF:
		dev_info(codec->dev, "Beamforming\n");
		mode_tab = rt3261_dsp_hfbf;
		tab_num = RT3261_DSP_HFBF_NUM;
		break;

	case RT3261_DSP_FFP:
		dev_info(codec->dev, "Far Field Pick-up\n");
		mode_tab = rt3261_dsp_ffp;
		tab_num = RT3261_DSP_FFP_NUM;
		break;

	case RT3261_DSP_DIS:
	default:
		dev_info(codec->dev, "Disable\n");
		return 0;
	}
*/
	param.cmd_fmt = 0x00e0;
	param.cmd = RT3261_DSP_CMD_MW;
	for (i = 0; i < RT3261_DSP_AEC_NUM; i++) {
		param.addr = rt3261_dsp_aec_ns_fens[i][0];
		param.data = rt3261_dsp_aec_ns_fens[i][1];
		ret = rt3261_dsp_write(codec, &param);
		if (ret < 0)
			goto mode_err;
	}

	return 0;

mode_err:

	dev_err(codec->dev, "Fail to set mode %d parameters: %d\n", mode, ret);
	return ret;
}
/**
 * rt3261_dsp_conf - Set DSP basic setting.
 *
 * @codec: SoC audio codec device.
 *
 * Set parameters of basic setting to DSP.
 *
 * Returns 0 for success or negative error code.
 */
static int rt3261_dsp_conf(struct snd_soc_codec *codec)
{
	struct rt3261_dsp_param param;
	int ret, i;

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_HI);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to power up DSP: %d\n", ret);
		goto conf_err;
	}

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_RST_PIN_MASK, RT3261_DSP_RST_PIN_LO);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
		goto conf_err;
	}

	mdelay(10);

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_RST_PIN_MASK | RT3261_DSP_CLK_MASK,
		RT3261_DSP_RST_PIN_HI | RT3261_DSP_CLK_384K);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to recover DSP: %d\n", ret);
		goto conf_err;
	}

	param.cmd_fmt = 0x00e0;
	param.cmd = RT3261_DSP_CMD_MW;
	for(i = 0; i < RT3261_DSP_INIT_NUM; i++) {
		param.addr = rt3261_dsp_init[i][0];
		param.data = rt3261_dsp_init[i][1];
		ret = rt3261_dsp_write(codec, &param);
		if (ret < 0) {
			dev_err(codec->dev, "Fail to config Dsp: %d\n", ret);
			goto conf_err;
		}
	}

	return 0;

conf_err:

	return ret;
}
/**
 * rt3261_dsp_rate - Set DSP rate setting.
 *
 * @codec: SoC audio codec device.
 * @rate: Sampling rate.
 *
 * Set parameters of sampling rate to DSP.
 *
 * Returns 0 for success or negative error code.
 */
static int rt3261_dsp_rate(struct snd_soc_codec *codec, int rate)
{
	struct rt3261_dsp_param param;
	int ret, i, tab_num;
	unsigned short (*rate_tab)[2];

	if (rate != 48000 &&  rate != 44100 && rate != 16000)
		return -EINVAL;

	if (rate > 44100) {
		rate_tab = rt3261_dsp_48;
		tab_num = RT3261_DSP_48_NUM;
	} else {
		if (rate > 16000) {
			rate_tab = rt3261_dsp_441;
			tab_num = RT3261_DSP_441_NUM;
		} else {
			rate_tab = rt3261_dsp_16;
			tab_num = RT3261_DSP_16_NUM;
		}
	}

	param.cmd_fmt = 0x00e0;
	param.cmd = RT3261_DSP_CMD_MW;
	for (i = 0; i < tab_num; i++) {
		param.addr = rate_tab[i][0];
		param.data = rate_tab[i][1];
		ret = rt3261_dsp_write(codec, &param);
		if (ret < 0)
			goto rate_err;
	}

	return 0;

rate_err:

	dev_err(codec->dev, "Fail to set rate %d parameters: %d\n", rate, ret);
	return ret;
}
int rt_codec_dsp_ioctl_common(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct rt_codec_cmd rt_codec;
	int *buf;
	int *p;
	int ret;
	struct rt3261_dsp_param param;

	//int mask1 = 0, mask2 = 0;

	struct rt_codec_cmd __user *_rt_codec = (struct rt_codec_cmd *)arg;
	struct snd_soc_codec *codec = hw->private_data;
	struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);

	if (copy_from_user(&rt_codec, _rt_codec, sizeof(rt_codec))) {
		dev_err(codec->dev, "copy_from_user faild\n");
		return -EFAULT;
	}
	dev_dbg(codec->dev, "rt_codec.number=%d\n",rt_codec.number);
	buf = kmalloc(sizeof(*buf) * rt_codec.number, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;
	if (copy_from_user(buf, rt_codec.buf, sizeof(*buf) * rt_codec.number)) {
		goto err;
	}

	ret = snd_soc_update_bits(codec, RT3261_PWR_DIG2,
		RT3261_PWR_I2S_DSP, RT3261_PWR_I2S_DSP);
	if (ret < 0) {
		dev_err(codec->dev,
			"Failed to power up DSP IIS interface: %d\n", ret);
		goto err;
	}

	switch (cmd) {
	case RT_READ_CODEC_DSP_IOCTL:
		for (p = buf; p < buf + rt_codec.number/2; p++)
			*(p+rt_codec.number/2) = rt3261_dsp_read(codec, *p);
		if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
			goto err;
		break;

	case RT_WRITE_CODEC_DSP_IOCTL:
		param.cmd_fmt = 0x00e0;
		param.cmd = RT3261_DSP_CMD_MW;
		p = buf;
		param.addr = *p;
		param.data = *(p+rt_codec.number/2);
		if(codec == NULL) {
			dev_dbg(codec->dev, "codec is null\n");
			break;
		}
		for (p = buf; p < buf + rt_codec.number/2; p++)
			rt3261_dsp_write(codec, &param);
		break;

	case RT_GET_CODEC_DSP_MODE_IOCTL:
		*buf = rt3261->dsp_sw;
		if (copy_to_user(rt_codec.buf, buf, sizeof(*buf) * rt_codec.number))
			goto err;
		break;

	default:
		dev_info(codec->dev, "unsported dsp command\n");
		break;
	}

	kfree(buf);
	return 0;

err:
	kfree(buf);
	return -EFAULT;
}
static ssize_t dsp_reg_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rt3261_priv *rt3261 = i2c_get_clientdata(client);
	struct snd_soc_codec *codec = rt3261->codec;
	struct rt3261_dsp_param param;
	unsigned int val=0,addr=0;
	int i;

	printk("register \"%s\" count=%d\n",buf,count);

	for(i=0;i<count;i++) //address
	{
		if(*(buf+i) <= '9' && *(buf+i)>='0')
		{
			addr = (addr << 4) | (*(buf+i)-'0');
		}
		else if(*(buf+i) <= 'f' && *(buf+i)>='a')
		{
			addr = (addr << 4) | ((*(buf+i)-'a')+0xa);
		}
		else if(*(buf+i) <= 'A' && *(buf+i)>='A')
		{
			addr = (addr << 4) | ((*(buf+i)-'A')+0xa);
		}
		else
		{
			break;
		}
	}
	 
	for(i=i+1 ;i<count;i++) //val
	{
		if(*(buf+i) <= '9' && *(buf+i)>='0')
		{
			val = (val << 4) | (*(buf+i)-'0');
		}
		else if(*(buf+i) <= 'f' && *(buf+i)>='a')
		{
			val = (val << 4) | ((*(buf+i)-'a')+0xa);
		}
		else if(*(buf+i) <= 'F' && *(buf+i)>='A')
		{
			val = (val << 4) | ((*(buf+i)-'A')+0xa);
			
		}
		else
		{
			break;
		}
	}
	printk("addr=0x%x val=0x%x\n",addr,val);
	if(i==count)
	{
		printk("0x%04x = 0x%04x\n",addr,rt3261_dsp_read(codec, addr));
	}
	else
	{
		param.cmd_fmt = 0x00e0;
		param.cmd = RT3261_DSP_CMD_MW;
		param.addr = addr;
		param.data = val;
		rt3261_dsp_write(codec, &param);
	}

	return count;
}
Beispiel #7
0
int rt3261_dsp_suspend(struct snd_soc_codec *codec, pm_message_t state)
{
	struct rt3261_dsp_param param;
	int ret;

	if (RT3261_VER_C == snd_soc_read(codec, RT3261_VENDOR_ID))
		return 0;

	ret = snd_soc_update_bits(codec, RT3261_PWR_DIG2,
		RT3261_PWR_I2S_DSP, RT3261_PWR_I2S_DSP);
	if (ret < 0) {
		dev_err(codec->dev,
			"Failed to power up DSP IIS interface: %d\n", ret);
		goto rsm_err;
	}

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_HI);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to power up DSP: %d\n", ret);
		goto rsm_err;
	}

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_RST_PIN_MASK, RT3261_DSP_RST_PIN_LO);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
		goto rsm_err;
	}

	mdelay(10);

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_RST_PIN_MASK, RT3261_DSP_RST_PIN_HI);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to recover DSP: %d\n", ret);
		goto rsm_err;
	}

	param.cmd_fmt = 0x00e0;
	param.addr = 0x3fd2;
	param.data = 0x0030;
	param.cmd = RT3261_DSP_CMD_MW;
	ret = rt3261_dsp_write(codec, &param);
	if (ret < 0) {
		dev_err(codec->dev,
			"Failed to Power up LDO of Dsp: %d\n", ret);
		goto rsm_err;
	}

	ret = snd_soc_update_bits(codec, RT3261_DSP_CTRL3,
		RT3261_DSP_PD_PIN_MASK, RT3261_DSP_PD_PIN_LO);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to power down DSP: %d\n", ret);
		goto rsm_err;
	}

	return 0;

rsm_err:

	return ret;
}