diff options
| -rw-r--r-- | include/uapi/sound/asoc.h | 35 | ||||
| -rw-r--r-- | sound/firewire/amdtp.c | 5 | ||||
| -rw-r--r-- | sound/firewire/amdtp.h | 2 | ||||
| -rw-r--r-- | sound/firewire/fireworks/fireworks.c | 10 | ||||
| -rw-r--r-- | sound/firewire/fireworks/fireworks.h | 2 | ||||
| -rw-r--r-- | sound/firewire/fireworks/fireworks_stream.c | 12 | ||||
| -rw-r--r-- | sound/hda/ext/hdac_ext_controller.c | 6 | ||||
| -rw-r--r-- | sound/hda/ext/hdac_ext_stream.c | 2 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 1 | ||||
| -rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/cs4265.c | 10 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5645.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5645.h | 4 | ||||
| -rw-r--r-- | sound/soc/intel/baytrail/sst-baytrail-ipc.c | 2 | ||||
| -rw-r--r-- | sound/soc/intel/haswell/sst-haswell-ipc.c | 2 | ||||
| -rw-r--r-- | sound/soc/soc-topology.c | 61 | 
16 files changed, 108 insertions, 50 deletions
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h index 785c5ca0994b..51b8066a223b 100644 --- a/include/uapi/sound/asoc.h +++ b/include/uapi/sound/asoc.h @@ -77,7 +77,7 @@  #define SND_SOC_TPLG_NUM_TEXTS		16  /* ABI version */ -#define SND_SOC_TPLG_ABI_VERSION	0x2 +#define SND_SOC_TPLG_ABI_VERSION	0x3  /* Max size of TLV data */  #define SND_SOC_TPLG_TLV_SIZE		32 @@ -97,7 +97,8 @@  #define SND_SOC_TPLG_TYPE_PCM		7  #define SND_SOC_TPLG_TYPE_MANIFEST	8  #define SND_SOC_TPLG_TYPE_CODEC_LINK	9 -#define SND_SOC_TPLG_TYPE_MAX	SND_SOC_TPLG_TYPE_CODEC_LINK +#define SND_SOC_TPLG_TYPE_PDATA		10 +#define SND_SOC_TPLG_TYPE_MAX	SND_SOC_TPLG_TYPE_PDATA  /* vendor block IDs - please add new vendor types to end */  #define SND_SOC_TPLG_TYPE_VENDOR_FW	1000 @@ -137,11 +138,19 @@ struct snd_soc_tplg_private {  /*   * Kcontrol TLV data.   */ +struct snd_soc_tplg_tlv_dbscale { +	__le32 min; +	__le32 step; +	__le32 mute; +} __attribute__((packed)); +  struct snd_soc_tplg_ctl_tlv { -	__le32 size;	/* in bytes aligned to 4 */ -	__le32 numid;	/* control element numeric identification */ -	__le32 count;	/* number of elem in data array */ -	__le32 data[SND_SOC_TPLG_TLV_SIZE]; +	__le32 size;	/* in bytes of this structure */ +	__le32 type;	/* SNDRV_CTL_TLVT_*, type of TLV */ +	union { +		__le32 data[SND_SOC_TPLG_TLV_SIZE]; +		struct snd_soc_tplg_tlv_dbscale scale; +	};  } __attribute__((packed));  /* @@ -155,9 +164,11 @@ struct snd_soc_tplg_channel {  } __attribute__((packed));  /* - * Kcontrol Operations IDs + * Genericl Operations IDs, for binding Kcontrol or Bytes ext ops + * Kcontrol ops need get/put/info. + * Bytes ext ops need get/put.   */ -struct snd_soc_tplg_kcontrol_ops_id { +struct snd_soc_tplg_io_ops {  	__le32 get;  	__le32 put;  	__le32 info; @@ -171,8 +182,8 @@ struct snd_soc_tplg_ctl_hdr {  	__le32 type;  	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];  	__le32 access; -	struct snd_soc_tplg_kcontrol_ops_id ops; -	__le32 tlv_size;	/* non zero means control has TLV data */ +	struct snd_soc_tplg_io_ops ops; +	struct snd_soc_tplg_ctl_tlv tlv;  } __attribute__((packed));  /* @@ -238,6 +249,7 @@ struct snd_soc_tplg_manifest {  	__le32 graph_elems;	/* number of graph elements */  	__le32 dai_elems;	/* number of DAI elements */  	__le32 dai_link_elems;	/* number of DAI link elements */ +	struct snd_soc_tplg_private priv;  } __attribute__((packed));  /* @@ -259,7 +271,6 @@ struct snd_soc_tplg_mixer_control {  	__le32 invert;  	__le32 num_channels;  	struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN]; -	struct snd_soc_tplg_ctl_tlv tlv;  	struct snd_soc_tplg_private priv;  } __attribute__((packed)); @@ -303,6 +314,7 @@ struct snd_soc_tplg_bytes_control {  	__le32 mask;  	__le32 base;  	__le32 num_regs; +	struct snd_soc_tplg_io_ops ext_ops;  	struct snd_soc_tplg_private priv;  } __attribute__((packed)); @@ -347,6 +359,7 @@ struct snd_soc_tplg_dapm_widget {  	__le32 reg;		/* negative reg = no direct dapm */  	__le32 shift;		/* bits to shift */  	__le32 mask;		/* non-shifted mask */ +	__le32 subseq;		/* sort within widget type */  	__u32 invert;		/* invert the power bit */  	__u32 ignore_suspend;	/* kept enabled over suspend */  	__u16 event_flags; diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 7bb988fa6b6d..2a153d260836 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -740,8 +740,9 @@ static int handle_in_packet(struct amdtp_stream *s,  	    s->data_block_counter != UINT_MAX)  		data_block_counter = s->data_block_counter; -	if (((s->flags & CIP_SKIP_DBC_ZERO_CHECK) && data_block_counter == 0) || -	    (s->data_block_counter == UINT_MAX)) { +	if (((s->flags & CIP_SKIP_DBC_ZERO_CHECK) && +	     data_block_counter == s->tx_first_dbc) || +	    s->data_block_counter == UINT_MAX) {  		lost = false;  	} else if (!(s->flags & CIP_DBC_IS_END_EVENT)) {  		lost = data_block_counter != s->data_block_counter; diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index 26b909329e54..b2cf9e75693b 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -157,6 +157,8 @@ struct amdtp_stream {  	/* quirk: fixed interval of dbc between previos/current packets. */  	unsigned int tx_dbc_interval; +	/* quirk: indicate the value of dbc field in a first packet. */ +	unsigned int tx_first_dbc;  	bool callbacked;  	wait_queue_head_t callback_wait; diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c index c670db4eee70..c94a432f7cc6 100644 --- a/sound/firewire/fireworks/fireworks.c +++ b/sound/firewire/fireworks/fireworks.c @@ -248,10 +248,16 @@ efw_probe(struct fw_unit *unit,  	err = get_hardware_info(efw);  	if (err < 0)  		goto error; -	if (entry->model_id == MODEL_ECHO_AUDIOFIRE_2) -		efw->is_af2 = true; +	/* AudioFire8 (since 2009) and AudioFirePre8 */  	if (entry->model_id == MODEL_ECHO_AUDIOFIRE_9)  		efw->is_af9 = true; +	/* These models uses the same firmware. */ +	if (entry->model_id == MODEL_ECHO_AUDIOFIRE_2 || +	    entry->model_id == MODEL_ECHO_AUDIOFIRE_4 || +	    entry->model_id == MODEL_ECHO_AUDIOFIRE_9 || +	    entry->model_id == MODEL_GIBSON_RIP || +	    entry->model_id == MODEL_GIBSON_GOLDTOP) +		efw->is_fireworks3 = true;  	snd_efw_proc_init(efw); diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h index c33252b7bc84..084d414b228c 100644 --- a/sound/firewire/fireworks/fireworks.h +++ b/sound/firewire/fireworks/fireworks.h @@ -70,8 +70,8 @@ struct snd_efw {  	bool resp_addr_changable;  	/* for quirks */ -	bool is_af2;  	bool is_af9; +	bool is_fireworks3;  	u32 firmware_version;  	unsigned int midi_in_ports; diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index a0762dd6231e..7e353f1f7bff 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -172,9 +172,15 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)  	efw->tx_stream.flags |= CIP_DBC_IS_END_EVENT;  	/* Fireworks reset dbc at bus reset. */  	efw->tx_stream.flags |= CIP_SKIP_DBC_ZERO_CHECK; -	/* AudioFire2 starts packets with non-zero dbc. */ -	if (efw->is_af2) -		efw->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK; +	/* +	 * But Recent firmwares starts packets with non-zero dbc. +	 * Driver version 5.7.6 installs firmware version 5.7.3. +	 */ +	if (efw->is_fireworks3 && +	    (efw->firmware_version == 0x5070000 || +	     efw->firmware_version == 0x5070300 || +	     efw->firmware_version == 0x5080000)) +		efw->tx_stream.tx_first_dbc = 0x02;  	/* AudioFire9 always reports wrong dbs. */  	if (efw->is_af9)  		efw->tx_stream.flags |= CIP_WRONG_DBS; diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index b2da19b60f4e..358f16195483 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -44,16 +44,10 @@ int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *ebus)  	offset = snd_hdac_chip_readl(bus, LLCH); -	if (offset < 0) -		return -EIO; -  	/* Lets walk the linked capabilities list */  	do {  		cur_cap = _snd_hdac_chip_read(l, bus, offset); -		if (cur_cap < 0) -			return -EIO; -  		dev_dbg(bus->dev, "Capability version: 0x%x\n",  				((cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF)); diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index f8ffbdbb450d..3de47dd1a76d 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -299,7 +299,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,  		if (stream->direction != substream->stream)  			continue; -		if (stream->opened) { +		if (!stream->opened) {  			if (!hstream->decoupled)  				snd_hdac_ext_stream_decouple(ebus, hstream, true);  			res = hstream; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c456c04e0928..0b9847affbec 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5189,6 +5189,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {  	SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),  	SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),  	SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), +	SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX),  	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),  	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),  	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 6492bca8c70f..4ca12665ff73 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -88,7 +88,7 @@ static int dac_mute_put(struct snd_kcontrol *ctl,  	int changed;  	mutex_lock(&chip->mutex); -	changed = !value->value.integer.value[0] != chip->dac_mute; +	changed = (!value->value.integer.value[0]) != chip->dac_mute;  	if (changed) {  		chip->dac_mute = !value->value.integer.value[0];  		chip->model.update_dac_mute(chip); diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index d7ec4756e45b..8e36198474d9 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -457,14 +457,14 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,  	case SND_SOC_DAIFMT_RIGHT_J:  		if (params_width(params) == 16) {  			snd_soc_update_bits(codec, CS4265_DAC_CTL, -				CS4265_DAC_CTL_DIF, (1 << 5)); +				CS4265_DAC_CTL_DIF, (2 << 4));  			snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, -				CS4265_SPDIF_CTL2_DIF, (1 << 7)); +				CS4265_SPDIF_CTL2_DIF, (2 << 6));  		} else {  			snd_soc_update_bits(codec, CS4265_DAC_CTL, -				CS4265_DAC_CTL_DIF, (3 << 5)); +				CS4265_DAC_CTL_DIF, (3 << 4));  			snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, -				CS4265_SPDIF_CTL2_DIF, (1 << 7)); +				CS4265_SPDIF_CTL2_DIF, (3 << 6));  		}  		break;  	case SND_SOC_DAIFMT_LEFT_J: @@ -473,7 +473,7 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,  		snd_soc_update_bits(codec, CS4265_ADC_CTL,  			CS4265_ADC_DIF, 0);  		snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, -			CS4265_SPDIF_CTL2_DIF, (1 << 6)); +			CS4265_SPDIF_CTL2_DIF, 0);  		break;  	default: diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index e9cc3aae5366..961bd7e5877e 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3341,6 +3341,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,  		break;  	case RT5645_DMIC_DATA_GPIO5: +		regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, +			RT5645_I2S2_DAC_PIN_MASK, RT5645_I2S2_DAC_PIN_GPIO);  		regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,  			RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO5);  		regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index 0353a6a273ab..278bb9f464c4 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h @@ -1693,6 +1693,10 @@  #define RT5645_GP6_PIN_SFT			6  #define RT5645_GP6_PIN_GPIO6			(0x0 << 6)  #define RT5645_GP6_PIN_DMIC2_SDA		(0x1 << 6) +#define RT5645_I2S2_DAC_PIN_MASK		(0x1 << 4) +#define RT5645_I2S2_DAC_PIN_SFT			4 +#define RT5645_I2S2_DAC_PIN_I2S			(0x0 << 4) +#define RT5645_I2S2_DAC_PIN_GPIO		(0x1 << 4)  #define RT5645_GP8_PIN_MASK			(0x1 << 3)  #define RT5645_GP8_PIN_SFT			3  #define RT5645_GP8_PIN_GPIO8			(0x0 << 3) diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c index 4c01bb43928d..5bbaa667bec1 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c +++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c @@ -701,6 +701,8 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)  	if (byt == NULL)  		return -ENOMEM; +	byt->dev = dev; +  	ipc = &byt->ipc;  	ipc->dev = dev;  	ipc->ops.tx_msg = byt_tx_msg; diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c index f95f271aab0c..f6efa9d4acad 100644 --- a/sound/soc/intel/haswell/sst-haswell-ipc.c +++ b/sound/soc/intel/haswell/sst-haswell-ipc.c @@ -2119,6 +2119,8 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)  	if (hsw == NULL)  		return -ENOMEM; +	hsw->dev = dev; +  	ipc = &hsw->ipc;  	ipc->dev = dev;  	ipc->ops.tx_msg = hsw_tx_msg; diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 59ac211f8fe7..31068b8f3db0 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -33,6 +33,7 @@  #include <sound/soc.h>  #include <sound/soc-dapm.h>  #include <sound/soc-topology.h> +#include <sound/tlv.h>  /*   * We make several passes over the data (since it wont necessarily be ordered) @@ -534,7 +535,7 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr,  			k->put = bops[i].put;  		if (k->get == NULL && bops[i].id == hdr->ops.get)  			k->get = bops[i].get; -		if (k->info == NULL && ops[i].id == hdr->ops.info) +		if (k->info == NULL && bops[i].id == hdr->ops.info)  			k->info = bops[i].info;  	} @@ -579,28 +580,51 @@ static int soc_tplg_init_kcontrol(struct soc_tplg *tplg,  	return 0;  } + +static int soc_tplg_create_tlv_db_scale(struct soc_tplg *tplg, +	struct snd_kcontrol_new *kc, struct snd_soc_tplg_tlv_dbscale *scale) +{ +	unsigned int item_len = 2 * sizeof(unsigned int); +	unsigned int *p; + +	p = kzalloc(item_len + 2 * sizeof(unsigned int), GFP_KERNEL); +	if (!p) +		return -ENOMEM; + +	p[0] = SNDRV_CTL_TLVT_DB_SCALE; +	p[1] = item_len; +	p[2] = scale->min; +	p[3] = (scale->step & TLV_DB_SCALE_MASK) +			| (scale->mute ? TLV_DB_SCALE_MUTE : 0); + +	kc->tlv.p = (void *)p; +	return 0; +} +  static int soc_tplg_create_tlv(struct soc_tplg *tplg, -	struct snd_kcontrol_new *kc, struct snd_soc_tplg_ctl_tlv *tplg_tlv) +	struct snd_kcontrol_new *kc, struct snd_soc_tplg_ctl_hdr *tc)  { -	struct snd_ctl_tlv *tlv; -	int size; +	struct snd_soc_tplg_ctl_tlv *tplg_tlv; -	if (tplg_tlv->count == 0) +	if (!(tc->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE))  		return 0; -	size = ((tplg_tlv->count + (sizeof(unsigned int) - 1)) & -		~(sizeof(unsigned int) - 1)); -	tlv = kzalloc(sizeof(*tlv) + size, GFP_KERNEL); -	if (tlv == NULL) -		return -ENOMEM; - -	dev_dbg(tplg->dev, " created TLV type %d size %d bytes\n", -		tplg_tlv->numid, size); +	if (tc->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { +		kc->tlv.c = snd_soc_bytes_tlv_callback; +	} else { +		tplg_tlv = &tc->tlv; +		switch (tplg_tlv->type) { +		case SNDRV_CTL_TLVT_DB_SCALE: +			return soc_tplg_create_tlv_db_scale(tplg, kc, +					&tplg_tlv->scale); -	tlv->numid = tplg_tlv->numid; -	tlv->length = size; -	memcpy(&tlv->tlv[0], tplg_tlv->data, size); -	kc->tlv.p = (void *)tlv; +		/* TODO: add support for other TLV types */ +		default: +			dev_dbg(tplg->dev, "Unsupported TLV type %d\n", +					tplg_tlv->type); +			return -EINVAL; +		} +	}  	return 0;  } @@ -772,7 +796,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,  		}  		/* create any TLV data */ -		soc_tplg_create_tlv(tplg, &kc, &mc->tlv); +		soc_tplg_create_tlv(tplg, &kc, &mc->hdr);  		/* register control here */  		err = soc_tplg_add_kcontrol(tplg, &kc, @@ -1350,6 +1374,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,  	template.reg = w->reg;  	template.shift = w->shift;  	template.mask = w->mask; +	template.subseq = w->subseq;  	template.on_val = w->invert ? 0 : 1;  	template.off_val = w->invert ? 1 : 0;  	template.ignore_suspend = w->ignore_suspend;  | 
