ASoC: codecs: wsa883x: add codec dai for each wsa883x

Add new codec dai for each wsa883x, since each WSA is
initialized as a codec and not as aux device.

Change-Id: I023c14faffcd1c1149531040ceae9ed1fe161385
Signed-off-by: Vignesh Kulothungan <vigneshk@codeaurora.org>
This commit is contained in:
Vignesh Kulothungan
2020-02-03 15:33:31 -08:00
committed by Gerrit - the friendly Code Review server
parent 6cdec19289
commit 9ffe8f6f21
2 changed files with 98 additions and 8 deletions

View File

@@ -130,6 +130,9 @@ struct wsa883x_priv {
int num_supplies; int num_supplies;
struct regulator_bulk_data *supplies; struct regulator_bulk_data *supplies;
unsigned long status_mask; unsigned long status_mask;
char *wsa883x_name_prefix;
struct snd_soc_dai_driver *dai_driver;
struct snd_soc_component_driver *driver;
}; };
#endif /* WSA883X_INTERNAL_H */ #endif /* WSA883X_INTERNAL_H */

View File

@@ -38,12 +38,23 @@
#define WSA883X_TEMP_RETRY 3 #define WSA883X_TEMP_RETRY 3
#define WSA883X_VBAT_TIMER_SEC 2 #define WSA883X_VBAT_TIMER_SEC 2
#define MAX_NAME_LEN 30
#define WSA883X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
SNDRV_PCM_RATE_384000)
/* Fractional Rates */
#define WSA883X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
#define WSA883X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC; static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC;
module_param(wsa883x_vbat_timer_sec, int, 0664); module_param(wsa883x_vbat_timer_sec, int, 0664);
MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling"); MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling");
#define DRV_NAME "wsa-codec"
enum { enum {
WSA_4OHMS =4, WSA_4OHMS =4,
WSA_8OHMS = 8, WSA_8OHMS = 8,
@@ -1242,8 +1253,8 @@ static void wsa883x_codec_remove(struct snd_soc_component *component)
return; return;
} }
static const struct snd_soc_component_driver soc_codec_dev_wsa883x = { static const struct snd_soc_component_driver soc_codec_dev_wsa883x_wsa = {
.name = DRV_NAME, .name = "",
.probe = wsa883x_codec_probe, .probe = wsa883x_codec_probe,
.remove = wsa883x_codec_remove, .remove = wsa883x_codec_remove,
.controls = wsa883x_snd_controls, .controls = wsa883x_snd_controls,
@@ -1336,6 +1347,21 @@ static int wsa883x_enable_supplies(struct device * dev,
return ret; return ret;
} }
static struct snd_soc_dai_driver wsa_dai[] = {
{
.name = "",
.playback = {
.stream_name = "",
.rates = WSA883X_RATES | WSA883X_FRAC_RATES,
.formats = WSA883X_FORMATS,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 2,
},
},
};
static int wsa883x_swr_probe(struct swr_device *pdev) static int wsa883x_swr_probe(struct swr_device *pdev)
{ {
int ret = 0, i = 0; int ret = 0, i = 0;
@@ -1343,6 +1369,10 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
u8 devnum = 0; u8 devnum = 0;
bool pin_state_current = false; bool pin_state_current = false;
struct wsa_ctrl_platform_data *plat_data = NULL; struct wsa_ctrl_platform_data *plat_data = NULL;
struct snd_soc_component *component;
const char *wsa883x_name_prefix_of = NULL;
char buffer[MAX_NAME_LEN];
int dev_index = 0;
wsa883x = devm_kzalloc(&pdev->dev, sizeof(struct wsa883x_priv), wsa883x = devm_kzalloc(&pdev->dev, sizeof(struct wsa883x_priv),
GFP_KERNEL); GFP_KERNEL);
@@ -1445,14 +1475,58 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR); wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PA_ON_ERR);
ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa883x, ret = of_property_read_string(pdev->dev.of_node, "qcom,wsa-prefix",
NULL, 0); &wsa883x_name_prefix_of);
if (ret) { if (ret) {
dev_err(&pdev->dev, "%s: Codec registration failed\n", dev_err(&pdev->dev,
__func__); "%s: Looking up %s property in node %s failed\n",
__func__, "qcom,wsa-prefix",
pdev->dev.of_node->full_name);
goto err_irq; goto err_irq;
} }
wsa883x->driver = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_component_driver), GFP_KERNEL);
if (!wsa883x->driver) {
ret = -ENOMEM;
goto err_irq;
}
memcpy(wsa883x->driver, &soc_codec_dev_wsa883x_wsa,
sizeof(struct snd_soc_component_driver));
wsa883x->dai_driver = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_dai_driver), GFP_KERNEL);
if (!wsa883x->dai_driver) {
ret = -ENOMEM;
goto err_mem;
}
memcpy(wsa883x->dai_driver, wsa_dai, sizeof(struct snd_soc_dai_driver));
/* Get last digit from HEX format */
dev_index = (int)((char)(pdev->addr & 0xF));
snprintf(buffer, sizeof(buffer), "wsa-codec.%d", dev_index);
wsa883x->driver->name = kstrndup(buffer, strlen(buffer), GFP_KERNEL);
snprintf(buffer, sizeof(buffer), "wsa_rx%d", dev_index);
wsa883x->dai_driver->name =
kstrndup(buffer, strlen(buffer), GFP_KERNEL);
snprintf(buffer, sizeof(buffer), "WSA883X_AIF%d Playback", dev_index);
wsa883x->dai_driver->playback.stream_name =
kstrndup(buffer, strlen(buffer), GFP_KERNEL);
/* Number of DAI's used is 1 */
ret = snd_soc_register_component(&pdev->dev,
wsa883x->driver, wsa883x->dai_driver, 1);
wsa883x->wsa883x_name_prefix = kstrndup(wsa883x_name_prefix_of,
strlen(wsa883x_name_prefix_of), GFP_KERNEL);
component = snd_soc_lookup_component(&pdev->dev, wsa883x->driver->name);
component->name_prefix = wsa883x->wsa883x_name_prefix;
wsa883x->parent_np = of_parse_phandle(pdev->dev.of_node, wsa883x->parent_np = of_parse_phandle(pdev->dev.of_node,
"qcom,bolero-handle", 0); "qcom,bolero-handle", 0);
if (wsa883x->parent_np) { if (wsa883x->parent_np) {
@@ -1517,6 +1591,11 @@ static int wsa883x_swr_probe(struct swr_device *pdev)
return 0; return 0;
err_mem:
if (wsa883x->dai_driver)
kfree(wsa883x->dai_driver);
if (wsa883x->driver)
kfree(wsa883x->driver);
err_irq: err_irq:
wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR, NULL); wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_SAF2WAR, NULL);
wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF, NULL); wcd_free_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_WAR2SAF, NULL);
@@ -1567,6 +1646,14 @@ static int wsa883x_swr_remove(struct swr_device *pdev)
#endif #endif
mutex_destroy(&wsa883x->res_lock); mutex_destroy(&wsa883x->res_lock);
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
kfree(wsa883x->wsa883x_name_prefix);
kfree(wsa883x->driver->name);
kfree(wsa883x->dai_driver->name);
kfree(wsa883x->dai_driver->playback.stream_name);
if (wsa883x->dai_driver)
kfree(wsa883x->dai_driver);
if (wsa883x->driver)
kfree(wsa883x->driver);
swr_set_dev_data(pdev, NULL); swr_set_dev_data(pdev, NULL);
return 0; return 0;
} }