Unified · Split
| @@ -77,7 +77,7 @@ · 76 unmodified lines | ||
| 77 | 77 | #define SND_SOC_TPLG_NUM_TEXTS 16 |
| 78 | 78 | |
| 79 | 79 | /* ABI version */ |
| 80 | −#define SND_SOC_TPLG_ABI_VERSION 0x2 | |
| 80 | +#define SND_SOC_TPLG_ABI_VERSION 0x3 | |
| 81 | 81 | |
| 82 | 82 | /* Max size of TLV data */ |
| 83 | 83 | #define SND_SOC_TPLG_TLV_SIZE 32 |
| @@ -97,7 +97,8 @@ · 13 unmodified lines | ||
| 97 | 97 | #define SND_SOC_TPLG_TYPE_PCM 7 |
| 98 | 98 | #define SND_SOC_TPLG_TYPE_MANIFEST 8 |
| 99 | 99 | #define SND_SOC_TPLG_TYPE_CODEC_LINK 9 |
| 100 | −#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_CODEC_LINK | |
| 100 | +#define SND_SOC_TPLG_TYPE_PDATA 10 | |
| 101 | +#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_PDATA | |
| 101 | 102 | |
| 102 | 103 | /* vendor block IDs - please add new vendor types to end */ |
| 103 | 104 | #define SND_SOC_TPLG_TYPE_VENDOR_FW 1000 |
| @@ -137,11 +138,19 @@ struct snd_soc_tplg_private { · 33 unmodified lines | ||
| 137 | 138 | /* |
| 138 | 139 | * Kcontrol TLV data. |
| 139 | 140 | */ |
| 141 | +struct snd_soc_tplg_tlv_dbscale { | |
| 142 | + __le32 min; | |
| 143 | + __le32 step; | |
| 144 | + __le32 mute; | |
| 145 | +} __attribute__((packed)); | |
| 146 | + | |
| 140 | 147 | struct snd_soc_tplg_ctl_tlv { |
| 141 | − __le32 size; /* in bytes aligned to 4 */ | |
| 142 | − __le32 numid; /* control element numeric identification */ | |
| 143 | − __le32 count; /* number of elem in data array */ | |
| 144 | − __le32 data[SND_SOC_TPLG_TLV_SIZE]; | |
| 148 | + __le32 size; /* in bytes of this structure */ | |
| 149 | + __le32 type; /* SNDRV_CTL_TLVT_*, type of TLV */ | |
| 150 | + union { | |
| 151 | + __le32 data[SND_SOC_TPLG_TLV_SIZE]; | |
| 152 | + struct snd_soc_tplg_tlv_dbscale scale; | |
| 153 | + }; | |
| 145 | 154 | } __attribute__((packed)); |
| 146 | 155 | |
| 147 | 156 | /* |
| @@ -155,9 +164,11 @@ struct snd_soc_tplg_channel { · 7 unmodified lines | ||
| 155 | 164 | } __attribute__((packed)); |
| 156 | 165 | |
| 157 | 166 | /* |
| 158 | − * Kcontrol Operations IDs | |
| 167 | + * Genericl Operations IDs, for binding Kcontrol or Bytes ext ops | |
| 168 | + * Kcontrol ops need get/put/info. | |
| 169 | + * Bytes ext ops need get/put. | |
| 159 | 170 | */ |
| 160 | −struct snd_soc_tplg_kcontrol_ops_id { | |
| 171 | +struct snd_soc_tplg_io_ops { | |
| 161 | 172 | __le32 get; |
| 162 | 173 | __le32 put; |
| 163 | 174 | __le32 info; |
| @@ -171,8 +182,8 @@ struct snd_soc_tplg_ctl_hdr { · 7 unmodified lines | ||
| 171 | 182 | __le32 type; |
| 172 | 183 | char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; |
| 173 | 184 | __le32 access; |
| 174 | − struct snd_soc_tplg_kcontrol_ops_id ops; | |
| 175 | − __le32 tlv_size; /* non zero means control has TLV data */ | |
| 185 | + struct snd_soc_tplg_io_ops ops; | |
| 186 | + struct snd_soc_tplg_ctl_tlv tlv; | |
| 176 | 187 | } __attribute__((packed)); |
| 177 | 188 | |
| 178 | 189 | /* |
| @@ -238,6 +249,7 @@ struct snd_soc_tplg_manifest { · 59 unmodified lines | ||
| 238 | 249 | __le32 graph_elems; /* number of graph elements */ |
| 239 | 250 | __le32 dai_elems; /* number of DAI elements */ |
| 240 | 251 | __le32 dai_link_elems; /* number of DAI link elements */ |
| 252 | + struct snd_soc_tplg_private priv; | |
| 241 | 253 | } __attribute__((packed)); |
| 242 | 254 | |
| 243 | 255 | /* |
| @@ -259,7 +271,6 @@ struct snd_soc_tplg_mixer_control { · 15 unmodified lines | ||
| 259 | 271 | __le32 invert; |
| 260 | 272 | __le32 num_channels; |
| 261 | 273 | struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN]; |
| 262 | − struct snd_soc_tplg_ctl_tlv tlv; | |
| 263 | 274 | struct snd_soc_tplg_private priv; |
| 264 | 275 | } __attribute__((packed)); |
| 265 | 276 | |
| @@ -303,6 +314,7 @@ struct snd_soc_tplg_bytes_control { · 37 unmodified lines | ||
| 303 | 314 | __le32 mask; |
| 304 | 315 | __le32 base; |
| 305 | 316 | __le32 num_regs; |
| 317 | + struct snd_soc_tplg_io_ops ext_ops; | |
| 306 | 318 | struct snd_soc_tplg_private priv; |
| 307 | 319 | } __attribute__((packed)); |
| 308 | 320 | |
| @@ -347,6 +359,7 @@ struct snd_soc_tplg_dapm_widget { · 38 unmodified lines | ||
| 347 | 359 | __le32 reg; /* negative reg = no direct dapm */ |
| 348 | 360 | __le32 shift; /* bits to shift */ |
| 349 | 361 | __le32 mask; /* non-shifted mask */ |
| 362 | + __le32 subseq; /* sort within widget type */ | |
| 350 | 363 | __u32 invert; /* invert the power bit */ |
| 351 | 364 | __u32 ignore_suspend; /* kept enabled over suspend */ |
| 352 | 365 | __u16 event_flags; |
| @@ -457,14 +457,14 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, · 456 unmodified lines | ||
| 457 | 457 | case SND_SOC_DAIFMT_RIGHT_J: |
| 458 | 458 | if (params_width(params) == 16) { |
| 459 | 459 | snd_soc_update_bits(codec, CS4265_DAC_CTL, |
| 460 | − CS4265_DAC_CTL_DIF, (1 << 5)); | |
| 460 | + CS4265_DAC_CTL_DIF, (2 << 4)); | |
| 461 | 461 | snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, |
| 462 | − CS4265_SPDIF_CTL2_DIF, (1 << 7)); | |
| 462 | + CS4265_SPDIF_CTL2_DIF, (2 << 6)); | |
| 463 | 463 | } else { |
| 464 | 464 | snd_soc_update_bits(codec, CS4265_DAC_CTL, |
| 465 | − CS4265_DAC_CTL_DIF, (3 << 5)); | |
| 465 | + CS4265_DAC_CTL_DIF, (3 << 4)); | |
| 466 | 466 | snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, |
| 467 | − CS4265_SPDIF_CTL2_DIF, (1 << 7)); | |
| 467 | + CS4265_SPDIF_CTL2_DIF, (3 << 6)); | |
| 468 | 468 | } |
| 469 | 469 | break; |
| 470 | 470 | case SND_SOC_DAIFMT_LEFT_J: |
| @@ -473,7 +473,7 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 473 | 473 | snd_soc_update_bits(codec, CS4265_ADC_CTL, |
| 474 | 474 | CS4265_ADC_DIF, 0); |
| 475 | 475 | snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, |
| 476 | − CS4265_SPDIF_CTL2_DIF, (1 << 6)); | |
| 476 | + CS4265_SPDIF_CTL2_DIF, 0); | |
| 477 | 477 | |
| 478 | 478 | break; |
| 479 | 479 | default: |
| @@ -701,6 +701,8 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) · 700 unmodified lines | ||
| 701 | 701 | if (byt == NULL) |
| 702 | 702 | return -ENOMEM; |
| 703 | 703 | |
| 704 | + byt->dev = dev; | |
| 705 | + | |
| 704 | 706 | ipc = &byt->ipc; |
| 705 | 707 | ipc->dev = dev; |
| 706 | 708 | ipc->ops.tx_msg = byt_tx_msg; |
| @@ -2119,6 +2119,8 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) · 2118 unmodified lines | ||
| 2119 | 2119 | if (hsw == NULL) |
| 2120 | 2120 | return -ENOMEM; |
| 2121 | 2121 | |
| 2122 | + hsw->dev = dev; | |
| 2123 | + | |
| 2122 | 2124 | ipc = &hsw->ipc; |
| 2123 | 2125 | ipc->dev = dev; |
| 2124 | 2126 | ipc->ops.tx_msg = hsw_tx_msg; |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #include <sound/soc.h> |
| 34 | 34 | #include <sound/soc-dapm.h> |
| 35 | 35 | #include <sound/soc-topology.h> |
| 36 | +#include <sound/tlv.h> | |
| 36 | 37 | |
| 37 | 38 | /* |
| 38 | 39 | * 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, · 495 unmodified lines | ||
| 534 | 535 | k->put = bops[i].put; |
| 535 | 536 | if (k->get == NULL && bops[i].id == hdr->ops.get) |
| 536 | 537 | k->get = bops[i].get; |
| 537 | − if (k->info == NULL && ops[i].id == hdr->ops.info) | |
| 538 | + if (k->info == NULL && bops[i].id == hdr->ops.info) | |
| 538 | 539 | k->info = bops[i].info; |
| 539 | 540 | } |
| 540 | 541 | |
| @@ -579,28 +580,51 @@ static int soc_tplg_init_kcontrol(struct soc_tplg *tplg, · 38 unmodified lines | ||
| 579 | 580 | return 0; |
| 580 | 581 | } |
| 581 | 582 | |
| 583 | + | |
| 584 | +static int soc_tplg_create_tlv_db_scale(struct soc_tplg *tplg, | |
| 585 | + struct snd_kcontrol_new *kc, struct snd_soc_tplg_tlv_dbscale *scale) | |
| 586 | +{ | |
| 587 | + unsigned int item_len = 2 * sizeof(unsigned int); | |
| 588 | + unsigned int *p; | |
| 589 | + | |
| 590 | + p = kzalloc(item_len + 2 * sizeof(unsigned int), GFP_KERNEL); | |
| 591 | + if (!p) | |
| 592 | + return -ENOMEM; | |
| 593 | + | |
| 594 | + p[0] = SNDRV_CTL_TLVT_DB_SCALE; | |
| 595 | + p[1] = item_len; | |
| 596 | + p[2] = scale->min; | |
| 597 | + p[3] = (scale->step & TLV_DB_SCALE_MASK) | |
| 598 | + | (scale->mute ? TLV_DB_SCALE_MUTE : 0); | |
| 599 | + | |
| 600 | + kc->tlv.p = (void *)p; | |
| 601 | + return 0; | |
| 602 | +} | |
| 603 | + | |
| 582 | 604 | static int soc_tplg_create_tlv(struct soc_tplg *tplg, |
| 583 | − struct snd_kcontrol_new *kc, struct snd_soc_tplg_ctl_tlv *tplg_tlv) | |
| 605 | + struct snd_kcontrol_new *kc, struct snd_soc_tplg_ctl_hdr *tc) | |
| 584 | 606 | { |
| 585 | − struct snd_ctl_tlv *tlv; | |
| 586 | − int size; | |
| 607 | + struct snd_soc_tplg_ctl_tlv *tplg_tlv; | |
| 587 | 608 | |
| 588 | − if (tplg_tlv->count == 0) | |
| 609 | + if (!(tc->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)) | |
| 589 | 610 | return 0; |
| 590 | 611 | |
| 591 | − size = ((tplg_tlv->count + (sizeof(unsigned int) - 1)) & | |
| 592 | − ~(sizeof(unsigned int) - 1)); | |
| 593 | − tlv = kzalloc(sizeof(*tlv) + size, GFP_KERNEL); | |
| 594 | − if (tlv == NULL) | |
| 595 | − return -ENOMEM; | |
| 596 | − | |
| 597 | − dev_dbg(tplg->dev, " created TLV type %d size %d bytes\n", | |
| 598 | − tplg_tlv->numid, size); | |
| 612 | + if (tc->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { | |
| 613 | + kc->tlv.c = snd_soc_bytes_tlv_callback; | |
| 614 | + } else { | |
| 615 | + tplg_tlv = &tc->tlv; | |
| 616 | + switch (tplg_tlv->type) { | |
| 617 | + case SNDRV_CTL_TLVT_DB_SCALE: | |
| 618 | + return soc_tplg_create_tlv_db_scale(tplg, kc, | |
| 619 | + &tplg_tlv->scale); | |
| 599 | 620 | |
| 600 | − tlv->numid = tplg_tlv->numid; | |
| 601 | − tlv->length = size; | |
| 602 | − memcpy(&tlv->tlv[0], tplg_tlv->data, size); | |
| 603 | − kc->tlv.p = (void *)tlv; | |
| 621 | + /* TODO: add support for other TLV types */ | |
| 622 | + default: | |
| 623 | + dev_dbg(tplg->dev, "Unsupported TLV type %d\n", | |
| 624 | + tplg_tlv->type); | |
| 625 | + return -EINVAL; | |
| 626 | + } | |
| 627 | + } | |
| 604 | 628 | |
| 605 | 629 | return 0; |
| 606 | 630 | } |
| @@ -772,7 +796,7 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count, · 165 unmodified lines | ||
| 772 | 796 | } |
| 773 | 797 | |
| 774 | 798 | /* create any TLV data */ |
| 775 | − soc_tplg_create_tlv(tplg, &kc, &mc->tlv); | |
| 799 | + soc_tplg_create_tlv(tplg, &kc, &mc->hdr); | |
| 776 | 800 | |
| 777 | 801 | /* register control here */ |
| 778 | 802 | err = soc_tplg_add_kcontrol(tplg, &kc, |
| @@ -1350,6 +1374,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, · 571 unmodified lines | ||
| 1350 | 1374 | template.reg = w->reg; |
| 1351 | 1375 | template.shift = w->shift; |
| 1352 | 1376 | template.mask = w->mask; |
| 1377 | + template.subseq = w->subseq; | |
| 1353 | 1378 | template.on_val = w->invert ? 0 : 1; |
| 1354 | 1379 | template.off_val = w->invert ? 1 : 0; |
| 1355 | 1380 | template.ignore_suspend = w->ignore_suspend; |