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

Commit 300fff00 authored by Dechen Chai's avatar Dechen Chai
Browse files

ASoC: bengal: Update machine driver for qrbx210



Remove msm_aux_codec_init.

Change-Id: Iee99202a6874d52ee1bb0b052c70faac64505411
Signed-off-by: default avatarDechen Chai <dchai@codeaurora.org>
parent 874ab7e7
Loading
Loading
Loading
Loading
+93 −428
Original line number Diff line number Diff line
@@ -179,11 +179,6 @@ struct msm_wsa881x_dev_info {
	u32 index;
};

struct aux_codec_dev_info {
	struct device_node *of_node;
	u32 index;
};

struct dev_config {
	u32 sample_rate;
	u32 bit_format;
@@ -560,6 +555,8 @@ static int dmic_2_3_gpio_cnt;
static void *def_wcd_mbhc_cal(void);
static void *def_rouleur_mbhc_cal(void);

static int msm_int_audrx_init(struct snd_soc_pcm_runtime*);

/*
 * Need to report LINEIN
 * if R/L channel impedance is larger than 5K ohm
@@ -4263,6 +4260,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int ret = -EINVAL;
	struct snd_soc_component *component;
	struct snd_soc_component *bolero_component = NULL;
	struct snd_soc_dapm_context *dapm;
	struct snd_card *card;
	struct snd_info_entry *entry;
@@ -4277,6 +4275,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
		pr_err("%s: could not find component for bolero_codec\n",
			__func__);
		return ret;
	} else {
		bolero_component = component;
	}

	dapm = snd_soc_component_get_dapm(component);
@@ -4315,39 +4315,8 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)

	snd_soc_dapm_sync(dapm);

	for (i = 0; i < rtd->card->num_aux_devs; i++)
	{
		if (msm_aux_dev[i].name != NULL ) {
			if (strstr(msm_aux_dev[i].name, "wsa"))
				continue;
		}

		if (msm_aux_dev[i].codec_of_node) {
			pdev = of_find_device_by_node(
					msm_aux_dev[i].codec_of_node);

			if (pdev)
				data = (char*) of_device_get_match_data(
								&pdev->dev);
			if (data != NULL) {
				if (!strncmp(data, "wcd937x",
						sizeof("wcd937x"))) {
					bolero_set_port_map(component,
						ARRAY_SIZE(sm_port_map),
						sm_port_map);
					break;
				} else if (!strncmp( data, "rouleur",
							sizeof("rouleur"))) {
					bolero_set_port_map(component,
						ARRAY_SIZE(sm_port_map_rouleur),
						sm_port_map_rouleur);
					break;
				}
			}
		}
	}

	card = rtd->card->snd_card;

	if (!pdata->codec_root) {
		entry = msm_snd_info_create_subdir(card->module, "codecs",
						 card->proc_root);
@@ -4361,6 +4330,39 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
	}
	bolero_info_create_codec_entry(pdata->codec_root, component);
	bolero_register_wake_irq(component, false);

	component = snd_soc_rtdcom_lookup(rtd, ROULEUR_DRV_NAME);
	if (!component)
		component = snd_soc_rtdcom_lookup(rtd, WCD937X_DRV_NAME);

	if (!component) {
		pr_err("%s component is NULL\n", __func__);
		return -EINVAL;
	}

	dapm = snd_soc_component_get_dapm(component);
	card = component->card->snd_card;

	snd_soc_dapm_ignore_suspend(dapm, "EAR");
	snd_soc_dapm_ignore_suspend(dapm, "AUX");
	snd_soc_dapm_ignore_suspend(dapm, "LO");
	snd_soc_dapm_ignore_suspend(dapm, "HPHL");
	snd_soc_dapm_ignore_suspend(dapm, "HPHR");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
	snd_soc_dapm_sync(dapm);

	if (!strncmp(component->driver->name, ROULEUR_DRV_NAME,
						strlen(ROULEUR_DRV_NAME))) {
		rouleur_info_create_codec_entry(pdata->codec_root, component);
		bolero_set_port_map(bolero_component, ARRAY_SIZE(sm_port_map_rouleur), sm_port_map_rouleur);
	} else if (!strncmp(component->driver->name, WCD937X_DRV_NAME,
						strlen(WCD937X_DRV_NAME))) {
		wcd937x_info_create_codec_entry(pdata->codec_root, component);
		bolero_set_port_map(bolero_component, ARRAY_SIZE(sm_port_map), sm_port_map);
	}
	codec_reg_done = true;
	return 0;
err:
@@ -5713,6 +5715,59 @@ static const struct of_device_id bengal_asoc_machine_of_match[] = {
	{},
};

static int msm_snd_card_bengal_late_probe(struct snd_soc_card *card)
{
	struct snd_soc_component *component = NULL;
	const char *be_dl_name = LPASS_BE_RX_CDC_DMA_RX_0;
	struct snd_soc_pcm_runtime *rtd;
	int ret = 0;
	void *mbhc_calibration;

	rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
	if (!rtd) {
		dev_err(card->dev,
			"%s: snd_soc_get_pcm_runtime for %s failed!\n",
			__func__, be_dl_name);
		return -EINVAL;
	}

	component = snd_soc_rtdcom_lookup(rtd, ROULEUR_DRV_NAME);
	if (!component)
		component = snd_soc_rtdcom_lookup(rtd, WCD937X_DRV_NAME);
	if (!component) {
		pr_err("%s component is NULL\n", __func__);
		return -EINVAL;
	}

	if (!strncmp(component->driver->name, ROULEUR_DRV_NAME,
						strlen(ROULEUR_DRV_NAME))) {
		mbhc_calibration = def_rouleur_mbhc_cal();
		if (!mbhc_calibration)
			return -ENOMEM;
		wcd_mbhc_cfg.calibration = mbhc_calibration;
		ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg);
	} else if (!strncmp(component->driver->name, WCD937X_DRV_NAME,
						strlen(WCD937X_DRV_NAME))) {
		mbhc_calibration = def_wcd_mbhc_cal();
		if (!mbhc_calibration)
			return -ENOMEM;
		wcd_mbhc_cfg.calibration = mbhc_calibration;
		ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
	} else {
		return 0;
	}
	if (ret) {
		dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
			__func__, ret);
		goto err_hs_detect;
	}
	return 0;

err_hs_detect:
	kfree(mbhc_calibration);
	return ret;
}

static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
{
	struct snd_soc_card *card = NULL;
@@ -5871,398 +5926,12 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
	if (card) {
		card->dai_link = dailink;
		card->num_links = total_links;
		card->late_probe = msm_snd_card_bengal_late_probe;
	}

	return card;
}

static int msm_aux_codec_init(struct snd_soc_component *component)
{
	struct snd_soc_dapm_context *dapm =
				snd_soc_component_get_dapm(component);
	int ret = 0;
	void *mbhc_calibration;
	struct snd_info_entry *entry;
	struct snd_card *card = component->card->snd_card;
	struct msm_asoc_mach_data *pdata;
	struct platform_device *pdev = NULL;
	char *data = NULL;
	int i = 0;

	snd_soc_dapm_ignore_suspend(dapm, "EAR");
	snd_soc_dapm_ignore_suspend(dapm, "AUX");
	snd_soc_dapm_ignore_suspend(dapm, "LO");
	snd_soc_dapm_ignore_suspend(dapm, "HPHL");
	snd_soc_dapm_ignore_suspend(dapm, "HPHR");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
	snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
	snd_soc_dapm_sync(dapm);

	pdata = snd_soc_card_get_drvdata(component->card);
	if (!pdata->codec_root) {
		entry = snd_info_create_subdir(card->module, "codecs",
						 card->proc_root);
		if (!entry) {
			dev_dbg(component->dev, "%s: Cannot create codecs module entry\n",
				 __func__);
			ret = 0;
			goto mbhc_cfg_cal;
		}
		pdata->codec_root = entry;
	}

	for (i = 0; i < component->card->num_aux_devs; i++)
	{
		if (msm_aux_dev[i].name != NULL ) {
			if (strstr(msm_aux_dev[i].name, "wsa"))
				continue;
		}

		if (msm_aux_dev[i].codec_of_node) {
			pdev = of_find_device_by_node(
				msm_aux_dev[i].codec_of_node);
			if (pdev)
				data = (char*) of_device_get_match_data(
							&pdev->dev);

			if (data != NULL) {
				if (!strncmp(data, "wcd937x",
						sizeof("wcd937x"))) {
					wcd937x_info_create_codec_entry(
						pdata->codec_root, component);
					break;
				} else if (!strncmp(data, "rouleur",
						sizeof("rouleur"))) {
					rouleur_info_create_codec_entry(
						pdata->codec_root, component);
					break;
				}
			}
		}
	}

mbhc_cfg_cal:
        if (data != NULL) {
		if (!strncmp(data, "wcd937x", sizeof("wcd937x"))) {
			mbhc_calibration = def_wcd_mbhc_cal();
			if (!mbhc_calibration)
				return -ENOMEM;
			wcd_mbhc_cfg.calibration = mbhc_calibration;
			ret = wcd937x_mbhc_hs_detect(component, &wcd_mbhc_cfg);
		} else if (!strncmp( data, "rouleur", sizeof("rouleur"))) {
			mbhc_calibration = def_rouleur_mbhc_cal();
			if (!mbhc_calibration)
				return -ENOMEM;
			wcd_mbhc_cfg.calibration = mbhc_calibration;
			ret = rouleur_mbhc_hs_detect(component, &wcd_mbhc_cfg);
		}
	}

	if (ret) {
		dev_err(component->dev, "%s: mbhc hs detect failed, err:%d\n",
			__func__, ret);
		goto err_hs_detect;
	}
	return 0;

err_hs_detect:
	kfree(mbhc_calibration);
	return ret;
}

static int msm_init_aux_dev(struct platform_device *pdev,
				struct snd_soc_card *card)
{
	struct device_node *wsa_of_node;
	struct device_node *aux_codec_of_node;
	u32 wsa_max_devs;
	u32 wsa_dev_cnt;
	u32 codec_max_aux_devs = 0;
	u32 codec_aux_dev_cnt = 0;
	int i;
	struct msm_wsa881x_dev_info *wsa881x_dev_info;
	struct aux_codec_dev_info *aux_cdc_dev_info;
	const char *auxdev_name_prefix[1];
	char *dev_name_str = NULL;
	int found = 0;
	int codecs_found = 0;
	int ret = 0;

	/* Get maximum WSA device count for this platform */
	ret = of_property_read_u32(pdev->dev.of_node,
				   "qcom,wsa-max-devs", &wsa_max_devs);
	if (ret) {
		dev_info(&pdev->dev,
			 "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
			 __func__, pdev->dev.of_node->full_name, ret);
		wsa_max_devs = 0;
		goto codec_aux_dev;
	}
	if (wsa_max_devs == 0) {
		dev_warn(&pdev->dev,
			 "%s: Max WSA devices is 0 for this target?\n",
			 __func__);
		goto codec_aux_dev;
	}

	/* Get count of WSA device phandles for this platform */
	wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
						 "qcom,wsa-devs", NULL);
	if (wsa_dev_cnt == -ENOENT) {
		dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
			 __func__);
		goto err;
	} else if (wsa_dev_cnt <= 0) {
		dev_err(&pdev->dev,
			"%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
			__func__, wsa_dev_cnt);
		ret = -EINVAL;
		goto err;
	}

	/*
	 * Expect total phandles count to be NOT less than maximum possible
	 * WSA count. However, if it is less, then assign same value to
	 * max count as well.
	 */
	if (wsa_dev_cnt < wsa_max_devs) {
		dev_dbg(&pdev->dev,
			"%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
			__func__, wsa_max_devs, wsa_dev_cnt);
		wsa_max_devs = wsa_dev_cnt;
	}

	/* Make sure prefix string passed for each WSA device */
	ret = of_property_count_strings(pdev->dev.of_node,
					"qcom,wsa-aux-dev-prefix");
	if (ret != wsa_dev_cnt) {
		dev_err(&pdev->dev,
			"%s: expecting %d wsa prefix. Defined only %d in DT\n",
			__func__, wsa_dev_cnt, ret);
		ret = -EINVAL;
		goto err;
	}

	/*
	 * Alloc mem to store phandle and index info of WSA device, if already
	 * registered with ALSA core
	 */
	wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
					sizeof(struct msm_wsa881x_dev_info),
					GFP_KERNEL);
	if (!wsa881x_dev_info) {
		ret = -ENOMEM;
		goto err;
	}

	/*
	 * search and check whether all WSA devices are already
	 * registered with ALSA core or not. If found a node, store
	 * the node and the index in a local array of struct for later
	 * use.
	 */
	for (i = 0; i < wsa_dev_cnt; i++) {
		wsa_of_node = of_parse_phandle(pdev->dev.of_node,
					    "qcom,wsa-devs", i);
		if (unlikely(!wsa_of_node)) {
			/* we should not be here */
			dev_err(&pdev->dev,
				"%s: wsa dev node is not present\n",
				__func__);
			ret = -EINVAL;
			goto err;
		}
		if (soc_find_component(wsa_of_node, NULL)) {
			/* WSA device registered with ALSA core */
			wsa881x_dev_info[found].of_node = wsa_of_node;
			wsa881x_dev_info[found].index = i;
			found++;
			if (found == wsa_max_devs)
				break;
		}
	}

	if (found < wsa_max_devs) {
		dev_dbg(&pdev->dev,
			"%s: failed to find %d components. Found only %d\n",
			__func__, wsa_max_devs, found);
		return -EPROBE_DEFER;
	}
	dev_info(&pdev->dev,
		"%s: found %d wsa881x devices registered with ALSA core\n",
		__func__, found);

codec_aux_dev:
	/* Get maximum aux codec device count for this platform */
	ret = of_property_read_u32(pdev->dev.of_node,
				   "qcom,codec-max-aux-devs",
				   &codec_max_aux_devs);
	if (ret) {
		dev_err(&pdev->dev,
			 "%s: codec-max-aux-devs property missing in DT %s, ret = %d\n",
			 __func__, pdev->dev.of_node->full_name, ret);
		codec_max_aux_devs = 0;
		goto aux_dev_register;
	}
	if (codec_max_aux_devs == 0) {
		dev_dbg(&pdev->dev,
			 "%s: Max aux codec devices is 0 for this target?\n",
			 __func__);
		goto aux_dev_register;
	}

	/* Get count of aux codec device phandles for this platform */
	codec_aux_dev_cnt = of_count_phandle_with_args(
				pdev->dev.of_node,
				"qcom,codec-aux-devs", NULL);
	if (codec_aux_dev_cnt == -ENOENT) {
		dev_warn(&pdev->dev, "%s: No aux codec defined in DT.\n",
			 __func__);
		goto err;
	} else if (codec_aux_dev_cnt <= 0) {
		dev_err(&pdev->dev,
			"%s: Error reading aux codec device from DT, dev_cnt=%d\n",
			__func__, codec_aux_dev_cnt);
		ret = -EINVAL;
		goto err;
	}

	/*
	 * Expect total phandles count to be NOT less than maximum possible
	 * AUX device count. However, if it is less, then assign same value to
	 * max count as well.
	 */
	if (codec_aux_dev_cnt < codec_max_aux_devs) {
		dev_dbg(&pdev->dev,
			"%s: codec_max_aux_devs = %d cannot exceed codec_aux_dev_cnt = %d\n",
			__func__, codec_max_aux_devs,
			codec_aux_dev_cnt);
		codec_max_aux_devs = codec_aux_dev_cnt;
	}

	/*
	 * Alloc mem to store phandle and index info of aux codec
	 * if already registered with ALSA core
	 */
	aux_cdc_dev_info = devm_kcalloc(&pdev->dev, codec_aux_dev_cnt,
				sizeof(struct aux_codec_dev_info),
				GFP_KERNEL);
	if (!aux_cdc_dev_info) {
		ret = -ENOMEM;
		goto err;
	}

	/*
	 * search and check whether all aux codecs are already
	 * registered with ALSA core or not. If found a node, store
	 * the node and the index in a local array of struct for later
	 * use.
	 */
	for (i = 0; i < codec_aux_dev_cnt; i++) {
		aux_codec_of_node = of_parse_phandle(pdev->dev.of_node,
					    "qcom,codec-aux-devs", i);
		if (unlikely(!aux_codec_of_node)) {
			/* we should not be here */
			dev_err(&pdev->dev,
				"%s: aux codec dev node is not present\n",
				__func__);
			ret = -EINVAL;
			goto err;
		}
		if (soc_find_component(aux_codec_of_node, NULL)) {
			/* AUX codec registered with ALSA core */
			aux_cdc_dev_info[codecs_found].of_node =
						aux_codec_of_node;
			aux_cdc_dev_info[codecs_found].index = i;
			codecs_found++;
		}
	}

	if (codecs_found < codec_aux_dev_cnt) {
		dev_dbg(&pdev->dev,
			"%s: failed to find %d components. Found only %d\n",
			__func__, codec_aux_dev_cnt, codecs_found);
		return -EPROBE_DEFER;
	}
	dev_info(&pdev->dev,
		"%s: found %d AUX codecs registered with ALSA core\n",
		__func__, codecs_found);

