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