Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) ST-Ericsson SA 2012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *         Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *         for ST-Ericsson.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * License terms:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <sound/soc-dapm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "ux500_pcm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "ux500_msp_dai.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "mop500_ab8500.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "../codecs/ab8500-codec.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define TX_SLOT_MONO	0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define TX_SLOT_STEREO	0x000a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define RX_SLOT_MONO	0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define RX_SLOT_STEREO	0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define TX_SLOT_8CH	0x00FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define RX_SLOT_8CH	0x00FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define DEF_TX_SLOTS	TX_SLOT_STEREO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define DEF_RX_SLOTS	RX_SLOT_MONO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define DRIVERMODE_NORMAL	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define DRIVERMODE_CODEC_ONLY	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /* Slot configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static unsigned int tx_slots = DEF_TX_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static unsigned int rx_slots = DEF_RX_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* Configuration consistency parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static DEFINE_MUTEX(mop500_ab8500_params_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static unsigned long mop500_ab8500_usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int mop500_ab8500_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static int mop500_ab8500_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /* Clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static const char * const enum_mclk[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	"SYSCLK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	"ULPCLK"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) enum mclk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	MCLK_SYSCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	MCLK_ULPCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /* Private data for machine-part MOP500<->AB8500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) struct mop500_ab8500_drvdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	/* Clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	enum mclk mclk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct clk *clk_ptr_intclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct clk *clk_ptr_sysclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct clk *clk_ptr_ulpclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static inline const char *get_mclk_str(enum mclk mclk_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	switch (mclk_sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	case MCLK_SYSCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return "SYSCLK";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	case MCLK_ULPCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return "ULPCLK";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		return "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static int mop500_ab8500_set_mclk(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 				struct mop500_ab8500_drvdata *drvdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct clk *clk_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (IS_ERR(drvdata->clk_ptr_intclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			"%s: ERROR: intclk not initialized!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	switch (drvdata->mclk_sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	case MCLK_SYSCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		clk_ptr = drvdata->clk_ptr_sysclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	case MCLK_ULPCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		clk_ptr = drvdata->clk_ptr_ulpclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (IS_ERR(clk_ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			get_mclk_str(drvdata->mclk_sel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			"%s: ERROR: Setting intclk parent to %s failed (ret = %d)!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			__func__, get_mclk_str(drvdata->mclk_sel), status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		dev_dbg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			"%s: intclk parent changed to %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			__func__, get_mclk_str(drvdata->mclk_sel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * Control-events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct mop500_ab8500_drvdata *drvdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				snd_soc_card_get_drvdata(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct mop500_ab8500_drvdata *drvdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 				snd_soc_card_get_drvdata(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	unsigned int val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (val > (unsigned int)MCLK_ULPCLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (drvdata->mclk_sel == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	drvdata->mclk_sel = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * Controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	SOC_ENUM_EXT("Master Clock Select",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		soc_enum_mclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		mclk_input_control_get, mclk_input_control_put),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	SOC_DAPM_PIN_SWITCH("Headset Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	SOC_DAPM_PIN_SWITCH("Headset Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	SOC_DAPM_PIN_SWITCH("Earpiece"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	SOC_DAPM_PIN_SWITCH("Speaker Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	SOC_DAPM_PIN_SWITCH("Speaker Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	SOC_DAPM_PIN_SWITCH("LineOut Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	SOC_DAPM_PIN_SWITCH("LineOut Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	SOC_DAPM_PIN_SWITCH("Vibra 1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	SOC_DAPM_PIN_SWITCH("Vibra 2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	SOC_DAPM_PIN_SWITCH("Mic 1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	SOC_DAPM_PIN_SWITCH("Mic 2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	SOC_DAPM_PIN_SWITCH("LineIn Left"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	SOC_DAPM_PIN_SWITCH("LineIn Right"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	SOC_DAPM_PIN_SWITCH("DMic 1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	SOC_DAPM_PIN_SWITCH("DMic 2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	SOC_DAPM_PIN_SWITCH("DMic 3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	SOC_DAPM_PIN_SWITCH("DMic 4"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	SOC_DAPM_PIN_SWITCH("DMic 5"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	SOC_DAPM_PIN_SWITCH("DMic 6"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* ASoC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int mop500_ab8500_startup(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	/* Set audio-clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return mop500_ab8500_set_mclk(rtd->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				snd_soc_card_get_drvdata(rtd->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	struct device *dev = rtd->card->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	dev_dbg(dev, "%s: Enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	/* Reset slots configuration to default(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		tx_slots = DEF_TX_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		rx_slots = DEF_RX_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	struct device *dev = rtd->card->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	unsigned int fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	int channels, ret = 0, driver_mode, slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	unsigned int sw_codec, sw_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	bool is_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	dev_dbg(dev, "%s: Enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	dev_dbg(dev, "%s: substream->pcm->name = %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		"substream->pcm->id = %s.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		"substream->name = %s.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		"substream->number = %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		__func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		substream->pcm->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		substream->pcm->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		substream->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		substream->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	/* Ensure configuration consistency between DAIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	mutex_lock(&mop500_ab8500_params_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (mop500_ab8500_usage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		if (mop500_ab8500_rate != params_rate(params) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		    mop500_ab8500_channels != params_channels(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			mutex_unlock(&mop500_ab8500_params_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		mop500_ab8500_rate = params_rate(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		mop500_ab8500_channels = params_channels(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	__set_bit(cpu_dai->id, &mop500_ab8500_usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	mutex_unlock(&mop500_ab8500_params_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	channels = params_channels(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		sw_cpu = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		sw_cpu = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	/* Setup codec depending on driver-mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (channels == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		driver_mode = DRIVERMODE_CODEC_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		driver_mode = DRIVERMODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		(driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	/* Setup format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	if (driver_mode == DRIVERMODE_NORMAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		fmt = SND_SOC_DAIFMT_DSP_A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			SND_SOC_DAIFMT_CBM_CFM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			SND_SOC_DAIFMT_NB_NF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			SND_SOC_DAIFMT_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		fmt = SND_SOC_DAIFMT_DSP_A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			SND_SOC_DAIFMT_CBM_CFM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			SND_SOC_DAIFMT_NB_NF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			SND_SOC_DAIFMT_GATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	ret = snd_soc_runtime_set_dai_fmt(rtd, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	/* Setup TDM-slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	switch (channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		slots = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		tx_slots = (is_playback) ? TX_SLOT_MONO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		rx_slots = (is_playback) ? 0 : RX_SLOT_MONO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		slots = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		tx_slots = (is_playback) ? TX_SLOT_STEREO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		slots = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		tx_slots = (is_playback) ? TX_SLOT_8CH : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		rx_slots = (is_playback) ? 0 : RX_SLOT_8CH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (driver_mode == DRIVERMODE_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		sw_codec = sw_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		sw_codec = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		tx_slots, rx_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				sw_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		tx_slots, rx_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 				sw_codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	mutex_lock(&mop500_ab8500_params_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	__clear_bit(cpu_dai->id, &mop500_ab8500_usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	mutex_unlock(&mop500_ab8500_params_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct snd_soc_ops mop500_ab8500_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		.hw_params = mop500_ab8500_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		.hw_free = mop500_ab8500_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		.startup = mop500_ab8500_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		.shutdown = mop500_ab8500_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	struct device *dev = rtd->card->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct mop500_ab8500_drvdata *drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	dev_dbg(dev, "%s Enter.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	/* Create driver private-data struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (!drvdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	snd_soc_card_set_drvdata(rtd->card, drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	/* Setup clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (IS_ERR(drvdata->clk_ptr_sysclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	if (IS_ERR(drvdata->clk_ptr_ulpclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	drvdata->clk_ptr_intclk = clk_get(dev, "intclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	if (IS_ERR(drvdata->clk_ptr_intclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	/* Set intclk default parent to ulpclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	drvdata->mclk_sel = MCLK_ULPCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	ret = mop500_ab8500_set_mclk(dev, drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	drvdata->mclk_sel = MCLK_ULPCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	/* Add controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	ret = snd_soc_add_card_controls(rtd->card, mop500_ab8500_ctrls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			ARRAY_SIZE(mop500_ab8500_ctrls));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		pr_err("%s: Failed to add machine-controls (%d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 				__func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	ret = snd_soc_dapm_disable_pin(dapm, "Earpiece");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Left");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Right");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Left");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Right");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	ret |= snd_soc_dapm_disable_pin(dapm, "Mic 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	ret |= snd_soc_dapm_disable_pin(dapm, "Mic 2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Left");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Right");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	ret |= snd_soc_dapm_disable_pin(dapm, "DMic 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	ret |= snd_soc_dapm_disable_pin(dapm, "DMic 2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	ret |= snd_soc_dapm_disable_pin(dapm, "DMic 3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	ret |= snd_soc_dapm_disable_pin(dapm, "DMic 4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	ret |= snd_soc_dapm_disable_pin(dapm, "DMic 5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	ret |= snd_soc_dapm_disable_pin(dapm, "DMic 6");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) void mop500_ab8500_remove(struct snd_soc_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	if (drvdata->clk_ptr_sysclk != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		clk_put(drvdata->clk_ptr_sysclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (drvdata->clk_ptr_ulpclk != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		clk_put(drvdata->clk_ptr_ulpclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	if (drvdata->clk_ptr_intclk != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		clk_put(drvdata->clk_ptr_intclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	snd_soc_card_set_drvdata(card, drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }