brintos

brintos / linux-shallow public Read only

0
0
Text · 31.3 KiB · e3ac0e2 Raw
1137 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// HDA audio driver for Cirrus Logic CS35L56 smart amp4//5// Copyright (C) 2023 Cirrus Logic, Inc. and6//                    Cirrus Logic International Semiconductor Ltd.7//8 9#include <linux/acpi.h>10#include <linux/debugfs.h>11#include <linux/gpio/consumer.h>12#include <linux/module.h>13#include <linux/pm_runtime.h>14#include <linux/regmap.h>15#include <linux/slab.h>16#include <sound/core.h>17#include <sound/cs-amp-lib.h>18#include <sound/hda_codec.h>19#include <sound/tlv.h>20#include "cirrus_scodec.h"21#include "cs35l56_hda.h"22#include "hda_component.h"23#include "hda_cs_dsp_ctl.h"24#include "hda_generic.h"25 26 /*27  * The cs35l56_hda_dai_config[] reg sequence configures the device as28  *  ASP1_BCLK_FREQ = 3.072 MHz29  *  ASP1_RX_WIDTH = 32 cycles per slot, ASP1_TX_WIDTH = 32 cycles per slot, ASP1_FMT = I2S30  *  ASP1_DOUT_HIZ_CONTROL = Hi-Z during unused timeslots31  *  ASP1_RX_WL = 24 bits per sample32  *  ASP1_TX_WL = 24 bits per sample33  *  ASP1_RXn_EN 1..3 and ASP1_TXn_EN 1..4 disabled34  *35  * Override any Windows-specific mixer settings applied by the firmware.36  */37static const struct reg_sequence cs35l56_hda_dai_config[] = {38	{ CS35L56_ASP1_CONTROL1,	0x00000021 },39	{ CS35L56_ASP1_CONTROL2,	0x20200200 },40	{ CS35L56_ASP1_CONTROL3,	0x00000003 },41	{ CS35L56_ASP1_FRAME_CONTROL1,	0x03020100 },42	{ CS35L56_ASP1_FRAME_CONTROL5,	0x00020100 },43	{ CS35L56_ASP1_DATA_CONTROL5,	0x00000018 },44	{ CS35L56_ASP1_DATA_CONTROL1,	0x00000018 },45	{ CS35L56_ASP1_ENABLES1,	0x00000000 },46	{ CS35L56_ASP1TX1_INPUT,	0x00000018 },47	{ CS35L56_ASP1TX2_INPUT,	0x00000019 },48	{ CS35L56_ASP1TX3_INPUT,	0x00000020 },49	{ CS35L56_ASP1TX4_INPUT,	0x00000028 },50 51};52 53static void cs35l56_hda_wait_dsp_ready(struct cs35l56_hda *cs35l56)54{55	/* Wait for patching to complete */56	flush_work(&cs35l56->dsp_work);57}58 59static void cs35l56_hda_play(struct cs35l56_hda *cs35l56)60{61	unsigned int val;62	int ret;63 64	cs35l56_hda_wait_dsp_ready(cs35l56);65 66	pm_runtime_get_sync(cs35l56->base.dev);67	ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PLAY);68	if (ret == 0) {69		/* Wait for firmware to enter PS0 power state */70		ret = regmap_read_poll_timeout(cs35l56->base.regmap,71					       CS35L56_TRANSDUCER_ACTUAL_PS,72					       val, (val == CS35L56_PS0),73					       CS35L56_PS0_POLL_US,74					       CS35L56_PS0_TIMEOUT_US);75		if (ret)76			dev_warn(cs35l56->base.dev, "PS0 wait failed: %d\n", ret);77	}78	regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_ENABLES1,79			BIT(CS35L56_ASP_RX1_EN_SHIFT) | BIT(CS35L56_ASP_RX2_EN_SHIFT) |80			cs35l56->asp_tx_mask);81	cs35l56->playing = true;82}83 84static void cs35l56_hda_pause(struct cs35l56_hda *cs35l56)85{86	cs35l56->playing = false;87	cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PAUSE);88	regmap_clear_bits(cs35l56->base.regmap, CS35L56_ASP1_ENABLES1,89			  BIT(CS35L56_ASP_RX1_EN_SHIFT) | BIT(CS35L56_ASP_RX2_EN_SHIFT) |90			  BIT(CS35L56_ASP_TX1_EN_SHIFT) | BIT(CS35L56_ASP_TX2_EN_SHIFT) |91			  BIT(CS35L56_ASP_TX3_EN_SHIFT) | BIT(CS35L56_ASP_TX4_EN_SHIFT));92 93	pm_runtime_mark_last_busy(cs35l56->base.dev);94	pm_runtime_put_autosuspend(cs35l56->base.dev);95}96 97static void cs35l56_hda_playback_hook(struct device *dev, int action)98{99	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);100 101	dev_dbg(cs35l56->base.dev, "%s()%d: action: %d\n", __func__, __LINE__, action);102 103	switch (action) {104	case HDA_GEN_PCM_ACT_PREPARE:105		if (cs35l56->playing)106			break;107 108		/* If we're suspended: flag that resume should start playback */109		if (cs35l56->suspended) {110			cs35l56->playing = true;111			break;112		}113 114		cs35l56_hda_play(cs35l56);115		break;116	case HDA_GEN_PCM_ACT_CLEANUP:117		if (!cs35l56->playing)118			break;119 120		cs35l56_hda_pause(cs35l56);121		break;122	default:123		break;124	}125}126 127static int cs35l56_hda_runtime_suspend(struct device *dev)128{129	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);130 131	if (cs35l56->cs_dsp.booted)132		cs_dsp_stop(&cs35l56->cs_dsp);133 134	return cs35l56_runtime_suspend_common(&cs35l56->base);135}136 137static int cs35l56_hda_runtime_resume(struct device *dev)138{139	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);140	int ret;141 142	ret = cs35l56_runtime_resume_common(&cs35l56->base, false);143	if (ret < 0)144		return ret;145 146	if (cs35l56->cs_dsp.booted) {147		ret = cs_dsp_run(&cs35l56->cs_dsp);148		if (ret) {149			dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);150			goto err;151		}152	}153 154	ret = cs35l56_force_sync_asp1_registers_from_cache(&cs35l56->base);155	if (ret)156		goto err;157 158	return 0;159 160err:161	cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE);162	regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,163		     CS35L56_MBOX_CMD_HIBERNATE_NOW);164 165	regcache_cache_only(cs35l56->base.regmap, true);166 167	return ret;168}169 170static int cs35l56_hda_mixer_info(struct snd_kcontrol *kcontrol,171				  struct snd_ctl_elem_info *uinfo)172{173	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;174	uinfo->count = 1;175	uinfo->value.enumerated.items = CS35L56_NUM_INPUT_SRC;176	if (uinfo->value.enumerated.item >= CS35L56_NUM_INPUT_SRC)177		uinfo->value.enumerated.item = CS35L56_NUM_INPUT_SRC - 1;178	strscpy(uinfo->value.enumerated.name, cs35l56_tx_input_texts[uinfo->value.enumerated.item],179		sizeof(uinfo->value.enumerated.name));180 181	return 0;182}183 184static int cs35l56_hda_mixer_get(struct snd_kcontrol *kcontrol,185				 struct snd_ctl_elem_value *ucontrol)186{187	struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;188	unsigned int reg_val;189	int i;190 191	cs35l56_hda_wait_dsp_ready(cs35l56);192 193	regmap_read(cs35l56->base.regmap, kcontrol->private_value, &reg_val);194	reg_val &= CS35L56_ASP_TXn_SRC_MASK;195 196	for (i = 0; i < CS35L56_NUM_INPUT_SRC; ++i) {197		if (cs35l56_tx_input_values[i] == reg_val) {198			ucontrol->value.enumerated.item[0] = i;199			break;200		}201	}202 203	return 0;204}205 206static int cs35l56_hda_mixer_put(struct snd_kcontrol *kcontrol,207				 struct snd_ctl_elem_value *ucontrol)208{209	struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;210	unsigned int item = ucontrol->value.enumerated.item[0];211	bool changed;212 213	if (item >= CS35L56_NUM_INPUT_SRC)214		return -EINVAL;215 216	cs35l56_hda_wait_dsp_ready(cs35l56);217 218	regmap_update_bits_check(cs35l56->base.regmap, kcontrol->private_value,219				 CS35L56_INPUT_MASK, cs35l56_tx_input_values[item],220				 &changed);221 222	return changed;223}224 225static int cs35l56_hda_posture_info(struct snd_kcontrol *kcontrol,226				    struct snd_ctl_elem_info *uinfo)227{228	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;229	uinfo->count = 1;230	uinfo->value.integer.min = CS35L56_MAIN_POSTURE_MIN;231	uinfo->value.integer.max = CS35L56_MAIN_POSTURE_MAX;232	return 0;233}234 235static int cs35l56_hda_posture_get(struct snd_kcontrol *kcontrol,236				   struct snd_ctl_elem_value *ucontrol)237{238	struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;239	unsigned int pos;240	int ret;241 242	cs35l56_hda_wait_dsp_ready(cs35l56);243 244	ret = regmap_read(cs35l56->base.regmap, CS35L56_MAIN_POSTURE_NUMBER, &pos);245	if (ret)246		return ret;247 248	ucontrol->value.integer.value[0] = pos;249 250	return 0;251}252 253static int cs35l56_hda_posture_put(struct snd_kcontrol *kcontrol,254				   struct snd_ctl_elem_value *ucontrol)255{256	struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;257	unsigned long pos = ucontrol->value.integer.value[0];258	bool changed;259	int ret;260 261	if ((pos < CS35L56_MAIN_POSTURE_MIN) ||262	    (pos > CS35L56_MAIN_POSTURE_MAX))263		return -EINVAL;264 265	cs35l56_hda_wait_dsp_ready(cs35l56);266 267	ret = regmap_update_bits_check(cs35l56->base.regmap,268				       CS35L56_MAIN_POSTURE_NUMBER,269				       CS35L56_MAIN_POSTURE_MASK,270				       pos, &changed);271	if (ret)272		return ret;273 274	return changed;275}276 277static const struct {278	const char *name;279	unsigned int reg;280} cs35l56_hda_mixer_controls[] = {281	{ "ASP1 TX1 Source", CS35L56_ASP1TX1_INPUT },282	{ "ASP1 TX2 Source", CS35L56_ASP1TX2_INPUT },283	{ "ASP1 TX3 Source", CS35L56_ASP1TX3_INPUT },284	{ "ASP1 TX4 Source", CS35L56_ASP1TX4_INPUT },285};286 287static const DECLARE_TLV_DB_SCALE(cs35l56_hda_vol_tlv, -10000, 25, 0);288 289static int cs35l56_hda_vol_info(struct snd_kcontrol *kcontrol,290				struct snd_ctl_elem_info *uinfo)291{292	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;293	uinfo->count = 1;294	uinfo->value.integer.step = 1;295	uinfo->value.integer.min = 0;296	uinfo->value.integer.max = CS35L56_MAIN_RENDER_USER_VOLUME_MAX -297				   CS35L56_MAIN_RENDER_USER_VOLUME_MIN;298 299	return 0;300}301 302static int cs35l56_hda_vol_get(struct snd_kcontrol *kcontrol,303			       struct snd_ctl_elem_value *ucontrol)304{305	struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;306	unsigned int raw_vol;307	int vol;308	int ret;309 310	cs35l56_hda_wait_dsp_ready(cs35l56);311 312	ret = regmap_read(cs35l56->base.regmap, CS35L56_MAIN_RENDER_USER_VOLUME, &raw_vol);313 314	if (ret)315		return ret;316 317	vol = (s16)(raw_vol & 0xFFFF);318	vol >>= CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT;319 320	if (vol & BIT(CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT))321		vol |= ~((int)(BIT(CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT) - 1));322 323	ucontrol->value.integer.value[0] = vol - CS35L56_MAIN_RENDER_USER_VOLUME_MIN;324 325	return 0;326}327 328static int cs35l56_hda_vol_put(struct snd_kcontrol *kcontrol,329			       struct snd_ctl_elem_value *ucontrol)330{331	struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;332	long vol = ucontrol->value.integer.value[0];333	unsigned int raw_vol;334	bool changed;335	int ret;336 337	if ((vol < 0) || (vol > (CS35L56_MAIN_RENDER_USER_VOLUME_MAX -338				 CS35L56_MAIN_RENDER_USER_VOLUME_MIN)))339		return -EINVAL;340 341	raw_vol = (vol + CS35L56_MAIN_RENDER_USER_VOLUME_MIN) <<342		  CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT;343 344	cs35l56_hda_wait_dsp_ready(cs35l56);345 346	ret = regmap_update_bits_check(cs35l56->base.regmap,347				       CS35L56_MAIN_RENDER_USER_VOLUME,348				       CS35L56_MAIN_RENDER_USER_VOLUME_MASK,349				       raw_vol, &changed);350	if (ret)351		return ret;352 353	return changed;354}355 356static void cs35l56_hda_create_controls(struct cs35l56_hda *cs35l56)357{358	struct snd_kcontrol_new ctl_template = {359		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,360		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,361		.info = cs35l56_hda_posture_info,362		.get = cs35l56_hda_posture_get,363		.put = cs35l56_hda_posture_put,364	};365	char name[64];366	int i;367 368	snprintf(name, sizeof(name), "%s Posture Number", cs35l56->amp_name);369	ctl_template.name = name;370	cs35l56->posture_ctl = snd_ctl_new1(&ctl_template, cs35l56);371	if (snd_ctl_add(cs35l56->codec->card, cs35l56->posture_ctl))372		dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n", ctl_template.name);373 374	/* Mixer controls */375	ctl_template.info = cs35l56_hda_mixer_info;376	ctl_template.get = cs35l56_hda_mixer_get;377	ctl_template.put = cs35l56_hda_mixer_put;378 379	BUILD_BUG_ON(ARRAY_SIZE(cs35l56->mixer_ctl) != ARRAY_SIZE(cs35l56_hda_mixer_controls));380 381	for (i = 0; i < ARRAY_SIZE(cs35l56_hda_mixer_controls); ++i) {382		snprintf(name, sizeof(name), "%s %s", cs35l56->amp_name,383			 cs35l56_hda_mixer_controls[i].name);384		ctl_template.private_value = cs35l56_hda_mixer_controls[i].reg;385		cs35l56->mixer_ctl[i] = snd_ctl_new1(&ctl_template, cs35l56);386		if (snd_ctl_add(cs35l56->codec->card, cs35l56->mixer_ctl[i])) {387			dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n",388				ctl_template.name);389		}390	}391 392	ctl_template.info = cs35l56_hda_vol_info;393	ctl_template.get = cs35l56_hda_vol_get;394	ctl_template.put = cs35l56_hda_vol_put;395	ctl_template.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ);396	ctl_template.tlv.p = cs35l56_hda_vol_tlv;397	snprintf(name, sizeof(name), "%s Speaker Playback Volume", cs35l56->amp_name);398	ctl_template.name = name;399	cs35l56->volume_ctl = snd_ctl_new1(&ctl_template, cs35l56);400	if (snd_ctl_add(cs35l56->codec->card, cs35l56->volume_ctl))401		dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n", ctl_template.name);402}403 404static void cs35l56_hda_remove_controls(struct cs35l56_hda *cs35l56)405{406	int i;407 408	for (i = ARRAY_SIZE(cs35l56->mixer_ctl) - 1; i >= 0; i--)409		snd_ctl_remove(cs35l56->codec->card, cs35l56->mixer_ctl[i]);410 411	snd_ctl_remove(cs35l56->codec->card, cs35l56->posture_ctl);412	snd_ctl_remove(cs35l56->codec->card, cs35l56->volume_ctl);413}414 415static const struct cs_dsp_client_ops cs35l56_hda_client_ops = {416	/* cs_dsp requires the client to provide this even if it is empty */417};418 419static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56,420					     const struct firmware **firmware, char **filename,421					     const char *base_name, const char *system_name,422					     const char *amp_name,423					     const char *filetype)424{425	char *s, c;426	int ret = 0;427 428	if (system_name && amp_name)429		*filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", base_name,430				      system_name, amp_name, filetype);431	else if (system_name)432		*filename = kasprintf(GFP_KERNEL, "%s-%s.%s", base_name,433				      system_name, filetype);434	else435		*filename = kasprintf(GFP_KERNEL, "%s.%s", base_name, filetype);436 437	if (!*filename)438		return -ENOMEM;439 440	/*441	 * Make sure that filename is lower-case and any non alpha-numeric442	 * characters except full stop and forward slash are replaced with443	 * hyphens.444	 */445	s = *filename;446	while (*s) {447		c = *s;448		if (isalnum(c))449			*s = tolower(c);450		else if (c != '.' && c != '/')451			*s = '-';452		s++;453	}454 455	ret = firmware_request_nowarn(firmware, *filename, cs35l56->base.dev);456	if (ret) {457		dev_dbg(cs35l56->base.dev, "Failed to request '%s'\n", *filename);458		kfree(*filename);459		*filename = NULL;460		return ret;461	}462 463	dev_dbg(cs35l56->base.dev, "Found '%s'\n", *filename);464 465	return 0;466}467 468static void cs35l56_hda_request_firmware_files(struct cs35l56_hda *cs35l56,469					       unsigned int preloaded_fw_ver,470					       const struct firmware **wmfw_firmware,471					       char **wmfw_filename,472					       const struct firmware **coeff_firmware,473					       char **coeff_filename)474{475	const char *system_name = cs35l56->system_name;476	const char *amp_name = cs35l56->amp_name;477	char base_name[37];478	int ret;479 480	if (preloaded_fw_ver) {481		snprintf(base_name, sizeof(base_name),482			 "cirrus/cs35l%02x-%02x%s-%06x-dsp1-misc",483			 cs35l56->base.type,484			 cs35l56->base.rev,485			 cs35l56->base.secured ? "-s" : "",486			 preloaded_fw_ver & 0xffffff);487	} else {488		snprintf(base_name, sizeof(base_name),489			 "cirrus/cs35l%02x-%02x%s-dsp1-misc",490			 cs35l56->base.type,491			 cs35l56->base.rev,492			 cs35l56->base.secured ? "-s" : "");493	}494 495	if (system_name && amp_name) {496		if (!cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,497						       base_name, system_name, amp_name, "wmfw")) {498			cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,499							  base_name, system_name, amp_name, "bin");500			return;501		}502	}503 504	if (system_name) {505		if (!cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,506						       base_name, system_name, NULL, "wmfw")) {507			if (amp_name)508				cs35l56_hda_request_firmware_file(cs35l56,509								  coeff_firmware, coeff_filename,510								  base_name, system_name,511								  amp_name, "bin");512			if (!*coeff_firmware)513				cs35l56_hda_request_firmware_file(cs35l56,514								  coeff_firmware, coeff_filename,515								  base_name, system_name,516								  NULL, "bin");517			return;518		}519 520		/*521		 * Check for system-specific bin files without wmfw before522		 * falling back to generic firmware523		 */524		if (amp_name)525			cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,526							  base_name, system_name, amp_name, "bin");527		if (!*coeff_firmware)528			cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,529							  base_name, system_name, NULL, "bin");530 531		if (*coeff_firmware)532			return;533	}534 535	ret = cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,536						base_name, NULL, NULL, "wmfw");537	if (!ret) {538		cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,539						  base_name, NULL, NULL, "bin");540		return;541	}542 543	if (!*coeff_firmware)544		cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,545						  base_name, NULL, NULL, "bin");546}547 548static void cs35l56_hda_release_firmware_files(const struct firmware *wmfw_firmware,549					       char *wmfw_filename,550					       const struct firmware *coeff_firmware,551					       char *coeff_filename)552{553	if (wmfw_firmware)554		release_firmware(wmfw_firmware);555	kfree(wmfw_filename);556 557	if (coeff_firmware)558		release_firmware(coeff_firmware);559	kfree(coeff_filename);560}561 562static void cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56)563{564	int ret;565 566	if (!cs35l56->base.cal_data_valid || cs35l56->base.secured)567		return;568 569	ret = cs_amp_write_cal_coeffs(&cs35l56->cs_dsp,570				      &cs35l56_calibration_controls,571				      &cs35l56->base.cal_data);572	if (ret < 0)573		dev_warn(cs35l56->base.dev, "Failed to write calibration: %d\n", ret);574	else575		dev_info(cs35l56->base.dev, "Calibration applied\n");576}577 578static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)579{580	const struct firmware *coeff_firmware = NULL;581	const struct firmware *wmfw_firmware = NULL;582	char *coeff_filename = NULL;583	char *wmfw_filename = NULL;584	unsigned int preloaded_fw_ver;585	bool firmware_missing;586	int ret;587 588	/*589	 * Prepare for a new DSP power-up. If the DSP has had firmware590	 * downloaded previously then it needs to be powered down so that it591	 * can be updated.592	 */593	if (cs35l56->base.fw_patched)594		cs_dsp_power_down(&cs35l56->cs_dsp);595 596	cs35l56->base.fw_patched = false;597 598	ret = pm_runtime_resume_and_get(cs35l56->base.dev);599	if (ret < 0) {600		dev_err(cs35l56->base.dev, "Failed to resume and get %d\n", ret);601		return;602	}603 604	/*605	 * The firmware can only be upgraded if it is currently running606	 * from the built-in ROM. If not, the wmfw/bin must be for the607	 * version of firmware that is running on the chip.608	 */609	ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &preloaded_fw_ver);610	if (ret)611		goto err_pm_put;612 613	if (firmware_missing)614		preloaded_fw_ver = 0;615 616	cs35l56_hda_request_firmware_files(cs35l56, preloaded_fw_ver,617					   &wmfw_firmware, &wmfw_filename,618					   &coeff_firmware, &coeff_filename);619 620	/*621	 * If the BIOS didn't patch the firmware a bin file is mandatory to622	 * enable the ASP·623	 */624	if (!coeff_firmware && firmware_missing) {625		dev_err(cs35l56->base.dev, ".bin file required but not found\n");626		goto err_fw_release;627	}628 629	mutex_lock(&cs35l56->base.irq_lock);630 631	/*632	 * If the firmware hasn't been patched it must be shutdown before633	 * doing a full patch and reset afterwards. If it is already634	 * running a patched version the firmware files only contain635	 * tunings and we can use the lower cost reinit sequence instead.636	 */637	if (firmware_missing && (wmfw_firmware || coeff_firmware)) {638		ret = cs35l56_firmware_shutdown(&cs35l56->base);639		if (ret)640			goto err;641	}642 643	ret = cs_dsp_power_up(&cs35l56->cs_dsp, wmfw_firmware, wmfw_filename,644			      coeff_firmware, coeff_filename, "misc");645	if (ret) {646		dev_dbg(cs35l56->base.dev, "%s: cs_dsp_power_up ret %d\n", __func__, ret);647		goto err;648	}649 650	if (wmfw_filename)651		dev_dbg(cs35l56->base.dev, "Loaded WMFW Firmware: %s\n", wmfw_filename);652 653	if (coeff_filename)654		dev_dbg(cs35l56->base.dev, "Loaded Coefficients: %s\n", coeff_filename);655 656	/* If we downloaded firmware, reset the device and wait for it to boot */657	if (firmware_missing && (wmfw_firmware || coeff_firmware)) {658		cs35l56_system_reset(&cs35l56->base, false);659		regcache_mark_dirty(cs35l56->base.regmap);660		ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);661		if (ret)662			goto err_powered_up;663 664		regcache_cache_only(cs35l56->base.regmap, false);665	}666 667	/* Disable auto-hibernate so that runtime_pm has control */668	ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);669	if (ret)670		goto err_powered_up;671 672	regcache_sync(cs35l56->base.regmap);673 674	regmap_clear_bits(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS,675			  CS35L56_FIRMWARE_MISSING);676	cs35l56->base.fw_patched = true;677 678	ret = cs_dsp_run(&cs35l56->cs_dsp);679	if (ret)680		dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);681 682	cs35l56_hda_apply_calibration(cs35l56);683	ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);684	if (ret)685		cs_dsp_stop(&cs35l56->cs_dsp);686 687err_powered_up:688	if (!cs35l56->base.fw_patched)689		cs_dsp_power_down(&cs35l56->cs_dsp);690err:691	mutex_unlock(&cs35l56->base.irq_lock);692err_fw_release:693	cs35l56_hda_release_firmware_files(wmfw_firmware, wmfw_filename,694					   coeff_firmware, coeff_filename);695err_pm_put:696	pm_runtime_put(cs35l56->base.dev);697}698 699static void cs35l56_hda_dsp_work(struct work_struct *work)700{701	struct cs35l56_hda *cs35l56 = container_of(work, struct cs35l56_hda, dsp_work);702 703	cs35l56_hda_fw_load(cs35l56);704}705 706static int cs35l56_hda_bind(struct device *dev, struct device *master, void *master_data)707{708	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);709	struct hda_component_parent *parent = master_data;710	struct hda_component *comp;711 712	comp = hda_component_from_index(parent, cs35l56->index);713	if (!comp)714		return -EINVAL;715 716	if (comp->dev)717		return -EBUSY;718 719	comp->dev = dev;720	cs35l56->codec = parent->codec;721	strscpy(comp->name, dev_name(dev), sizeof(comp->name));722	comp->playback_hook = cs35l56_hda_playback_hook;723 724	queue_work(system_long_wq, &cs35l56->dsp_work);725 726	cs35l56_hda_create_controls(cs35l56);727 728#if IS_ENABLED(CONFIG_SND_DEBUG)729	cs35l56->debugfs_root = debugfs_create_dir(dev_name(cs35l56->base.dev), sound_debugfs_root);730	cs_dsp_init_debugfs(&cs35l56->cs_dsp, cs35l56->debugfs_root);731#endif732 733	dev_dbg(cs35l56->base.dev, "Bound\n");734 735	return 0;736}737 738static void cs35l56_hda_unbind(struct device *dev, struct device *master, void *master_data)739{740	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);741	struct hda_component_parent *parent = master_data;742	struct hda_component *comp;743 744	cancel_work_sync(&cs35l56->dsp_work);745 746	cs35l56_hda_remove_controls(cs35l56);747 748#if IS_ENABLED(CONFIG_SND_DEBUG)749	cs_dsp_cleanup_debugfs(&cs35l56->cs_dsp);750	debugfs_remove_recursive(cs35l56->debugfs_root);751#endif752 753	if (cs35l56->base.fw_patched)754		cs_dsp_power_down(&cs35l56->cs_dsp);755 756	comp = hda_component_from_index(parent, cs35l56->index);757	if (comp && (comp->dev == dev))758		memset(comp, 0, sizeof(*comp));759 760	cs35l56->codec = NULL;761 762	dev_dbg(cs35l56->base.dev, "Unbound\n");763}764 765static const struct component_ops cs35l56_hda_comp_ops = {766	.bind = cs35l56_hda_bind,767	.unbind = cs35l56_hda_unbind,768};769 770static int cs35l56_hda_system_suspend(struct device *dev)771{772	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);773 774	cs35l56_hda_wait_dsp_ready(cs35l56);775 776	if (cs35l56->playing)777		cs35l56_hda_pause(cs35l56);778 779	cs35l56->suspended = true;780 781	/*782	 * The interrupt line is normally shared, but after we start suspending783	 * we can't check if our device is the source of an interrupt, and can't784	 * clear it. Prevent this race by temporarily disabling the parent irq785	 * until we reach _no_irq.786	 */787	if (cs35l56->base.irq)788		disable_irq(cs35l56->base.irq);789 790	return pm_runtime_force_suspend(dev);791}792 793static int cs35l56_hda_system_suspend_late(struct device *dev)794{795	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);796 797	/*798	 * RESET is usually shared by all amps so it must not be asserted until799	 * all driver instances have done their suspend() stage.800	 */801	if (cs35l56->base.reset_gpio) {802		gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);803		cs35l56_wait_min_reset_pulse();804	}805 806	return 0;807}808 809static int cs35l56_hda_system_suspend_no_irq(struct device *dev)810{811	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);812 813	/* Handlers are now disabled so the parent IRQ can safely be re-enabled. */814	if (cs35l56->base.irq)815		enable_irq(cs35l56->base.irq);816 817	return 0;818}819 820static int cs35l56_hda_system_resume_no_irq(struct device *dev)821{822	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);823 824	/*825	 * WAKE interrupts unmask if the CS35L56 hibernates, which can cause826	 * spurious interrupts, and the interrupt line is normally shared.827	 * We can't check if our device is the source of an interrupt, and can't828	 * clear it, until it has fully resumed. Prevent this race by temporarily829	 * disabling the parent irq until we complete resume().830	 */831	if (cs35l56->base.irq)832		disable_irq(cs35l56->base.irq);833 834	return 0;835}836 837static int cs35l56_hda_system_resume_early(struct device *dev)838{839	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);840 841	/* Ensure a spec-compliant RESET pulse. */842	if (cs35l56->base.reset_gpio) {843		gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);844		cs35l56_wait_min_reset_pulse();845 846		/* Release shared RESET before drivers start resume(). */847		gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);848		cs35l56_wait_control_port_ready();849	}850 851	return 0;852}853 854static int cs35l56_hda_system_resume(struct device *dev)855{856	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);857	int ret;858 859	/* Undo pm_runtime_force_suspend() before re-enabling the irq */860	ret = pm_runtime_force_resume(dev);861	if (cs35l56->base.irq)862		enable_irq(cs35l56->base.irq);863 864	if (ret)865		return ret;866 867	cs35l56->suspended = false;868 869	if (!cs35l56->codec)870		return 0;871 872	ret = cs35l56_is_fw_reload_needed(&cs35l56->base);873	dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret);874	if (ret > 0)875		queue_work(system_long_wq, &cs35l56->dsp_work);876 877	if (cs35l56->playing)878		cs35l56_hda_play(cs35l56);879 880	return 0;881}882 883static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)884{885	u32 values[HDA_MAX_COMPONENTS];886	char hid_string[8];887	struct acpi_device *adev;888	const char *property, *sub;889	size_t nval;890	int i, ret;891 892	/*893	 * ACPI_COMPANION isn't available when this driver was instantiated by894	 * the serial-multi-instantiate driver, so lookup the node by HID895	 */896	if (!ACPI_COMPANION(cs35l56->base.dev)) {897		snprintf(hid_string, sizeof(hid_string), "CSC%04X", hid);898		adev = acpi_dev_get_first_match_dev(hid_string, NULL, -1);899		if (!adev) {900			dev_err(cs35l56->base.dev, "Failed to find an ACPI device for %s\n",901				dev_name(cs35l56->base.dev));902			return -ENODEV;903		}904		ACPI_COMPANION_SET(cs35l56->base.dev, adev);905	}906 907	property = "cirrus,dev-index";908	ret = device_property_count_u32(cs35l56->base.dev, property);909	if (ret <= 0)910		goto err;911 912	if (ret > ARRAY_SIZE(values)) {913		ret = -EINVAL;914		goto err;915	}916	nval = ret;917 918	ret = device_property_read_u32_array(cs35l56->base.dev, property, values, nval);919	if (ret)920		goto err;921 922	cs35l56->index = -1;923	for (i = 0; i < nval; i++) {924		if (values[i] == id) {925			cs35l56->index = i;926			break;927		}928	}929	/*930	 * It's not an error for the ID to be missing: for I2C there can be931	 * an alias address that is not a real device. So reject silently.932	 */933	if (cs35l56->index == -1) {934		dev_dbg(cs35l56->base.dev, "No index found in %s\n", property);935		ret = -ENODEV;936		goto err;937	}938 939	sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));940 941	if (IS_ERR(sub)) {942		dev_info(cs35l56->base.dev,943			 "Read ACPI _SUB failed(%ld): fallback to generic firmware\n",944			 PTR_ERR(sub));945	} else {946		ret = cirrus_scodec_get_speaker_id(cs35l56->base.dev, cs35l56->index, nval, -1);947		if (ret == -ENOENT) {948			cs35l56->system_name = sub;949		} else if (ret >= 0) {950			cs35l56->system_name = kasprintf(GFP_KERNEL, "%s-spkid%d", sub, ret);951			kfree(sub);952			if (!cs35l56->system_name)953				return -ENOMEM;954		} else {955			return ret;956		}957	}958 959	cs35l56->base.reset_gpio = devm_gpiod_get_index_optional(cs35l56->base.dev,960								 "reset",961								 cs35l56->index,962								 GPIOD_OUT_LOW);963	if (IS_ERR(cs35l56->base.reset_gpio)) {964		ret = PTR_ERR(cs35l56->base.reset_gpio);965 966		/*967		 * If RESET is shared the first amp to probe will grab the reset968		 * line and reset all the amps969		 */970		if (ret != -EBUSY)971			return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n");972 973		dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n");974		cs35l56->base.reset_gpio = NULL;975	}976 977	return 0;978 979err:980	if (ret != -ENODEV)981		dev_err(cs35l56->base.dev, "Failed property %s: %d\n", property, ret);982 983	return ret;984}985 986int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)987{988	int ret;989 990	mutex_init(&cs35l56->base.irq_lock);991	dev_set_drvdata(cs35l56->base.dev, cs35l56);992 993	INIT_WORK(&cs35l56->dsp_work, cs35l56_hda_dsp_work);994 995	ret = cs35l56_hda_read_acpi(cs35l56, hid, id);996	if (ret)997		goto err;998 999	cs35l56->amp_name = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, "AMP%d",1000					   cs35l56->index + 1);1001	if (!cs35l56->amp_name) {1002		ret = -ENOMEM;1003		goto err;1004	}1005 1006	cs35l56->base.cal_index = -1;1007 1008	cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp);1009	cs35l56->cs_dsp.client_ops = &cs35l56_hda_client_ops;1010 1011	if (cs35l56->base.reset_gpio) {1012		dev_dbg(cs35l56->base.dev, "Hard reset\n");1013 1014		/*1015		 * The GPIOD_OUT_LOW to *_gpiod_get_*() will be ignored if the1016		 * ACPI defines a different default state. So explicitly set low.1017		 */1018		gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);1019		cs35l56_wait_min_reset_pulse();1020		gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);1021	}1022 1023	ret = cs35l56_hw_init(&cs35l56->base);1024	if (ret < 0)1025		goto err;1026 1027	/* Reset the device and wait for it to boot */1028	cs35l56_system_reset(&cs35l56->base, false);1029	ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);1030	if (ret)1031		goto err;1032 1033	regcache_cache_only(cs35l56->base.regmap, false);1034 1035	ret = cs35l56_set_patch(&cs35l56->base);1036	if (ret)1037		goto err;1038 1039	regcache_mark_dirty(cs35l56->base.regmap);1040	regcache_sync(cs35l56->base.regmap);1041 1042	/* Disable auto-hibernate so that runtime_pm has control */1043	ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);1044	if (ret)1045		goto err;1046 1047	ret = cs35l56_get_calibration(&cs35l56->base);1048	if (ret)1049		goto err;1050 1051	ret = cs_dsp_halo_init(&cs35l56->cs_dsp);1052	if (ret) {1053		dev_err_probe(cs35l56->base.dev, ret, "cs_dsp_halo_init failed\n");1054		goto err;1055	}1056 1057	dev_info(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",1058		 cs35l56->system_name, cs35l56->amp_name);1059 1060	regmap_multi_reg_write(cs35l56->base.regmap, cs35l56_hda_dai_config,1061			       ARRAY_SIZE(cs35l56_hda_dai_config));1062	ret = cs35l56_force_sync_asp1_registers_from_cache(&cs35l56->base);1063	if (ret)1064		goto dsp_err;1065 1066	/*1067	 * By default only enable one ASP1TXn, where n=amplifier index,1068	 * This prevents multiple amps trying to drive the same slot.1069	 */1070	cs35l56->asp_tx_mask = BIT(cs35l56->index);1071 1072	pm_runtime_set_autosuspend_delay(cs35l56->base.dev, 3000);1073	pm_runtime_use_autosuspend(cs35l56->base.dev);1074	pm_runtime_set_active(cs35l56->base.dev);1075	pm_runtime_mark_last_busy(cs35l56->base.dev);1076	pm_runtime_enable(cs35l56->base.dev);1077 1078	cs35l56->base.init_done = true;1079 1080	ret = component_add(cs35l56->base.dev, &cs35l56_hda_comp_ops);1081	if (ret) {1082		dev_err(cs35l56->base.dev, "Register component failed: %d\n", ret);1083		goto pm_err;1084	}1085 1086	return 0;1087 1088pm_err:1089	pm_runtime_disable(cs35l56->base.dev);1090dsp_err:1091	cs_dsp_remove(&cs35l56->cs_dsp);1092err:1093	gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);1094 1095	return ret;1096}1097EXPORT_SYMBOL_NS_GPL(cs35l56_hda_common_probe, SND_HDA_SCODEC_CS35L56);1098 1099void cs35l56_hda_remove(struct device *dev)1100{1101	struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);1102 1103	component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops);1104 1105	pm_runtime_dont_use_autosuspend(cs35l56->base.dev);1106	pm_runtime_get_sync(cs35l56->base.dev);1107	pm_runtime_disable(cs35l56->base.dev);1108 1109	cs_dsp_remove(&cs35l56->cs_dsp);1110 1111	kfree(cs35l56->system_name);1112	pm_runtime_put_noidle(cs35l56->base.dev);1113 1114	gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);1115}1116EXPORT_SYMBOL_NS_GPL(cs35l56_hda_remove, SND_HDA_SCODEC_CS35L56);1117 1118const struct dev_pm_ops cs35l56_hda_pm_ops = {1119	RUNTIME_PM_OPS(cs35l56_hda_runtime_suspend, cs35l56_hda_runtime_resume, NULL)1120	SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend, cs35l56_hda_system_resume)1121	LATE_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_late,1122				 cs35l56_hda_system_resume_early)1123	NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_no_irq,1124				  cs35l56_hda_system_resume_no_irq)1125};1126EXPORT_SYMBOL_NS_GPL(cs35l56_hda_pm_ops, SND_HDA_SCODEC_CS35L56);1127 1128MODULE_DESCRIPTION("CS35L56 HDA Driver");1129MODULE_IMPORT_NS(FW_CS_DSP);1130MODULE_IMPORT_NS(SND_HDA_CIRRUS_SCODEC);1131MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS);1132MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);1133MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB);1134MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");1135MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");1136MODULE_LICENSE("GPL");1137