Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit deb6842f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "asoc: bolero: Add bolero clock changes" into audio-drivers.lnx.3.0

parents 184c49be 2df2d618
Loading
Loading
Loading
Loading
+146 −22
Original line number Diff line number Diff line
@@ -24,6 +24,14 @@

static struct snd_soc_codec_driver bolero;

/* MCLK_MUX table for all macros */
static u16 bolero_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = {
	{TX_MACRO, VA_MACRO},
	{TX_MACRO, RX_MACRO},
	{TX_MACRO, WSA_MACRO},
	{TX_MACRO, VA_MACRO},
};

static void bolero_ahb_write_device(char __iomem *io_base,
				    u16 reg, u8 value)
{
@@ -45,24 +53,31 @@ static int __bolero_reg_read(struct bolero_priv *priv,
			     u16 macro_id, u16 reg, u8 *val)
{
	int ret = -EINVAL;
	u16 current_mclk_mux_macro;

	if (!priv->macro_params[macro_id].mclk_fn) {
	mutex_lock(&priv->clk_lock);
	current_mclk_mux_macro =
		priv->current_mclk_mux_macro[macro_id];
	if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
		dev_dbg_ratelimited(priv->dev,
			"%s: mclk_fn not init for macro-id-%d\n",
			__func__, macro_id);
		return ret;
			"%s: mclk_fn not init for macro-id:%d, current_mclk_mux_macro:%d\n",
			__func__, macro_id, current_mclk_mux_macro);
		goto err;
	}
	ret = priv->macro_params[macro_id].mclk_fn(
			priv->macro_params[macro_id].dev, true);
	ret = priv->macro_params[current_mclk_mux_macro].mclk_fn(
			priv->macro_params[current_mclk_mux_macro].dev, true);
	if (ret) {
		dev_dbg_ratelimited(priv->dev,
				"%s: clock enable failed\n", __func__);
		return ret;
			"%s: clock enable failed for macro-id:%d, current_mclk_mux_macro:%d\n",
			__func__, macro_id, current_mclk_mux_macro);
		goto err;
	}
	bolero_ahb_read_device(
		priv->macro_params[macro_id].io_base, reg, val);
	priv->macro_params[macro_id].mclk_fn(
			priv->macro_params[macro_id].dev, false);
	priv->macro_params[current_mclk_mux_macro].mclk_fn(
			priv->macro_params[current_mclk_mux_macro].dev, false);
err:
	mutex_unlock(&priv->clk_lock);
	return ret;
}

@@ -70,24 +85,31 @@ static int __bolero_reg_write(struct bolero_priv *priv,
			      u16 macro_id, u16 reg, u8 val)
{
	int ret = -EINVAL;
	u16 current_mclk_mux_macro;

	if (!priv->macro_params[macro_id].mclk_fn) {
	mutex_lock(&priv->clk_lock);
	current_mclk_mux_macro =
		priv->current_mclk_mux_macro[macro_id];
	if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
		dev_dbg_ratelimited(priv->dev,
			"%s: mclk_fn not init for macro-id-%d\n",
			__func__, macro_id);
		return ret;
			"%s: mclk_fn not init for macro-id:%d, current_mclk_mux_macro:%d\n",
			__func__, macro_id, current_mclk_mux_macro);
		goto err;
	}
	ret = priv->macro_params[macro_id].mclk_fn(
			priv->macro_params[macro_id].dev, true);
	ret = priv->macro_params[current_mclk_mux_macro].mclk_fn(
			priv->macro_params[current_mclk_mux_macro].dev, true);
	if (ret) {
		dev_dbg_ratelimited(priv->dev,
				"%s: clock enable failed\n", __func__);
		return ret;
			"%s: clock enable failed for macro-id:%d, current_mclk_mux_macro:%d\n",
			__func__, macro_id, current_mclk_mux_macro);
		goto err;
	}
	bolero_ahb_write_device(
		priv->macro_params[macro_id].io_base, reg, val);
	priv->macro_params[macro_id].mclk_fn(
			priv->macro_params[macro_id].dev, false);
	priv->macro_params[current_mclk_mux_macro].mclk_fn(
			priv->macro_params[current_mclk_mux_macro].dev, false);
