Merge "asoc: bolero: Add bolero clock changes" into audio-drivers.lnx.3.0
This commit is contained in:
commit
deb6842fb9
3 changed files with 164 additions and 23 deletions
asoc/codecs/bolero
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -53,9 +62,15 @@ static inline void bolero_unregister_macro(struct device *dev, u16 macro_id)
|
|||
}
|
||||
|
||||
static inline struct device *bolero_get_device_ptr(struct device *dev,
|
||||
u16 macro_id)
|
||||
u16 macro_id)
|
||||
{
|
||||
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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue