mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	sound fixes for 6.3-rc1
A collection of various small fixes that have been gathered since the last PR. The majority of changes are for ASoC, and there is a small change in ASoC PCM core, but the rest are all for driver- specific fixes / quirks / updates. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmQCxUwOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE+ILQ/+JvzrQO16D2VzGogiVH0uZAtcmjRSB732yDvY TlYoT65bQAWKn5rGltMc6hfLNGHIrqG+0S/p0Wgwk9pJBL42BLDfWlLkDIQJvnil xx1f1ktLJ+NfQ/76FoJg4EpD2x3baiTB2JwhVAsnYAkSI2EyW6iVWfkWTFl1EErU baw2JKVzae6bFKwATms4QhkWK6u3boYd1HViuB58xE0qhBDvZjjnAr8uRmsljub4 43lKSkXbP9sLpyqWi6LApo4tqTV0DqEliSqG5rygLc1sbgqKhAFKgmB5Za5OqByn U2yhOqbKZACWO8QRqx286jfw/+YxY5wW2mECSkF301vLK8VPTRRLxbv7tDjRtfFm j3sCGMt3idvJaaTIZcLkuBJJyhLV8MUqSr86JosYVK5Pem9R4991f/++xvi8qLYz ypAitcyTD2wmDtX7fFKS3MMCfQAc7L3iiLIKfO4bmQtnKQa3J2+jluC8fYLq5Jiw Jh7lxpq/sorXXGXSph9SMy41Z0iBedlBABeTY0F5XeS4vkhrqRtX1XQYHdpQaAGx /7pd8sE1fTfsWbLotFi7gpyyEJ3WM9uz7QDrwa6KrxQYlbHhQhQ/Y0bV3O0SK+FA fs4QbQOWy/q1qs0vsyNCLyA8C34lNqallvzoSYEdK/qLcS/km56P8MJE1vd9BqNB lhzZjvo= =88Cc -----END PGP SIGNATURE----- Merge tag 'sound-fix-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of various small fixes that have been gathered since the last PR. The majority of changes are for ASoC, and there is a small change in ASoC PCM core, but the rest are all for driver- specific fixes / quirks / updates" * tag 'sound-fix-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (32 commits) ALSA: ice1712: Delete unreachable code in aureon_add_controls() ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls() ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC ALSA: hda/realtek: Improve support for Dell Precision 3260 ASoC: mediatek: mt8195: add missing initialization ASoC: mediatek: mt8188: add missing initialization ASoC: amd: yc: Add DMI entries to support HP OMEN 16-n0xxx (8A43) ASoC: zl38060 add gpiolib dependency ASoC: sam9g20ek: Disable capture unless building with microphone input ASoC: mt8192: Fix range for sidetone positive gain ASoC: mt8192: Report an error if when an invalid sidetone gain is written ASoC: mt8192: Fix event generation for controls ASoC: mt8192: Remove spammy log messages ASoC: mchp-pdmc: fix poc noise at capture startup ASoC: dt-bindings: sama7g5-pdmc: add microchip,startup-delay-us binding ASoC: soc-pcm: add option to start DMA after DAI ASoC: mt8183: Fix event generation for I2S DAI operations ASoC: mt8183: Remove spammy logging from I2S DAI driver ASoC: mt6358: Remove undefined HPx Mux enumeration values ASoC: mt6358: Validate Wake on Voice 2 writes ...
This commit is contained in:
		
						commit
						d172859ebf
					
				
					 23 changed files with 263 additions and 152 deletions
				
			
		| 
						 | 
					@ -23,6 +23,7 @@ properties:
 | 
				
			||||||
      - enum:
 | 
					      - enum:
 | 
				
			||||||
          - apple,t6000-mca
 | 
					          - apple,t6000-mca
 | 
				
			||||||
          - apple,t8103-mca
 | 
					          - apple,t8103-mca
 | 
				
			||||||
 | 
					          - apple,t8112-mca
 | 
				
			||||||
      - const: apple,mca
 | 
					      - const: apple,mca
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  reg:
 | 
					  reg:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,12 @@ properties:
 | 
				
			||||||
    maxItems: 4
 | 
					    maxItems: 4
 | 
				
			||||||
    uniqueItems: true
 | 
					    uniqueItems: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  microchip,startup-delay-us:
 | 
				
			||||||
 | 
					    description: |
 | 
				
			||||||
 | 
					      Specifies the delay in microseconds that needs to be applied after
 | 
				
			||||||
 | 
					      enabling the PDMC microphones to avoid unwanted noise due to microphones
 | 
				
			||||||
 | 
					      not being ready.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
required:
 | 
					required:
 | 
				
			||||||
  - compatible
 | 
					  - compatible
 | 
				
			||||||
  - reg
 | 
					  - reg
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,6 +190,8 @@ struct snd_soc_component_driver {
 | 
				
			||||||
	bool use_dai_pcm_id;	/* use DAI link PCM ID as PCM device number */
 | 
						bool use_dai_pcm_id;	/* use DAI link PCM ID as PCM device number */
 | 
				
			||||||
	int be_pcm_base;	/* base device ID for all BE PCMs */
 | 
						int be_pcm_base;	/* base device ID for all BE PCMs */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int start_dma_last;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
	const char *debugfs_prefix;
 | 
						const char *debugfs_prefix;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9260,6 +9260,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK),
 | 
						SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x1028, 0x0ac9, "Dell Precision 3260", ALC295_FIXUP_CHROME_BOOK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
 | 
						SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
 | 
						SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
 | 
						SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
 | 
				
			||||||
| 
						 | 
					@ -11617,6 +11618,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
 | 
						SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x870c, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
 | 
						SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
 | 
						SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2),
 | 
						SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1892,13 +1892,10 @@ static int aureon_add_controls(struct snd_ice1712 *ice)
 | 
				
			||||||
		unsigned char id;
 | 
							unsigned char id;
 | 
				
			||||||
		snd_ice1712_save_gpio_status(ice);
 | 
							snd_ice1712_save_gpio_status(ice);
 | 
				
			||||||
		id = aureon_cs8415_get(ice, CS8415_ID);
 | 
							id = aureon_cs8415_get(ice, CS8415_ID);
 | 
				
			||||||
 | 
							snd_ice1712_restore_gpio_status(ice);
 | 
				
			||||||
		if (id != 0x41)
 | 
							if (id != 0x41)
 | 
				
			||||||
			dev_info(ice->card->dev,
 | 
								dev_info(ice->card->dev,
 | 
				
			||||||
				 "No CS8415 chip. Skipping CS8415 controls.\n");
 | 
									 "No CS8415 chip. Skipping CS8415 controls.\n");
 | 
				
			||||||
		else if ((id & 0x0F) != 0x01)
 | 
					 | 
				
			||||||
			dev_info(ice->card->dev,
 | 
					 | 
				
			||||||
				 "Detected unsupported CS8415 rev. (%c)\n",
 | 
					 | 
				
			||||||
				 (char)((id & 0x0F) + 'A' - 1));
 | 
					 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
 | 
								for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
 | 
				
			||||||
				struct snd_kcontrol *kctl;
 | 
									struct snd_kcontrol *kctl;
 | 
				
			||||||
| 
						 | 
					@ -1909,7 +1906,6 @@ static int aureon_add_controls(struct snd_ice1712 *ice)
 | 
				
			||||||
					kctl->id.device = ice->pcm->device;
 | 
										kctl->id.device = ice->pcm->device;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		snd_ice1712_restore_gpio_status(ice);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,6 +255,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
 | 
				
			||||||
			DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
 | 
								DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.driver_data = &acp6x_card,
 | 
				
			||||||
 | 
							.matches = {
 | 
				
			||||||
 | 
								DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
 | 
				
			||||||
 | 
								DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.driver_data = &acp6x_card,
 | 
				
			||||||
 | 
							.matches = {
 | 
				
			||||||
 | 
								DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
 | 
				
			||||||
 | 
								DMI_MATCH(DMI_BOARD_NAME, "8A43"),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,6 @@
 | 
				
			||||||
#define SERDES_CONF_UNK3	BIT(14)
 | 
					#define SERDES_CONF_UNK3	BIT(14)
 | 
				
			||||||
#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
 | 
					#define SERDES_CONF_NO_DATA_FEEDBACK	BIT(15)
 | 
				
			||||||
#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
 | 
					#define SERDES_CONF_SYNC_SEL	GENMASK(18, 16)
 | 
				
			||||||
#define SERDES_CONF_SOME_RST	BIT(19)
 | 
					 | 
				
			||||||
#define REG_TX_SERDES_BITSTART	0x08
 | 
					#define REG_TX_SERDES_BITSTART	0x08
 | 
				
			||||||
#define REG_RX_SERDES_BITSTART	0x0c
 | 
					#define REG_RX_SERDES_BITSTART	0x0c
 | 
				
			||||||
#define REG_TX_SERDES_SLOTMASK	0x0c
 | 
					#define REG_TX_SERDES_SLOTMASK	0x0c
 | 
				
			||||||
| 
						 | 
					@ -203,15 +202,24 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_START:
 | 
						case SNDRV_PCM_TRIGGER_START:
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_RESUME:
 | 
						case SNDRV_PCM_TRIGGER_RESUME:
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 | 
						case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 | 
				
			||||||
 | 
							mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
 | 
				
			||||||
 | 
								   FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
 | 
				
			||||||
 | 
							mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
 | 
				
			||||||
 | 
								   FIELD_PREP(SERDES_CONF_SYNC_SEL, 7));
 | 
				
			||||||
		mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
 | 
							mca_modify(cl, serdes_unit + REG_SERDES_STATUS,
 | 
				
			||||||
			   SERDES_STATUS_EN | SERDES_STATUS_RST,
 | 
								   SERDES_STATUS_EN | SERDES_STATUS_RST,
 | 
				
			||||||
			   SERDES_STATUS_RST);
 | 
								   SERDES_STATUS_RST);
 | 
				
			||||||
		mca_modify(cl, serdes_conf, SERDES_CONF_SOME_RST,
 | 
							/*
 | 
				
			||||||
			   SERDES_CONF_SOME_RST);
 | 
							 * Experiments suggest that it takes at most ~1 us
 | 
				
			||||||
		readl_relaxed(cl->base + serdes_conf);
 | 
							 * for the bit to clear, so wait 2 us for good measure.
 | 
				
			||||||
		mca_modify(cl, serdes_conf, SERDES_STATUS_RST, 0);
 | 
							 */
 | 
				
			||||||
		WARN_ON(readl_relaxed(cl->base + REG_SERDES_STATUS) &
 | 
							udelay(2);
 | 
				
			||||||
 | 
							WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
 | 
				
			||||||
			SERDES_STATUS_RST);
 | 
								SERDES_STATUS_RST);
 | 
				
			||||||
 | 
							mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
 | 
				
			||||||
 | 
								   FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
 | 
				
			||||||
 | 
							mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
 | 
				
			||||||
 | 
								   FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -942,10 +950,17 @@ static int mca_pcm_new(struct snd_soc_component *component,
 | 
				
			||||||
		chan = mca_request_dma_channel(cl, i);
 | 
							chan = mca_request_dma_channel(cl, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (IS_ERR_OR_NULL(chan)) {
 | 
							if (IS_ERR_OR_NULL(chan)) {
 | 
				
			||||||
 | 
								mca_pcm_free(component, rtd->pcm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (chan && PTR_ERR(chan) == -EPROBE_DEFER)
 | 
				
			||||||
 | 
									return PTR_ERR(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			dev_err(component->dev, "unable to obtain DMA channel (stream %d cluster %d): %pe\n",
 | 
								dev_err(component->dev, "unable to obtain DMA channel (stream %d cluster %d): %pe\n",
 | 
				
			||||||
				i, cl->no, chan);
 | 
									i, cl->no, chan);
 | 
				
			||||||
			mca_pcm_free(component, rtd->pcm);
 | 
					
 | 
				
			||||||
 | 
								if (!chan)
 | 
				
			||||||
				return -EINVAL;
 | 
									return -EINVAL;
 | 
				
			||||||
 | 
								return PTR_ERR(chan);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cl->dma_chans[i] = chan;
 | 
							cl->dma_chans[i] = chan;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,6 +114,7 @@ struct mchp_pdmc {
 | 
				
			||||||
	struct clk *gclk;
 | 
						struct clk *gclk;
 | 
				
			||||||
	u32 pdmcen;
 | 
						u32 pdmcen;
 | 
				
			||||||
	u32 suspend_irq;
 | 
						u32 suspend_irq;
 | 
				
			||||||
 | 
						u32 startup_delay_us;
 | 
				
			||||||
	int mic_no;
 | 
						int mic_no;
 | 
				
			||||||
	int sinc_order;
 | 
						int sinc_order;
 | 
				
			||||||
	bool audio_filter_en;
 | 
						bool audio_filter_en;
 | 
				
			||||||
| 
						 | 
					@ -425,6 +426,7 @@ static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
 | 
				
			||||||
	.open = &mchp_pdmc_open,
 | 
						.open = &mchp_pdmc_open,
 | 
				
			||||||
	.close = &mchp_pdmc_close,
 | 
						.close = &mchp_pdmc_close,
 | 
				
			||||||
	.legacy_dai_naming = 1,
 | 
						.legacy_dai_naming = 1,
 | 
				
			||||||
 | 
						.start_dma_last = 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const unsigned int mchp_pdmc_1mic[] = {1};
 | 
					static const unsigned int mchp_pdmc_1mic[] = {1};
 | 
				
			||||||
| 
						 | 
					@ -632,6 +634,29 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void mchp_pdmc_noise_filter_workaround(struct mchp_pdmc *dd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 tmp, steps = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * PDMC doesn't wait for microphones' startup time thus the acquisition
 | 
				
			||||||
 | 
						 * may start before the microphones are ready leading to poc noises at
 | 
				
			||||||
 | 
						 * the beginning of capture. To avoid this, we need to wait 50ms (in
 | 
				
			||||||
 | 
						 * normal startup procedure) or 150 ms (worst case after resume from sleep
 | 
				
			||||||
 | 
						 * states) after microphones are enabled and then clear the FIFOs (by
 | 
				
			||||||
 | 
						 * reading the RHR 16 times) and possible interrupts before continuing.
 | 
				
			||||||
 | 
						 * Also, for this to work the DMA needs to be started after interrupts
 | 
				
			||||||
 | 
						 * are enabled.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						usleep_range(dd->startup_delay_us, dd->startup_delay_us + 5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (steps--)
 | 
				
			||||||
 | 
							regmap_read(dd->regmap, MCHP_PDMC_RHR, &tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clear interrupts. */
 | 
				
			||||||
 | 
						regmap_read(dd->regmap, MCHP_PDMC_ISR, &tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
 | 
					static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
 | 
				
			||||||
			     int cmd, struct snd_soc_dai *dai)
 | 
								     int cmd, struct snd_soc_dai *dai)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -644,15 +669,17 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
 | 
				
			||||||
	switch (cmd) {
 | 
						switch (cmd) {
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_RESUME:
 | 
						case SNDRV_PCM_TRIGGER_RESUME:
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_START:
 | 
						case SNDRV_PCM_TRIGGER_START:
 | 
				
			||||||
		/* Enable overrun and underrun error interrupts */
 | 
					 | 
				
			||||||
		regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
 | 
					 | 
				
			||||||
			     MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
 | 
					 | 
				
			||||||
		dd->suspend_irq = 0;
 | 
					 | 
				
			||||||
		fallthrough;
 | 
					 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 | 
						case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 | 
				
			||||||
		snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
 | 
							snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
 | 
				
			||||||
					      MCHP_PDMC_MR_PDMCEN_MASK,
 | 
										      MCHP_PDMC_MR_PDMCEN_MASK,
 | 
				
			||||||
					      dd->pdmcen);
 | 
										      dd->pdmcen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mchp_pdmc_noise_filter_workaround(dd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Enable interrupts. */
 | 
				
			||||||
 | 
							regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
 | 
				
			||||||
 | 
								     MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
 | 
				
			||||||
 | 
							dd->suspend_irq = 0;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_SUSPEND:
 | 
						case SNDRV_PCM_TRIGGER_SUSPEND:
 | 
				
			||||||
		regmap_read(dd->regmap, MCHP_PDMC_IMR, &dd->suspend_irq);
 | 
							regmap_read(dd->regmap, MCHP_PDMC_IMR, &dd->suspend_irq);
 | 
				
			||||||
| 
						 | 
					@ -796,6 +823,7 @@ static bool mchp_pdmc_readable_reg(struct device *dev, unsigned int reg)
 | 
				
			||||||
	case MCHP_PDMC_CFGR:
 | 
						case MCHP_PDMC_CFGR:
 | 
				
			||||||
	case MCHP_PDMC_IMR:
 | 
						case MCHP_PDMC_IMR:
 | 
				
			||||||
	case MCHP_PDMC_ISR:
 | 
						case MCHP_PDMC_ISR:
 | 
				
			||||||
 | 
						case MCHP_PDMC_RHR:
 | 
				
			||||||
	case MCHP_PDMC_VER:
 | 
						case MCHP_PDMC_VER:
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -817,6 +845,17 @@ static bool mchp_pdmc_writeable_reg(struct device *dev, unsigned int reg)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool mchp_pdmc_volatile_reg(struct device *dev, unsigned int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (reg) {
 | 
				
			||||||
 | 
						case MCHP_PDMC_ISR:
 | 
				
			||||||
 | 
						case MCHP_PDMC_RHR:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool mchp_pdmc_precious_reg(struct device *dev, unsigned int reg)
 | 
					static bool mchp_pdmc_precious_reg(struct device *dev, unsigned int reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (reg) {
 | 
						switch (reg) {
 | 
				
			||||||
| 
						 | 
					@ -836,6 +875,7 @@ static const struct regmap_config mchp_pdmc_regmap_config = {
 | 
				
			||||||
	.readable_reg	= mchp_pdmc_readable_reg,
 | 
						.readable_reg	= mchp_pdmc_readable_reg,
 | 
				
			||||||
	.writeable_reg	= mchp_pdmc_writeable_reg,
 | 
						.writeable_reg	= mchp_pdmc_writeable_reg,
 | 
				
			||||||
	.precious_reg	= mchp_pdmc_precious_reg,
 | 
						.precious_reg	= mchp_pdmc_precious_reg,
 | 
				
			||||||
 | 
						.volatile_reg	= mchp_pdmc_volatile_reg,
 | 
				
			||||||
	.cache_type	= REGCACHE_FLAT,
 | 
						.cache_type	= REGCACHE_FLAT,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -918,6 +958,9 @@ static int mchp_pdmc_dt_init(struct mchp_pdmc *dd)
 | 
				
			||||||
		dd->channel_mic_map[i].clk_edge = edge;
 | 
							dd->channel_mic_map[i].clk_edge = edge;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dd->startup_delay_us = 150000;
 | 
				
			||||||
 | 
						of_property_read_u32(np, "microchip,startup-delay-us", &dd->startup_delay_us);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,6 +98,9 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
 | 
				
			||||||
	.init = at91sam9g20ek_wm8731_init,
 | 
						.init = at91sam9g20ek_wm8731_init,
 | 
				
			||||||
	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 | 
						.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 | 
				
			||||||
		   SND_SOC_DAIFMT_CBP_CFP,
 | 
							   SND_SOC_DAIFMT_CBP_CFP,
 | 
				
			||||||
 | 
					#ifndef ENABLE_MIC_INPUT
 | 
				
			||||||
 | 
						.playback_only = true,
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	SND_SOC_DAILINK_REG(pcm),
 | 
						SND_SOC_DAILINK_REG(pcm),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2103,6 +2103,7 @@ config SND_SOC_WSA883X
 | 
				
			||||||
config SND_SOC_ZL38060
 | 
					config SND_SOC_ZL38060
 | 
				
			||||||
	tristate "Microsemi ZL38060 Connected Home Audio Processor"
 | 
						tristate "Microsemi ZL38060 Connected Home Audio Processor"
 | 
				
			||||||
	depends on SPI_MASTER
 | 
						depends on SPI_MASTER
 | 
				
			||||||
 | 
						depends on GPIOLIB
 | 
				
			||||||
	select REGMAP
 | 
						select REGMAP
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Support for ZL38060 Connected Home Audio Processor from Microsemi,
 | 
						  Support for ZL38060 Connected Home Audio Processor from Microsemi,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,22 +444,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = {
 | 
				
			||||||
	.endianness		= 1,
 | 
						.endianness		= 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void adau7118_regulator_disable(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct adau7118_data *st = data;
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * If we fail to disable DVDD, don't bother in trying IOVDD. We
 | 
					 | 
				
			||||||
	 * actually don't want to be left in the situation where DVDD
 | 
					 | 
				
			||||||
	 * is enabled and IOVDD is disabled.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	ret = regulator_disable(st->dvdd);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	regulator_disable(st->iovdd);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int adau7118_regulator_setup(struct adau7118_data *st)
 | 
					static int adau7118_regulator_setup(struct adau7118_data *st)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	st->iovdd = devm_regulator_get(st->dev, "iovdd");
 | 
						st->iovdd = devm_regulator_get(st->dev, "iovdd");
 | 
				
			||||||
| 
						 | 
					@ -481,8 +465,7 @@ static int adau7118_regulator_setup(struct adau7118_data *st)
 | 
				
			||||||
		regcache_cache_only(st->map, true);
 | 
							regcache_cache_only(st->map, true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return devm_add_action_or_reset(st->dev, adau7118_regulator_disable,
 | 
						return 0;
 | 
				
			||||||
					st);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau7118_parset_dt(const struct adau7118_data *st)
 | 
					static int adau7118_parset_dt(const struct adau7118_data *st)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -339,11 +339,39 @@ static void da7219_aad_hptest_work(struct work_struct *work)
 | 
				
			||||||
				    SND_JACK_HEADSET | SND_JACK_LINEOUT);
 | 
									    SND_JACK_HEADSET | SND_JACK_LINEOUT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void da7219_aad_jack_det_work(struct work_struct *work)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct da7219_aad_priv *da7219_aad =
 | 
				
			||||||
 | 
							container_of(work, struct da7219_aad_priv, jack_det_work);
 | 
				
			||||||
 | 
						struct snd_soc_component *component = da7219_aad->component;
 | 
				
			||||||
 | 
						u8 srm_st;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&da7219_aad->jack_det_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
 | 
				
			||||||
 | 
						msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4);
 | 
				
			||||||
 | 
						/* Enable ground switch */
 | 
				
			||||||
 | 
						snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&da7219_aad->jack_det_mutex);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * IRQ
 | 
					 * IRQ
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static irqreturn_t da7219_aad_pre_irq_thread(int irq, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct da7219_aad_priv *da7219_aad = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!da7219_aad->jack_inserted)
 | 
				
			||||||
 | 
							schedule_work(&da7219_aad->jack_det_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return IRQ_WAKE_THREAD;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 | 
					static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct da7219_aad_priv *da7219_aad = data;
 | 
						struct da7219_aad_priv *da7219_aad = data;
 | 
				
			||||||
| 
						 | 
					@ -351,14 +379,9 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 | 
				
			||||||
	struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 | 
						struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
 | 
				
			||||||
	u8 events[DA7219_AAD_IRQ_REG_MAX];
 | 
						u8 events[DA7219_AAD_IRQ_REG_MAX];
 | 
				
			||||||
	u8 statusa, srm_st;
 | 
						u8 statusa;
 | 
				
			||||||
	int i, report = 0, mask = 0;
 | 
						int i, report = 0, mask = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK;
 | 
					 | 
				
			||||||
	msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4);
 | 
					 | 
				
			||||||
	/* Enable ground switch */
 | 
					 | 
				
			||||||
	snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Read current IRQ events */
 | 
						/* Read current IRQ events */
 | 
				
			||||||
	regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 | 
						regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
 | 
				
			||||||
			 events, DA7219_AAD_IRQ_REG_MAX);
 | 
								 events, DA7219_AAD_IRQ_REG_MAX);
 | 
				
			||||||
| 
						 | 
					@ -377,6 +400,9 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
 | 
				
			||||||
		events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
 | 
							events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
 | 
				
			||||||
		statusa);
 | 
							statusa);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!da7219_aad->jack_inserted)
 | 
				
			||||||
 | 
							cancel_work_sync(&da7219_aad->jack_det_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
 | 
						if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
 | 
				
			||||||
		/* Jack Insertion */
 | 
							/* Jack Insertion */
 | 
				
			||||||
		if (events[DA7219_AAD_IRQ_REG_A] &
 | 
							if (events[DA7219_AAD_IRQ_REG_A] &
 | 
				
			||||||
| 
						 | 
					@ -940,8 +966,9 @@ int da7219_aad_init(struct snd_soc_component *component)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
 | 
						INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
 | 
				
			||||||
	INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
 | 
						INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
 | 
				
			||||||
 | 
						INIT_WORK(&da7219_aad->jack_det_work, da7219_aad_jack_det_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = request_threaded_irq(da7219_aad->irq, NULL,
 | 
						ret = request_threaded_irq(da7219_aad->irq, da7219_aad_pre_irq_thread,
 | 
				
			||||||
				   da7219_aad_irq_thread,
 | 
									   da7219_aad_irq_thread,
 | 
				
			||||||
				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 | 
									   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 | 
				
			||||||
				   "da7219-aad", da7219_aad);
 | 
									   "da7219-aad", da7219_aad);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
#define __DA7219_AAD_H
 | 
					#define __DA7219_AAD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/timer.h>
 | 
					#include <linux/timer.h>
 | 
				
			||||||
 | 
					#include <linux/mutex.h>
 | 
				
			||||||
#include <sound/soc.h>
 | 
					#include <sound/soc.h>
 | 
				
			||||||
#include <sound/jack.h>
 | 
					#include <sound/jack.h>
 | 
				
			||||||
#include <sound/da7219-aad.h>
 | 
					#include <sound/da7219-aad.h>
 | 
				
			||||||
| 
						 | 
					@ -196,6 +197,9 @@ struct da7219_aad_priv {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct work_struct btn_det_work;
 | 
						struct work_struct btn_det_work;
 | 
				
			||||||
	struct work_struct hptest_work;
 | 
						struct work_struct hptest_work;
 | 
				
			||||||
 | 
						struct work_struct jack_det_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct mutex  jack_det_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_jack *jack;
 | 
						struct snd_soc_jack *jack;
 | 
				
			||||||
	bool micbias_resume_enable;
 | 
						bool micbias_resume_enable;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -560,6 +560,9 @@ static int mt6358_put_wov(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);
 | 
						struct mt6358_priv *priv = snd_soc_component_get_drvdata(c);
 | 
				
			||||||
	int enabled = ucontrol->value.integer.value[0];
 | 
						int enabled = ucontrol->value.integer.value[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enabled < 0 || enabled > 1)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (priv->wov_enabled != enabled) {
 | 
						if (priv->wov_enabled != enabled) {
 | 
				
			||||||
		if (enabled)
 | 
							if (enabled)
 | 
				
			||||||
			mt6358_enable_wov_phase2(priv);
 | 
								mt6358_enable_wov_phase2(priv);
 | 
				
			||||||
| 
						 | 
					@ -567,6 +570,8 @@ static int mt6358_put_wov(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
			mt6358_disable_wov_phase2(priv);
 | 
								mt6358_disable_wov_phase2(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		priv->wov_enabled = enabled;
 | 
							priv->wov_enabled = enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -632,9 +637,6 @@ static const char * const hp_in_mux_map[] = {
 | 
				
			||||||
	"Audio Playback",
 | 
						"Audio Playback",
 | 
				
			||||||
	"Test Mode",
 | 
						"Test Mode",
 | 
				
			||||||
	"HP Impedance",
 | 
						"HP Impedance",
 | 
				
			||||||
	"undefined1",
 | 
					 | 
				
			||||||
	"undefined2",
 | 
					 | 
				
			||||||
	"undefined3",
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int hp_in_mux_map_value[] = {
 | 
					static int hp_in_mux_map_value[] = {
 | 
				
			||||||
| 
						 | 
					@ -643,9 +645,6 @@ static int hp_in_mux_map_value[] = {
 | 
				
			||||||
	HP_MUX_HP,
 | 
						HP_MUX_HP,
 | 
				
			||||||
	HP_MUX_TEST_MODE,
 | 
						HP_MUX_TEST_MODE,
 | 
				
			||||||
	HP_MUX_HP_IMPEDANCE,
 | 
						HP_MUX_HP_IMPEDANCE,
 | 
				
			||||||
	HP_MUX_OPEN,
 | 
					 | 
				
			||||||
	HP_MUX_OPEN,
 | 
					 | 
				
			||||||
	HP_MUX_OPEN,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SOC_VALUE_ENUM_SINGLE_DECL(hpl_in_mux_map_enum,
 | 
					static SOC_VALUE_ENUM_SINGLE_DECL(hpl_in_mux_map_enum,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -569,7 +569,7 @@ static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
			ret += sma1303_regmap_update_bits(sma1303,
 | 
								ret += sma1303_regmap_update_bits(sma1303,
 | 
				
			||||||
					SMA1303_11_SYSTEM_CTRL2,
 | 
										SMA1303_11_SYSTEM_CTRL2,
 | 
				
			||||||
					SMA1303_LR_DATA_SW_MASK,
 | 
										SMA1303_LR_DATA_SW_MASK,
 | 
				
			||||||
					SMA1303_LR_DATA_SW_NORMAL,
 | 
										SMA1303_LR_DATA_SW_SWAP,
 | 
				
			||||||
					&temp);
 | 
										&temp);
 | 
				
			||||||
			if (temp == true)
 | 
								if (temp == true)
 | 
				
			||||||
				change = true;
 | 
									change = true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,6 +223,20 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
 | 
				
			||||||
					SOF_RT5682_SSP_AMP(2) |
 | 
										SOF_RT5682_SSP_AMP(2) |
 | 
				
			||||||
					SOF_RT5682_NUM_HDMIDEV(4)),
 | 
										SOF_RT5682_NUM_HDMIDEV(4)),
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.callback = sof_rt5682_quirk_cb,
 | 
				
			||||||
 | 
							.matches = {
 | 
				
			||||||
 | 
								DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
 | 
				
			||||||
 | 
								DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.driver_data = (void *)(SOF_RT5682_MCLK_EN |
 | 
				
			||||||
 | 
										SOF_RT5682_SSP_CODEC(2) |
 | 
				
			||||||
 | 
										SOF_SPEAKER_AMP_PRESENT |
 | 
				
			||||||
 | 
										SOF_MAX98360A_SPEAKER_AMP_PRESENT |
 | 
				
			||||||
 | 
										SOF_RT5682_SSP_AMP(0) |
 | 
				
			||||||
 | 
										SOF_RT5682_NUM_HDMIDEV(4)
 | 
				
			||||||
 | 
										),
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.callback = sof_rt5682_quirk_cb,
 | 
							.callback = sof_rt5682_quirk_cb,
 | 
				
			||||||
		.matches = {
 | 
							.matches = {
 | 
				
			||||||
| 
						 | 
					@ -1105,6 +1119,15 @@ static const struct platform_device_id board_ids[] = {
 | 
				
			||||||
					SOF_RT5682_SSP_AMP(1) |
 | 
										SOF_RT5682_SSP_AMP(1) |
 | 
				
			||||||
					SOF_RT5682_NUM_HDMIDEV(4)),
 | 
										SOF_RT5682_NUM_HDMIDEV(4)),
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.name = "mtl_mx98360_rt5682",
 | 
				
			||||||
 | 
							.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 | 
				
			||||||
 | 
										SOF_RT5682_SSP_CODEC(0) |
 | 
				
			||||||
 | 
										SOF_SPEAKER_AMP_PRESENT |
 | 
				
			||||||
 | 
										SOF_MAX98360A_SPEAKER_AMP_PRESENT |
 | 
				
			||||||
 | 
										SOF_RT5682_SSP_AMP(1) |
 | 
				
			||||||
 | 
										SOF_RT5682_NUM_HDMIDEV(4)),
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "jsl_rt5682",
 | 
							.name = "jsl_rt5682",
 | 
				
			||||||
		.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 | 
							.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,11 @@ static const struct snd_soc_acpi_codecs mtl_max98357a_amp = {
 | 
				
			||||||
	.codecs = {"MX98357A"}
 | 
						.codecs = {"MX98357A"}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_soc_acpi_codecs mtl_max98360a_amp = {
 | 
				
			||||||
 | 
						.num_codecs = 1,
 | 
				
			||||||
 | 
						.codecs = {"MX98360A"}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = {
 | 
					static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = {
 | 
				
			||||||
	.num_codecs = 2,
 | 
						.num_codecs = 2,
 | 
				
			||||||
	.codecs = {"10EC5682", "RTL5682"},
 | 
						.codecs = {"10EC5682", "RTL5682"},
 | 
				
			||||||
| 
						 | 
					@ -28,6 +33,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = {
 | 
				
			||||||
		.quirk_data = &mtl_max98357a_amp,
 | 
							.quirk_data = &mtl_max98357a_amp,
 | 
				
			||||||
		.sof_tplg_filename = "sof-mtl-max98357a-rt5682.tplg",
 | 
							.sof_tplg_filename = "sof-mtl-max98357a-rt5682.tplg",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.comp_ids = &mtl_rt5682_rt5682s_hp,
 | 
				
			||||||
 | 
							.drv_name = "mtl_mx98360_rt5682",
 | 
				
			||||||
 | 
							.machine_quirk = snd_soc_acpi_codec_list,
 | 
				
			||||||
 | 
							.quirk_data = &mtl_max98360a_amp,
 | 
				
			||||||
 | 
							.sof_tplg_filename = "sof-mtl-max98360a-rt5682.tplg",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{},
 | 
						{},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines);
 | 
					EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,16 +141,13 @@ static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
	struct mtk_afe_i2s_priv *i2s_priv;
 | 
						struct mtk_afe_i2s_priv *i2s_priv;
 | 
				
			||||||
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 | 
						struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 | 
				
			||||||
	int hd_en;
 | 
						int hd_en, change;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ucontrol->value.enumerated.item[0] >= e->items)
 | 
						if (ucontrol->value.enumerated.item[0] >= e->items)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hd_en = ucontrol->value.integer.value[0];
 | 
						hd_en = ucontrol->value.integer.value[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
 | 
					 | 
				
			||||||
		 __func__, kcontrol->id.name, hd_en);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 | 
						i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!i2s_priv) {
 | 
						if (!i2s_priv) {
 | 
				
			||||||
| 
						 | 
					@ -158,9 +155,10 @@ static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						change = i2s_priv->low_jitter_en != hd_en;
 | 
				
			||||||
	i2s_priv->low_jitter_en = hd_en;
 | 
						i2s_priv->low_jitter_en = hd_en;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return change;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
 | 
					static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
 | 
				
			||||||
| 
						 | 
					@ -276,9 +274,6 @@ static int mtk_apll_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 | 
						struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_PRE_PMU:
 | 
						case SND_SOC_DAPM_PRE_PMU:
 | 
				
			||||||
		if (strcmp(w->name, APLL1_W_NAME) == 0)
 | 
							if (strcmp(w->name, APLL1_W_NAME) == 0)
 | 
				
			||||||
| 
						 | 
					@ -307,9 +302,6 @@ static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
	struct mtk_afe_i2s_priv *i2s_priv;
 | 
						struct mtk_afe_i2s_priv *i2s_priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	i2s_priv = get_i2s_priv_by_name(afe, w->name);
 | 
						i2s_priv = get_i2s_priv_by_name(afe, w->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!i2s_priv) {
 | 
						if (!i2s_priv) {
 | 
				
			||||||
| 
						 | 
					@ -715,11 +707,6 @@ static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
 | 
				
			||||||
	unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT;
 | 
						unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
 | 
					 | 
				
			||||||
		 __func__,
 | 
					 | 
				
			||||||
		 i2s_id,
 | 
					 | 
				
			||||||
		 rate, format);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (i2s_priv) {
 | 
						if (i2s_priv) {
 | 
				
			||||||
		i2s_priv->rate = rate;
 | 
							i2s_priv->rate = rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -810,8 +797,6 @@ static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	apll = mt8183_get_apll_by_rate(afe, freq);
 | 
						apll = mt8183_get_apll_by_rate(afe, freq);
 | 
				
			||||||
	apll_rate = mt8183_get_apll_rate(afe, apll);
 | 
						apll_rate = mt8183_get_apll_rate(afe, apll);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -679,7 +679,6 @@ static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	unsigned int old_val;
 | 
						unsigned int old_val;
 | 
				
			||||||
	unsigned int mask;
 | 
						unsigned int mask;
 | 
				
			||||||
	unsigned int reg;
 | 
						unsigned int reg;
 | 
				
			||||||
	unsigned int shift;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (source >= e->items)
 | 
						if (source >= e->items)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -687,27 +686,22 @@ static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
 | 
						if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
 | 
				
			||||||
		reg = ETDM_OUT1_CON4;
 | 
							reg = ETDM_OUT1_CON4;
 | 
				
			||||||
		mask = ETDM_OUT_CON4_CLOCK_MASK;
 | 
							mask = ETDM_OUT_CON4_CLOCK_MASK;
 | 
				
			||||||
		shift = ETDM_OUT_CON4_CLOCK_SHIFT;
 | 
					 | 
				
			||||||
		val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
 | 
							val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
 | 
				
			||||||
	} else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
 | 
						} else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
 | 
				
			||||||
		reg = ETDM_OUT2_CON4;
 | 
							reg = ETDM_OUT2_CON4;
 | 
				
			||||||
		mask = ETDM_OUT_CON4_CLOCK_MASK;
 | 
							mask = ETDM_OUT_CON4_CLOCK_MASK;
 | 
				
			||||||
		shift = ETDM_OUT_CON4_CLOCK_SHIFT;
 | 
					 | 
				
			||||||
		val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
 | 
							val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
 | 
				
			||||||
	} else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
 | 
						} else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
 | 
				
			||||||
		reg = ETDM_OUT3_CON4;
 | 
							reg = ETDM_OUT3_CON4;
 | 
				
			||||||
		mask = ETDM_OUT_CON4_CLOCK_MASK;
 | 
							mask = ETDM_OUT_CON4_CLOCK_MASK;
 | 
				
			||||||
		shift = ETDM_OUT_CON4_CLOCK_SHIFT;
 | 
					 | 
				
			||||||
		val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
 | 
							val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);
 | 
				
			||||||
	} else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
 | 
						} else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
 | 
				
			||||||
		reg = ETDM_IN1_CON2;
 | 
							reg = ETDM_IN1_CON2;
 | 
				
			||||||
		mask = ETDM_IN_CON2_CLOCK_MASK;
 | 
							mask = ETDM_IN_CON2_CLOCK_MASK;
 | 
				
			||||||
		shift = ETDM_IN_CON2_CLOCK_SHIFT;
 | 
					 | 
				
			||||||
		val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);
 | 
							val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);
 | 
				
			||||||
	} else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
 | 
						} else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
 | 
				
			||||||
		reg = ETDM_IN2_CON2;
 | 
							reg = ETDM_IN2_CON2;
 | 
				
			||||||
		mask = ETDM_IN_CON2_CLOCK_MASK;
 | 
							mask = ETDM_IN_CON2_CLOCK_MASK;
 | 
				
			||||||
		shift = ETDM_IN_CON2_CLOCK_SHIFT;
 | 
					 | 
				
			||||||
		val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);
 | 
							val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -715,8 +709,6 @@ static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regmap_read(afe->regmap, reg, &old_val);
 | 
						regmap_read(afe->regmap, reg, &old_val);
 | 
				
			||||||
	old_val &= mask;
 | 
						old_val &= mask;
 | 
				
			||||||
	old_val >>= shift;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (old_val == val)
 | 
						if (old_val == val)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2506,6 +2498,9 @@ static void mt8188_dai_etdm_parse_of(struct mtk_base_afe *afe)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* etdm in only */
 | 
						/* etdm in only */
 | 
				
			||||||
	for (i = 0; i < 2; i++) {
 | 
						for (i = 0; i < 2; i++) {
 | 
				
			||||||
 | 
							dai_id = ETDM_TO_DAI_ID(i);
 | 
				
			||||||
 | 
							etdm_data = afe_priv->dai_priv[dai_id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snprintf(prop, sizeof(prop), "mediatek,%s-chn-disabled",
 | 
							snprintf(prop, sizeof(prop), "mediatek,%s-chn-disabled",
 | 
				
			||||||
			 of_afe_etdms[i].name);
 | 
								 of_afe_etdms[i].name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,9 +303,6 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
	struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
						struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
				
			||||||
	int mtkaif_dmic = afe_priv->mtkaif_dmic;
 | 
						int mtkaif_dmic = afe_priv->mtkaif_dmic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event, mtkaif_dmic);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_PRE_PMU:
 | 
						case SND_SOC_DAPM_PRE_PMU:
 | 
				
			||||||
		mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 1);
 | 
							mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 1);
 | 
				
			||||||
| 
						 | 
					@ -345,10 +342,6 @@ static int mtk_adda_ch34_ul_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
	int mtkaif_dmic = afe_priv->mtkaif_dmic_ch34;
 | 
						int mtkaif_dmic = afe_priv->mtkaif_dmic_ch34;
 | 
				
			||||||
	int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only;
 | 
						int mtkaif_adda6_only = afe_priv->mtkaif_adda6_only;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev,
 | 
					 | 
				
			||||||
		 "%s(), name %s, event 0x%x, mtkaif_dmic %d, mtkaif_adda6_only %d\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event, mtkaif_dmic, mtkaif_adda6_only);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_PRE_PMU:
 | 
						case SND_SOC_DAPM_PRE_PMU:
 | 
				
			||||||
		mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34,
 | 
							mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34,
 | 
				
			||||||
| 
						 | 
					@ -538,9 +531,6 @@ static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 | 
						struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), name %s, event 0x%x\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_PRE_PMU:
 | 
						case SND_SOC_DAPM_PRE_PMU:
 | 
				
			||||||
		mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 0);
 | 
							mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA, 0);
 | 
				
			||||||
| 
						 | 
					@ -564,9 +554,6 @@ static int mtk_adda_ch34_dl_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 | 
						struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), name %s, event 0x%x\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_PRE_PMU:
 | 
						case SND_SOC_DAPM_PRE_PMU:
 | 
				
			||||||
		mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34,
 | 
							mt8192_afe_gpio_request(afe->dev, true, MT8192_DAI_ADDA_CH34,
 | 
				
			||||||
| 
						 | 
					@ -604,19 +591,21 @@ static int stf_positive_gain_set(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
	struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
						struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
				
			||||||
	int gain_db = ucontrol->value.integer.value[0];
 | 
						int gain_db = ucontrol->value.integer.value[0];
 | 
				
			||||||
 | 
						bool change = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afe_priv->stf_positive_gain_db = gain_db;
 | 
						afe_priv->stf_positive_gain_db = gain_db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gain_db >= 0 && gain_db <= 24) {
 | 
						if (gain_db >= 0 && gain_db <= 24) {
 | 
				
			||||||
		regmap_update_bits(afe->regmap,
 | 
							regmap_update_bits_check(afe->regmap,
 | 
				
			||||||
					 AFE_SIDETONE_GAIN,
 | 
										 AFE_SIDETONE_GAIN,
 | 
				
			||||||
					 POSITIVE_GAIN_MASK_SFT,
 | 
										 POSITIVE_GAIN_MASK_SFT,
 | 
				
			||||||
				   (gain_db / 6) << POSITIVE_GAIN_SFT);
 | 
										 (gain_db / 6) << POSITIVE_GAIN_SFT,
 | 
				
			||||||
 | 
										 &change);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dev_warn(afe->dev, "%s(), gain_db %d invalid\n",
 | 
							return -EINVAL;
 | 
				
			||||||
			 __func__, gain_db);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
					
 | 
				
			||||||
 | 
						return change;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mt8192_adda_dmic_get(struct snd_kcontrol *kcontrol,
 | 
					static int mt8192_adda_dmic_get(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
| 
						 | 
					@ -637,15 +626,17 @@ static int mt8192_adda_dmic_set(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
	struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
						struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
				
			||||||
	int dmic_on;
 | 
						int dmic_on;
 | 
				
			||||||
 | 
						bool change;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dmic_on = ucontrol->value.integer.value[0];
 | 
						dmic_on = ucontrol->value.integer.value[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
 | 
						change = (afe_priv->mtkaif_dmic != dmic_on) ||
 | 
				
			||||||
		 __func__, kcontrol->id.name, dmic_on);
 | 
							(afe_priv->mtkaif_dmic_ch34 != dmic_on);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	afe_priv->mtkaif_dmic = dmic_on;
 | 
						afe_priv->mtkaif_dmic = dmic_on;
 | 
				
			||||||
	afe_priv->mtkaif_dmic_ch34 = dmic_on;
 | 
						afe_priv->mtkaif_dmic_ch34 = dmic_on;
 | 
				
			||||||
	return 0;
 | 
					
 | 
				
			||||||
 | 
						return change;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mt8192_adda6_only_get(struct snd_kcontrol *kcontrol,
 | 
					static int mt8192_adda6_only_get(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
| 
						 | 
					@ -666,20 +657,20 @@ static int mt8192_adda6_only_set(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
						struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 | 
				
			||||||
	struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
						struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
				
			||||||
	int mtkaif_adda6_only;
 | 
						int mtkaif_adda6_only;
 | 
				
			||||||
 | 
						bool change;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtkaif_adda6_only = ucontrol->value.integer.value[0];
 | 
						mtkaif_adda6_only = ucontrol->value.integer.value[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",
 | 
						change = afe_priv->mtkaif_adda6_only != mtkaif_adda6_only;
 | 
				
			||||||
		 __func__, kcontrol->id.name, mtkaif_adda6_only);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	afe_priv->mtkaif_adda6_only = mtkaif_adda6_only;
 | 
						afe_priv->mtkaif_adda6_only = mtkaif_adda6_only;
 | 
				
			||||||
	return 0;
 | 
					
 | 
				
			||||||
 | 
						return change;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_kcontrol_new mtk_adda_controls[] = {
 | 
					static const struct snd_kcontrol_new mtk_adda_controls[] = {
 | 
				
			||||||
	SOC_SINGLE("Sidetone_Gain", AFE_SIDETONE_GAIN,
 | 
						SOC_SINGLE("Sidetone_Gain", AFE_SIDETONE_GAIN,
 | 
				
			||||||
		   SIDE_TONE_GAIN_SFT, SIDE_TONE_GAIN_MASK, 0),
 | 
							   SIDE_TONE_GAIN_SFT, SIDE_TONE_GAIN_MASK, 0),
 | 
				
			||||||
	SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 100, 0,
 | 
						SOC_SINGLE_EXT("Sidetone_Positive_Gain_dB", SND_SOC_NOPM, 0, 24, 0,
 | 
				
			||||||
		       stf_positive_gain_get, stf_positive_gain_set),
 | 
							       stf_positive_gain_get, stf_positive_gain_set),
 | 
				
			||||||
	SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
 | 
						SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
 | 
				
			||||||
		   DL_2_GAIN_CTL_PRE_SFT, DL_2_GAIN_CTL_PRE_MASK, 0),
 | 
							   DL_2_GAIN_CTL_PRE_SFT, DL_2_GAIN_CTL_PRE_MASK, 0),
 | 
				
			||||||
| 
						 | 
					@ -750,9 +741,6 @@ static int mtk_stf_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regmap_read(afe->regmap, AFE_SIDETONE_CON1, ®_value);
 | 
						regmap_read(afe->regmap, AFE_SIDETONE_CON1, ®_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), name %s, event 0x%x, ul_rate 0x%x, AFE_SIDETONE_CON1 0x%x\n",
 | 
					 | 
				
			||||||
		 __func__, w->name, event, ul_rate, reg_value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_PRE_PMU:
 | 
						case SND_SOC_DAPM_PRE_PMU:
 | 
				
			||||||
		/* set side tone gain = 0 */
 | 
							/* set side tone gain = 0 */
 | 
				
			||||||
| 
						 | 
					@ -1163,12 +1151,6 @@ static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	unsigned int rate = params_rate(params);
 | 
						unsigned int rate = params_rate(params);
 | 
				
			||||||
	int id = dai->id;
 | 
						int id = dai->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
 | 
					 | 
				
			||||||
		 __func__,
 | 
					 | 
				
			||||||
		 id,
 | 
					 | 
				
			||||||
		 substream->stream,
 | 
					 | 
				
			||||||
		 rate);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 | 
						if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 | 
				
			||||||
		unsigned int dl_src2_con0 = 0;
 | 
							unsigned int dl_src2_con0 = 0;
 | 
				
			||||||
		unsigned int dl_src2_con1 = 0;
 | 
							unsigned int dl_src2_con1 = 0;
 | 
				
			||||||
| 
						 | 
					@ -1441,8 +1423,6 @@ int mt8192_dai_adda_register(struct mtk_base_afe *afe)
 | 
				
			||||||
	struct mtk_base_afe_dai *dai;
 | 
						struct mtk_base_afe_dai *dai;
 | 
				
			||||||
	struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
						struct mt8192_afe_private *afe_priv = afe->platform_priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(afe->dev, "%s()\n", __func__);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
 | 
						dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
 | 
				
			||||||
	if (!dai)
 | 
						if (!dai)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2567,6 +2567,9 @@ static void mt8195_dai_etdm_parse_of(struct mtk_base_afe *afe)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* etdm in only */
 | 
						/* etdm in only */
 | 
				
			||||||
	for (i = 0; i < 2; i++) {
 | 
						for (i = 0; i < 2; i++) {
 | 
				
			||||||
 | 
							dai_id = ETDM_TO_DAI_ID(i);
 | 
				
			||||||
 | 
							etdm_data = afe_priv->dai_priv[dai_id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = snprintf(prop, sizeof(prop),
 | 
							ret = snprintf(prop, sizeof(prop),
 | 
				
			||||||
			       "mediatek,%s-chn-disabled",
 | 
								       "mediatek,%s-chn-disabled",
 | 
				
			||||||
			       of_afe_etdms[i].name);
 | 
								       of_afe_etdms[i].name);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,10 +39,10 @@ struct rsnd_adg {
 | 
				
			||||||
	int clkin_size;
 | 
						int clkin_size;
 | 
				
			||||||
	int clkout_size;
 | 
						int clkout_size;
 | 
				
			||||||
	u32 ckr;
 | 
						u32 ckr;
 | 
				
			||||||
	u32 rbga;
 | 
						u32 brga;
 | 
				
			||||||
	u32 rbgb;
 | 
						u32 brgb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int rbg_rate[ADG_HZ_SIZE]; /* RBGA / RBGB */
 | 
						int brg_rate[ADG_HZ_SIZE]; /* BRGA / BRGB */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define for_each_rsnd_clkin(pos, adg, i)	\
 | 
					#define for_each_rsnd_clkin(pos, adg, i)	\
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ static const char * const clkout_name_gen2[] = {
 | 
				
			||||||
	[CLKOUT3] = "audio_clkout3",
 | 
						[CLKOUT3] = "audio_clkout3",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u32 rsnd_adg_calculate_rbgx(unsigned long div)
 | 
					static u32 rsnd_adg_calculate_brgx(unsigned long div)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,8 +131,8 @@ static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
 | 
				
			||||||
		adg->clkin_rate[CLKA],	/* 0000: CLKA */
 | 
							adg->clkin_rate[CLKA],	/* 0000: CLKA */
 | 
				
			||||||
		adg->clkin_rate[CLKB],	/* 0001: CLKB */
 | 
							adg->clkin_rate[CLKB],	/* 0001: CLKB */
 | 
				
			||||||
		adg->clkin_rate[CLKC],	/* 0010: CLKC */
 | 
							adg->clkin_rate[CLKC],	/* 0010: CLKC */
 | 
				
			||||||
		adg->rbg_rate[ADG_HZ_441],	/* 0011: RBGA */
 | 
							adg->brg_rate[ADG_HZ_441],	/* 0011: BRGA */
 | 
				
			||||||
		adg->rbg_rate[ADG_HZ_48],	/* 0100: RBGB */
 | 
							adg->brg_rate[ADG_HZ_48],	/* 0100: BRGB */
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	min = ~0;
 | 
						min = ~0;
 | 
				
			||||||
| 
						 | 
					@ -323,10 +323,10 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * find divided clock from BRGA/BRGB
 | 
						 * find divided clock from BRGA/BRGB
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (rate == adg->rbg_rate[ADG_HZ_441])
 | 
						if (rate == adg->brg_rate[ADG_HZ_441])
 | 
				
			||||||
		return 0x10;
 | 
							return 0x10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rate == adg->rbg_rate[ADG_HZ_48])
 | 
						if (rate == adg->brg_rate[ADG_HZ_48])
 | 
				
			||||||
		return 0x20;
 | 
							return 0x20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return -EIO;
 | 
						return -EIO;
 | 
				
			||||||
| 
						 | 
					@ -358,13 +358,13 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
 | 
				
			||||||
		ckr = 0x80000000; /* BRGB output = 48kHz */
 | 
							ckr = 0x80000000; /* BRGB output = 48kHz */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
 | 
						rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr | ckr);
 | 
				
			||||||
	rsnd_mod_write(adg_mod, BRRA,  adg->rbga);
 | 
						rsnd_mod_write(adg_mod, BRRA,  adg->brga);
 | 
				
			||||||
	rsnd_mod_write(adg_mod, BRRB,  adg->rbgb);
 | 
						rsnd_mod_write(adg_mod, BRRB,  adg->brgb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n",
 | 
						dev_dbg(dev, "CLKOUT is based on BRG%c (= %dHz)\n",
 | 
				
			||||||
		(ckr) ? 'B' : 'A',
 | 
							(ckr) ? 'B' : 'A',
 | 
				
			||||||
		(ckr) ?	adg->rbg_rate[ADG_HZ_48] :
 | 
							(ckr) ?	adg->brg_rate[ADG_HZ_48] :
 | 
				
			||||||
			adg->rbg_rate[ADG_HZ_441]);
 | 
								adg->brg_rate[ADG_HZ_441]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -484,7 +484,7 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
 | 
				
			||||||
	struct device *dev = rsnd_priv_to_dev(priv);
 | 
						struct device *dev = rsnd_priv_to_dev(priv);
 | 
				
			||||||
	struct device_node *np = dev->of_node;
 | 
						struct device_node *np = dev->of_node;
 | 
				
			||||||
	struct property *prop;
 | 
						struct property *prop;
 | 
				
			||||||
	u32 ckr, rbgx, rbga, rbgb;
 | 
						u32 ckr, brgx, brga, brgb;
 | 
				
			||||||
	u32 rate, div;
 | 
						u32 rate, div;
 | 
				
			||||||
	u32 req_rate[ADG_HZ_SIZE] = {};
 | 
						u32 req_rate[ADG_HZ_SIZE] = {};
 | 
				
			||||||
	uint32_t count = 0;
 | 
						uint32_t count = 0;
 | 
				
			||||||
| 
						 | 
					@ -501,8 +501,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ckr = 0;
 | 
						ckr = 0;
 | 
				
			||||||
	rbga = 2; /* default 1/6 */
 | 
						brga = 2; /* default 1/6 */
 | 
				
			||||||
	rbgb = 2; /* default 1/6 */
 | 
						brgb = 2; /* default 1/6 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * ADG supports BRRA/BRRB output only
 | 
						 * ADG supports BRRA/BRRB output only
 | 
				
			||||||
| 
						 | 
					@ -543,30 +543,30 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
 | 
				
			||||||
		if (0 == rate) /* not used */
 | 
							if (0 == rate) /* not used */
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* RBGA */
 | 
							/* BRGA */
 | 
				
			||||||
		if (!adg->rbg_rate[ADG_HZ_441] && (0 == rate % 44100)) {
 | 
							if (!adg->brg_rate[ADG_HZ_441] && (0 == rate % 44100)) {
 | 
				
			||||||
			div = 6;
 | 
								div = 6;
 | 
				
			||||||
			if (req_Hz[ADG_HZ_441])
 | 
								if (req_Hz[ADG_HZ_441])
 | 
				
			||||||
				div = rate / req_Hz[ADG_HZ_441];
 | 
									div = rate / req_Hz[ADG_HZ_441];
 | 
				
			||||||
			rbgx = rsnd_adg_calculate_rbgx(div);
 | 
								brgx = rsnd_adg_calculate_brgx(div);
 | 
				
			||||||
			if (BRRx_MASK(rbgx) == rbgx) {
 | 
								if (BRRx_MASK(brgx) == brgx) {
 | 
				
			||||||
				rbga = rbgx;
 | 
									brga = brgx;
 | 
				
			||||||
				adg->rbg_rate[ADG_HZ_441] = rate / div;
 | 
									adg->brg_rate[ADG_HZ_441] = rate / div;
 | 
				
			||||||
				ckr |= brg_table[i] << 20;
 | 
									ckr |= brg_table[i] << 20;
 | 
				
			||||||
				if (req_Hz[ADG_HZ_441])
 | 
									if (req_Hz[ADG_HZ_441])
 | 
				
			||||||
					parent_clk_name = __clk_get_name(clk);
 | 
										parent_clk_name = __clk_get_name(clk);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* RBGB */
 | 
							/* BRGB */
 | 
				
			||||||
		if (!adg->rbg_rate[ADG_HZ_48] && (0 == rate % 48000)) {
 | 
							if (!adg->brg_rate[ADG_HZ_48] && (0 == rate % 48000)) {
 | 
				
			||||||
			div = 6;
 | 
								div = 6;
 | 
				
			||||||
			if (req_Hz[ADG_HZ_48])
 | 
								if (req_Hz[ADG_HZ_48])
 | 
				
			||||||
				div = rate / req_Hz[ADG_HZ_48];
 | 
									div = rate / req_Hz[ADG_HZ_48];
 | 
				
			||||||
			rbgx = rsnd_adg_calculate_rbgx(div);
 | 
								brgx = rsnd_adg_calculate_brgx(div);
 | 
				
			||||||
			if (BRRx_MASK(rbgx) == rbgx) {
 | 
								if (BRRx_MASK(brgx) == brgx) {
 | 
				
			||||||
				rbgb = rbgx;
 | 
									brgb = brgx;
 | 
				
			||||||
				adg->rbg_rate[ADG_HZ_48] = rate / div;
 | 
									adg->brg_rate[ADG_HZ_48] = rate / div;
 | 
				
			||||||
				ckr |= brg_table[i] << 16;
 | 
									ckr |= brg_table[i] << 16;
 | 
				
			||||||
				if (req_Hz[ADG_HZ_48])
 | 
									if (req_Hz[ADG_HZ_48])
 | 
				
			||||||
					parent_clk_name = __clk_get_name(clk);
 | 
										parent_clk_name = __clk_get_name(clk);
 | 
				
			||||||
| 
						 | 
					@ -620,8 +620,8 @@ static int rsnd_adg_get_clkout(struct rsnd_priv *priv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rsnd_adg_get_clkout_end:
 | 
					rsnd_adg_get_clkout_end:
 | 
				
			||||||
	adg->ckr = ckr;
 | 
						adg->ckr = ckr;
 | 
				
			||||||
	adg->rbga = rbga;
 | 
						adg->brga = brga;
 | 
				
			||||||
	adg->rbgb = rbgb;
 | 
						adg->brgb = brgb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -663,9 +663,9 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
 | 
				
			||||||
			__clk_get_name(clk), clk, clk_get_rate(clk));
 | 
								__clk_get_name(clk), clk, clk_get_rate(clk));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
 | 
						dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
 | 
				
			||||||
		adg->ckr, adg->rbga, adg->rbgb);
 | 
							adg->ckr, adg->brga, adg->brgb);
 | 
				
			||||||
	dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->rbg_rate[ADG_HZ_441]);
 | 
						dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->brg_rate[ADG_HZ_441]);
 | 
				
			||||||
	dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->rbg_rate[ADG_HZ_48]);
 | 
						dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->brg_rate[ADG_HZ_48]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
 | 
						 * Actual CLKOUT will be exchanged in rsnd_adg_ssi_clk_try_start()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1088,22 +1088,39 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 | 
					static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 | 
						struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 | 
				
			||||||
	int ret = -EINVAL, _ret = 0;
 | 
						struct snd_soc_component *component;
 | 
				
			||||||
 | 
						int ret = -EINVAL, _ret = 0, start_dma_last = 0, i;
 | 
				
			||||||
	int rollback = 0;
 | 
						int rollback = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cmd) {
 | 
						switch (cmd) {
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_START:
 | 
						case SNDRV_PCM_TRIGGER_START:
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_RESUME:
 | 
						case SNDRV_PCM_TRIGGER_RESUME:
 | 
				
			||||||
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 | 
						case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 | 
				
			||||||
 | 
							/* Do we need to start dma last? */
 | 
				
			||||||
 | 
							for_each_rtd_components(rtd, i, component) {
 | 
				
			||||||
 | 
								if (component->driver->start_dma_last) {
 | 
				
			||||||
 | 
									start_dma_last = 1;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = snd_soc_link_trigger(substream, cmd, 0);
 | 
							ret = snd_soc_link_trigger(substream, cmd, 0);
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			goto start_err;
 | 
								goto start_err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (start_dma_last) {
 | 
				
			||||||
 | 
								ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
 | 
				
			||||||
 | 
								if (ret < 0)
 | 
				
			||||||
 | 
									goto start_err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
			ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
 | 
								ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
 | 
				
			||||||
			if (ret < 0)
 | 
								if (ret < 0)
 | 
				
			||||||
				goto start_err;
 | 
									goto start_err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
 | 
								ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
start_err:
 | 
					start_err:
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			rollback = 1;
 | 
								rollback = 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue