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

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

Merge "ASoC: wcd9306: use hwdep nodes to get calibration"

parents 3ec06e86 80507977
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ snd-soc-uda134x-objs := uda134x.o
snd-soc-uda1380-objs := uda1380.o
snd-soc-wcd9310-objs := wcd9310.o wcd9310-tables.o
snd-soc-wcd9320-objs := wcd9320.o wcd9320-tables.o
snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o
snd-soc-wcd9306-objs := wcd9306.o wcd9306-tables.o wcdcal-hwdep.o
snd-soc-wcd9330-objs := wcd9330.o wcd9330-tables.o wcdcal-hwdep.o
snd-soc-wcd9xxx-objs := wcd9xxx-resmgr.o wcd9xxx-mbhc.o wcd9xxx-common.o
snd-soc-msm8x10-wcd-objs := msm8x10-wcd.o msm8x10-wcd-tables.o wcd9xxx-common.o
+88 −24
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <linux/ratelimit.h>
#include <linux/debugfs.h>
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/mfd/wcd9xxx/core.h>
#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
#include <linux/mfd/wcd9xxx/wcd9306_registers.h>
@@ -38,6 +37,7 @@
#include "wcd9306.h"
#include "wcd9xxx-resmgr.h"
#include "wcd9xxx-common.h"
#include "wcdcal-hwdep.h"

#define TAPAN_HPH_PA_SETTLE_COMP_ON 5000
#define TAPAN_HPH_PA_SETTLE_COMP_OFF 13000
@@ -291,6 +291,9 @@ struct tapan_priv {
	u32 anc_slot;
	bool anc_func;

	/* cal info for codec */
	struct fw_info *fw_data;

	/*track adie loopback mode*/
	bool lb_mode;

@@ -2245,15 +2248,18 @@ static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,
	const char *filename;
	const struct firmware *fw;
	int i;
	int ret;
	int ret = 0;
	int num_anc_slots;
	struct wcd9xxx_anc_header *anc_head;
	struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
	struct firmware_cal *hwdep_cal = NULL;
	u32 anc_writes_size = 0;
	int anc_size_remaining;
	u32 *anc_ptr;
	u16 reg;
	u8 mask, val, old_val;
	size_t cal_size;
	const void *data;

	dev_dbg(codec->dev, "%s %d\n", __func__, event);
	if (tapan->anc_func == 0)
@@ -2263,39 +2269,54 @@ static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,

		filename = "wcd9306/wcd9306_anc.bin";

		hwdep_cal = wcdcal_get_fw_cal(tapan->fw_data, WCD9XXX_ANC_CAL);
		if (hwdep_cal) {
			data = hwdep_cal->data;
			cal_size = hwdep_cal->size;
			dev_dbg(codec->dev, "%s: using hwdep calibration\n",
				__func__);
		} else {
			ret = request_firmware(&fw, filename, codec->dev);
			if (ret != 0) {
				dev_err(codec->dev, "Failed to acquire ANC data: %d\n",
					ret);
				return -ENODEV;
			}

		if (fw->size < sizeof(struct wcd9xxx_anc_header)) {
			if (!fw) {
				dev_err(codec->dev, "failed to get anc fw");
				return -ENODEV;
			}
			data = fw->data;
			cal_size = fw->size;
			dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
				__func__);
		}
		if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
			dev_err(codec->dev, "Not enough data\n");
			release_firmware(fw);
			return -ENOMEM;
			ret = -ENOMEM;
			goto err;
		}

		/* First number is the number of register writes */
		anc_head = (struct wcd9xxx_anc_header *)(fw->data);
		anc_ptr = (u32 *)(fw->data +
		anc_head = (struct wcd9xxx_anc_header *)(data);
		anc_ptr = (u32 *)(data +
				  sizeof(struct wcd9xxx_anc_header));
		anc_size_remaining = fw->size -
		anc_size_remaining = cal_size -
				     sizeof(struct wcd9xxx_anc_header);
		num_anc_slots = anc_head->num_anc_slots;

		if (tapan->anc_slot >= num_anc_slots) {
			dev_err(codec->dev, "Invalid ANC slot selected\n");
			release_firmware(fw);
			return -EINVAL;
			ret = -EINVAL;
			goto err;
		}

		for (i = 0; i < num_anc_slots; i++) {

			if (anc_size_remaining < TAPAN_PACKED_REG_SIZE) {
				dev_err(codec->dev, "Invalid register format\n");
				release_firmware(fw);
				return -EINVAL;
				ret = -EINVAL;
				goto err;
			}
			anc_writes_size = (u32)(*anc_ptr);
			anc_size_remaining -= sizeof(u32);
@@ -2304,8 +2325,8 @@ static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,
			if (anc_writes_size * TAPAN_PACKED_REG_SIZE
				> anc_size_remaining) {
				dev_err(codec->dev, "Invalid register format\n");
				release_firmware(fw);
				return -ENOMEM;
				ret = -EINVAL;
				goto err;
			}

			if (tapan->anc_slot == i)
@@ -2317,8 +2338,8 @@ static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,
		}
		if (i == num_anc_slots) {
			dev_err(codec->dev, "Selected ANC slot not present\n");
			release_firmware(fw);
			return -ENOMEM;
			ret = -EINVAL;
			goto err;
		}

		for (i = 0; i < anc_writes_size; i++) {
@@ -2328,6 +2349,7 @@ static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,
			snd_soc_write(codec, reg, (old_val & ~mask) |
					(val & mask));
		}
		if (!hwdep_cal)
			release_firmware(fw);

		break;
@@ -2342,6 +2364,10 @@ static int tapan_codec_enable_anc(struct snd_soc_dapm_widget *w,
		break;
	}
	return 0;
err:
	if (!hwdep_cal)
		release_firmware(fw);
	return ret;
}