err:
	mutex_unlock(&priv->clk_lock);
	return ret;
}

@@ -204,6 +226,8 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
	priv->macro_params[macro_id].dai_ptr = ops->dai_ptr;
	priv->macro_params[macro_id].mclk_fn = ops->mclk_fn;
	priv->macro_params[macro_id].dev = dev;
	priv->current_mclk_mux_macro[macro_id] =
				bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
	priv->num_dais += ops->num_dais;
	priv->num_macros_registered++;
	priv->macros_supported[macro_id] = true;
@@ -214,6 +238,12 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
			dev_err(dev, "%s: copy_dais failed\n", __func__);
			return ret;
		}
		if (priv->macros_supported[TX_MACRO] == false) {
			bolero_mclk_mux_tbl[WSA_MACRO][MCLK_MUX0] = WSA_MACRO;
			priv->current_mclk_mux_macro[WSA_MACRO] = WSA_MACRO;
			bolero_mclk_mux_tbl[VA_MACRO][MCLK_MUX0] = VA_MACRO;
			priv->current_mclk_mux_macro[VA_MACRO] = VA_MACRO;
		}
		ret = snd_soc_register_codec(dev->parent, &bolero,
				priv->bolero_dais, priv->num_dais);
		if (ret < 0) {
@@ -265,6 +295,100 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
}
EXPORT_SYMBOL(bolero_unregister_macro);

/**
 * bolero_request_clock - request for clock enable/disable
 *
 * @dev: macro device ptr.
 * @macro_id: ID of macro calling this API.
 * @mclk_mux_id: MCLK_MUX ID.
 * @enable: enable or disable clock flag
 *
 * Returns 0 on success or -EINVAL on error.
 */
int bolero_request_clock(struct device *dev, u16 macro_id,
			 enum mclk_mux mclk_mux_id,
			 bool enable)
{
	struct bolero_priv *priv;
	u16 mclk_mux0_macro, mclk_mux1_macro;
	int ret = 0;

	if (!dev) {
		pr_err("%s: dev is null\n", __func__);
		return -EINVAL;
	}
	if (!bolero_is_valid_macro_dev(dev)) {
		dev_err(dev, "%s: macro:%d not in valid registered macro-list\n",
			__func__, macro_id);
		return -EINVAL;
	}
	priv = dev_get_drvdata(dev->parent);
	if (!priv || (macro_id >= MAX_MACRO)) {
		dev_err(dev, "%s: priv is null or invalid macro\n", __func__);
		return -EINVAL;
	}
	mclk_mux0_macro =  bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
	mutex_lock(&priv->clk_lock);
	switch (mclk_mux_id) {
	case MCLK_MUX0:
		ret = priv->macro_params[mclk_mux0_macro].mclk_fn(
			priv->macro_params[mclk_mux0_macro].dev, enable);
		if (ret < 0) {
			dev_err(dev,
				"%s: MCLK_MUX0 %s failed for macro:%d, mclk_mux0_macro:%d\n",
				__func__,
				enable ? "enable" : "disable",
				macro_id, mclk_mux0_macro);
			goto err;
		}
		break;
	case MCLK_MUX1:
		mclk_mux1_macro =  bolero_mclk_mux_tbl[macro_id][MCLK_MUX1];
		ret = priv->macro_params[mclk_mux0_macro].mclk_fn(
			priv->macro_params[mclk_mux0_macro].dev,
			true);
		if (ret < 0) {
			dev_err(dev,
				"%s: MCLK_MUX0 en failed for macro:%d mclk_mux0_macro:%d\n",
				__func__, macro_id, mclk_mux0_macro);
			goto err;
		}
		ret = priv->macro_params[mclk_mux1_macro].mclk_fn(
			priv->macro_params[mclk_mux1_macro].dev, enable);
		if (ret < 0) {
			dev_err(dev,
				"%s: MCLK_MUX1 %s failed for macro:%d, mclk_mux1_macro:%d\n",
				__func__,
				enable ? "enable" : "disable",
				macro_id, mclk_mux1_macro);
			priv->macro_params[mclk_mux0_macro].mclk_fn(
				priv->macro_params[mclk_mux0_macro].dev,
				false);
			goto err;
		}
		priv->macro_params[mclk_mux0_macro].mclk_fn(
			priv->macro_params[mclk_mux0_macro].dev,
			false);
		break;
	case MCLK_MUX_MAX:
	default:
		dev_err(dev, "%s: invalid mclk_mux_id: %d\n",
			__func__, mclk_mux_id);
		ret = -EINVAL;
		goto err;
	}
	if (enable)
		priv->current_mclk_mux_macro[macro_id] =
				bolero_mclk_mux_tbl[macro_id][mclk_mux_id];
	else
		priv->current_mclk_mux_macro[macro_id] =
				bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
err:
	mutex_unlock(&priv->clk_lock);
	return ret;
}
EXPORT_SYMBOL(bolero_request_clock);

