aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConnor McAdams <conmanx360@gmail.com>2018-05-08 13:20:09 -0400
committerTakashi Iwai <tiwai@suse.de>2018-05-13 03:29:30 -0400
commit447fd8e9a88e466326a07c85c1344e45d3a6cddf (patch)
tree9662764edfa4341c62ae507c10425045e2532178
parent7e6ed62ebedb352be3a6f0907bcab25789db7914 (diff)
ALSA: hda/ca0132: add the ability to set src_id on scp commands
This patch adds the ability to change the src_id on scp commands, which is used in the dsp setup of the Recon3Di and the Sound Blaster Z. It also makes sure to maintain backwards compatibility with the older dspio_set_uint_param function, and sets it's src to the default 0x20. Signed-off-by: Connor McAdams <conmanx360@gmail.com> Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_ca0132.c86
1 files changed, 74 insertions, 12 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index dd98b7731dc4..3b83f07e8be7 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1583,8 +1583,8 @@ static int dspio_send_scp_message(struct hda_codec *codec,
1583 * Returns zero or a negative error code. 1583 * Returns zero or a negative error code.
1584 */ 1584 */
1585static int dspio_scp(struct hda_codec *codec, 1585static int dspio_scp(struct hda_codec *codec,
1586 int mod_id, int req, int dir, void *data, unsigned int len, 1586 int mod_id, int src_id, int req, int dir, const void *data,
1587 void *reply, unsigned int *reply_len) 1587 unsigned int len, void *reply, unsigned int *reply_len)
1588{ 1588{
1589 int status = 0; 1589 int status = 0;
1590 struct scp_msg scp_send, scp_reply; 1590 struct scp_msg scp_send, scp_reply;
@@ -1608,7 +1608,7 @@ static int dspio_scp(struct hda_codec *codec,
1608 return -EINVAL; 1608 return -EINVAL;
1609 } 1609 }
1610 1610
1611 scp_send.hdr = make_scp_header(mod_id, 0x20, (dir == SCP_GET), req, 1611 scp_send.hdr = make_scp_header(mod_id, src_id, (dir == SCP_GET), req,
1612 0, 0, 0, len/sizeof(unsigned int)); 1612 0, 0, 0, len/sizeof(unsigned int));
1613 if (data != NULL && len > 0) { 1613 if (data != NULL && len > 0) {
1614 len = min((unsigned int)(sizeof(scp_send.data)), len); 1614 len = min((unsigned int)(sizeof(scp_send.data)), len);
@@ -1665,15 +1665,24 @@ static int dspio_scp(struct hda_codec *codec,
1665 * Set DSP parameters 1665 * Set DSP parameters
1666 */ 1666 */
1667static int dspio_set_param(struct hda_codec *codec, int mod_id, 1667static int dspio_set_param(struct hda_codec *codec, int mod_id,
1668 int req, void *data, unsigned int len) 1668 int src_id, int req, const void *data, unsigned int len)
1669{ 1669{
1670 return dspio_scp(codec, mod_id, req, SCP_SET, data, len, NULL, NULL); 1670 return dspio_scp(codec, mod_id, src_id, req, SCP_SET, data, len, NULL,
1671 NULL);
1671} 1672}
1672 1673
1673static int dspio_set_uint_param(struct hda_codec *codec, int mod_id, 1674static int dspio_set_uint_param(struct hda_codec *codec, int mod_id,
1674 int req, unsigned int data) 1675 int req, const unsigned int data)
1675{ 1676{
1676 return dspio_set_param(codec, mod_id, req, &data, sizeof(unsigned int)); 1677 return dspio_set_param(codec, mod_id, 0x20, req, &data,
1678 sizeof(unsigned int));
1679}
1680
1681static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id,
1682 int req, const unsigned int data)
1683{
1684 return dspio_set_param(codec, mod_id, 0x00, req, &data,
1685 sizeof(unsigned int));
1677} 1686}
1678 1687
1679/* 1688/*
@@ -1685,8 +1694,9 @@ static int dspio_alloc_dma_chan(struct hda_codec *codec, unsigned int *dma_chan)
1685 unsigned int size = sizeof(dma_chan); 1694 unsigned int size = sizeof(dma_chan);
1686 1695
1687 codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n"); 1696 codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n");
1688 status = dspio_scp(codec, MASTERCONTROL, MASTERCONTROL_ALLOC_DMA_CHAN, 1697 status = dspio_scp(codec, MASTERCONTROL, 0x20,
1689 SCP_GET, NULL, 0, dma_chan, &size); 1698 MASTERCONTROL_ALLOC_DMA_CHAN, SCP_GET, NULL, 0,
1699 dma_chan, &size);
1690 1700
1691 if (status < 0) { 1701 if (status < 0) {
1692 codec_dbg(codec, "dspio_alloc_dma_chan: SCP Failed\n"); 1702 codec_dbg(codec, "dspio_alloc_dma_chan: SCP Failed\n");
@@ -1715,8 +1725,9 @@ static int dspio_free_dma_chan(struct hda_codec *codec, unsigned int dma_chan)
1715 codec_dbg(codec, " dspio_free_dma_chan() -- begin\n"); 1725 codec_dbg(codec, " dspio_free_dma_chan() -- begin\n");
1716 codec_dbg(codec, "dspio_free_dma_chan: chan=%d\n", dma_chan); 1726 codec_dbg(codec, "dspio_free_dma_chan: chan=%d\n", dma_chan);
1717 1727
1718 status = dspio_scp(codec, MASTERCONTROL, MASTERCONTROL_ALLOC_DMA_CHAN, 1728 status = dspio_scp(codec, MASTERCONTROL, 0x20,
1719 SCP_SET, &dma_chan, sizeof(dma_chan), NULL, &dummy); 1729 MASTERCONTROL_ALLOC_DMA_CHAN, SCP_SET, &dma_chan,
1730 sizeof(dma_chan), NULL, &dummy);
1720 1731
1721 if (status < 0) { 1732 if (status < 0) {
1722 codec_dbg(codec, "dspio_free_dma_chan: SCP Failed\n"); 1733 codec_dbg(codec, "dspio_free_dma_chan: SCP Failed\n");
@@ -3230,7 +3241,7 @@ static int tuning_ctl_set(struct hda_codec *codec, hda_nid_t nid,
3230 break; 3241 break;
3231 3242
3232 snd_hda_power_up(codec); 3243 snd_hda_power_up(codec);
3233 dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 3244 dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
3234 ca0132_tuning_ctls[i].req, 3245 ca0132_tuning_ctls[i].req,
3235 &(lookup[idx]), sizeof(unsigned int)); 3246 &(lookup[idx]), sizeof(unsigned int));
3236 snd_hda_power_down(codec); 3247 snd_hda_power_down(codec);
@@ -4616,6 +4627,27 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
4616 * Recon3Di r3di_setup_defaults sub functions. 4627 * Recon3Di r3di_setup_defaults sub functions.
4617 */ 4628 */
4618 4629
4630static void r3di_dsp_scp_startup(struct hda_codec *codec)
4631{
4632 unsigned int tmp;
4633
4634 tmp = 0x00000000;
4635 dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
4636
4637 tmp = 0x00000001;
4638 dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
4639
4640 tmp = 0x00000004;
4641 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4642
4643 tmp = 0x00000005;
4644 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4645
4646 tmp = 0x00000000;
4647 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4648
4649}
4650
4619static void r3di_dsp_initial_mic_setup(struct hda_codec *codec) 4651static void r3di_dsp_initial_mic_setup(struct hda_codec *codec)
4620{ 4652{
4621 unsigned int tmp; 4653 unsigned int tmp;
@@ -4733,6 +4765,34 @@ static void sbz_chipio_startup_data(struct hda_codec *codec)
4733 mutex_unlock(&spec->chipio_mutex); 4765 mutex_unlock(&spec->chipio_mutex);
4734} 4766}
4735 4767
4768/*
4769 * Sound Blaster Z uses these after DSP is loaded. Weird SCP commands
4770 * without a 0x20 source like normal.
4771 */
4772static void sbz_dsp_scp_startup(struct hda_codec *codec)
4773{
4774 unsigned int tmp;
4775
4776 tmp = 0x00000003;
4777 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4778
4779 tmp = 0x00000000;
4780 dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
4781
4782 tmp = 0x00000001;
4783 dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
4784
4785 tmp = 0x00000004;
4786 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4787
4788 tmp = 0x00000005;
4789 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4790
4791 tmp = 0x00000000;
4792 dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
4793
4794}
4795
4736static void sbz_dsp_initial_mic_setup(struct hda_codec *codec) 4796static void sbz_dsp_initial_mic_setup(struct hda_codec *codec)
4737{ 4797{
4738 unsigned int tmp; 4798 unsigned int tmp;
@@ -4811,6 +4871,7 @@ static void r3di_setup_defaults(struct hda_codec *codec)
4811 if (spec->dsp_state != DSP_DOWNLOADED) 4871 if (spec->dsp_state != DSP_DOWNLOADED)
4812 return; 4872 return;
4813 4873
4874 r3di_dsp_scp_startup(codec);
4814 4875
4815 r3di_dsp_initial_mic_setup(codec); 4876 r3di_dsp_initial_mic_setup(codec);
4816 4877
@@ -4855,6 +4916,7 @@ static void sbz_setup_defaults(struct hda_codec *codec)
4855 if (spec->dsp_state != DSP_DOWNLOADED) 4916 if (spec->dsp_state != DSP_DOWNLOADED)
4856 return; 4917 return;
4857 4918
4919 sbz_dsp_scp_startup(codec);
4858 4920
4859 sbz_init_analog_mics(codec); 4921 sbz_init_analog_mics(codec);
4860 4922