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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); } return count; }
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, ¶m); 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; }