aux_dev_register:
	card->num_aux_devs = wsa_max_devs + codec_aux_dev_cnt;
	card->num_configs = wsa_max_devs + codec_aux_dev_cnt;

	/* Alloc array of AUX devs struct */
	msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
				       sizeof(struct snd_soc_aux_dev),
				       GFP_KERNEL);
	if (!msm_aux_dev) {
		ret = -ENOMEM;
		goto err;
	}

	/* Alloc array of codec conf struct */
	msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_configs,
					  sizeof(struct snd_soc_codec_conf),
					  GFP_KERNEL);
	if (!msm_codec_conf) {
		ret = -ENOMEM;
		goto err;
	}

	for (i = 0; i < wsa_max_devs; i++) {
		dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
					    GFP_KERNEL);
		if (!dev_name_str) {
			ret = -ENOMEM;
			goto err;
		}

		ret = of_property_read_string_index(pdev->dev.of_node,
						    "qcom,wsa-aux-dev-prefix",
						    wsa881x_dev_info[i].index,
						    auxdev_name_prefix);
		if (ret) {
			dev_err(&pdev->dev,
				"%s: failed to read wsa aux dev prefix, ret = %d\n",
				__func__, ret);
			ret = -EINVAL;
			goto err;
		}

		snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
		msm_aux_dev[i].name = dev_name_str;
		msm_aux_dev[i].codec_name = NULL;
		msm_aux_dev[i].codec_of_node =
					wsa881x_dev_info[i].of_node;
		msm_aux_dev[i].init = NULL;
		msm_codec_conf[i].dev_name = NULL;
		msm_codec_conf[i].name_prefix = auxdev_name_prefix[0];
		msm_codec_conf[i].of_node =
				wsa881x_dev_info[i].of_node;
	}

	for (i = 0; i < codec_aux_dev_cnt; i++) {
		msm_aux_dev[wsa_max_devs + i].name = NULL;
		msm_aux_dev[wsa_max_devs + i].codec_name = NULL;
		msm_aux_dev[wsa_max_devs + i].codec_of_node =
					aux_cdc_dev_info[i].of_node;
		msm_aux_dev[wsa_max_devs + i].init =  msm_aux_codec_init;
		msm_codec_conf[wsa_max_devs + i].dev_name = NULL;
		msm_codec_conf[wsa_max_devs + i].name_prefix =
						NULL;
		msm_codec_conf[wsa_max_devs + i].of_node =
				aux_cdc_dev_info[i].of_node;
	}

	card->codec_conf = msm_codec_conf;
	card->aux_dev = msm_aux_dev;
err:
	return ret;
}

static void msm_i2s_auxpcm_init(struct platform_device *pdev)
{
	int count = 0;
@@ -6439,10 +6108,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
		goto err;
	}

	ret = msm_init_aux_dev(pdev, card);
	if (ret)
		goto err;

	ret = devm_snd_soc_register_card(&pdev->dev, card);
	if (ret == -EPROBE_DEFER) {
		if (codec_reg_done)