static int tapan_codec_enable_micbias(struct snd_soc_dapm_widget *w,
@@ -6037,6 +6063,26 @@ static void tapan_compute_impedance(struct wcd9xxx_mbhc *mbhc, s16 *l, s16 *r,
	*zr = rr;
}

static struct firmware_cal *tapan_get_hwdep_fw_cal(struct snd_soc_codec *codec,
		enum wcd_cal_type type)
{
	struct tapan_priv *tapan;
	struct firmware_cal *hwdep_cal;
	if (!codec) {
		pr_err("%s: NULL codec pointer\n", __func__);
		return NULL;
	}
	tapan = snd_soc_codec_get_drvdata(codec);
	hwdep_cal = wcdcal_get_fw_cal(tapan->fw_data, type);
	if (!hwdep_cal) {
		dev_err(codec->dev, "%s: cal not sent by %d\n",
				__func__, type);
		return NULL;
	} else {
		return hwdep_cal;
	}
}

static const struct wcd9xxx_mbhc_cb mbhc_cb = {
	.enable_mux_bias_block = tapan_enable_mux_bias_block,
	.cfilt_fast_mode = tapan_put_cfilt_fast_mode,
@@ -6046,6 +6092,7 @@ static const struct wcd9xxx_mbhc_cb mbhc_cb = {
	.get_cdc_type = tapan_get_cdc_type,
	.setup_zdet = tapan_setup_zdet,
	.compute_impedance = tapan_compute_impedance,
	.get_hwdep_fw_cal = tapan_get_hwdep_fw_cal,
};

int tapan_hs_detect(struct snd_soc_codec *codec,
@@ -6380,6 +6427,21 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
	else
		rco_clk_rate = TAPAN_MCLK_CLK_9P6MHZ;


	tapan->fw_data = kzalloc(sizeof(*(tapan->fw_data)), GFP_KERNEL);
	if (!tapan->fw_data) {
		dev_err(codec->dev, "Failed to allocate fw_data\n");
		goto err_nomem_slimch;
	}
	set_bit(WCD9XXX_ANC_CAL, tapan->fw_data->cal_bit);
	set_bit(WCD9XXX_MAD_CAL, tapan->fw_data->cal_bit);
	set_bit(WCD9XXX_MBHC_CAL, tapan->fw_data->cal_bit);
	ret = wcd_cal_create_hwdep(tapan->fw_data,
				WCD9XXX_CODEC_HWDEP_NODE, codec);
	if (ret < 0) {
		dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
		goto err_hwdep;
	}
	ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec,
				tapan_enable_mbhc_micbias,
				&mbhc_cb, &cdc_intr_ids, rco_clk_rate,
@@ -6425,7 +6487,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
	if (!ptr) {
		pr_err("%s: no mem for slim chan ctl data\n", __func__);
		ret = -ENOMEM;
		goto err_nomem_slimch;
		goto err_hwdep;
	}

	if (tapan->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
@@ -6487,6 +6549,8 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)

err_pdata:
	kfree(ptr);
err_hwdep:
	kfree(tapan->fw_data);
err_nomem_slimch:
	kfree(tapan);
	return ret;
+1 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ config SND_SOC_MSM8226
	select DOLBY_DAP
	select DTS_SRS_TM
	select QTI_PP
	select SND_HWDEP
	help
	 To add support for SoC audio on MSM8226.
	 This will enable sound soc drivers which