static int bolero_soc_codec_probe(struct snd_soc_codec *codec)
{
	struct bolero_priv *priv = dev_get_drvdata(codec->dev);
@@ -359,8 +483,6 @@ static void bolero_add_child_devices(struct work_struct *work)
fail_pdev_add:
	for (i = cnt; i > 0; i--)
		platform_device_put(priv->pdev_child_devices[i - 1]);
err:
	return;
}

static int bolero_probe(struct platform_device *pdev)
@@ -405,6 +527,7 @@ static int bolero_probe(struct platform_device *pdev)

	dev_set_drvdata(&pdev->dev, priv);
	mutex_init(&priv->io_lock);
	mutex_init(&priv->clk_lock);
	INIT_WORK(&priv->bolero_add_child_devices_work,
		  bolero_add_child_devices);
	schedule_work(&priv->bolero_add_child_devices_work);
@@ -420,6 +543,7 @@ static int bolero_remove(struct platform_device *pdev)
	for (i = priv->child_num; i > 0; i--)
		platform_device_unregister(priv->pdev_child_devices[i - 1]);
	mutex_destroy(&priv->io_lock);
	mutex_destroy(&priv->clk_lock);
	return 0;
}

+16 −1
Original line number Diff line number Diff line
@@ -25,6 +25,12 @@ enum {
	MAX_MACRO
};

enum mclk_mux {
	MCLK_MUX0,
	MCLK_MUX1,
	MCLK_MUX_MAX
};

struct macro_ops {
	int (*init)(struct snd_soc_codec *codec);
	int (*exit)(struct snd_soc_codec *codec);
@@ -40,6 +46,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
			  struct macro_ops *ops);
void bolero_unregister_macro(struct device *dev, u16 macro_id);
struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id);
int bolero_request_clock(struct device *dev, u16 macro_id,
			 enum mclk_mux mclk_mux_id,
			 bool enable);
#else
static inline int bolero_register_macro(struct device *dev,
					u16 macro_id,
@@ -57,5 +66,11 @@ static inline struct device *bolero_get_device_ptr(struct device *dev,
{
	return NULL;
}
static inline int bolero_request_clock(struct device *dev, u16 macro_id,
				       enum mclk_mux mclk_mux_id,
				       bool enable)
{
	return 0;
}
#endif /* CONFIG_SND_SOC_BOLERO */
#endif /* BOLERO_CDC_H */
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ struct bolero_priv {
	struct snd_soc_codec *codec;
	struct regmap *regmap;
	struct mutex io_lock;
	struct mutex clk_lock;
	bool va_without_decimation;
	bool macros_supported[MAX_MACRO];
	struct macro_ops macro_params[MAX_MACRO];
@@ -34,6 +35,7 @@ struct bolero_priv {
	u16 num_dais;
	u16 num_macros_registered;
	u16 child_num;
	u16 current_mclk_mux_macro[MAX_MACRO];
	struct platform_device *pdev_child_devices[MAX_MACRO];

	struct work_struct bolero_add_child_devices_work;