diff options
| -rw-r--r-- | drivers/extcon/extcon-arizona.c | 107 | ||||
| -rw-r--r-- | drivers/mfd/wm5102-tables.c | 10 | ||||
| -rw-r--r-- | include/linux/mfd/arizona/core.h | 3 | ||||
| -rw-r--r-- | include/linux/mfd/arizona/registers.h | 42 | ||||
| -rw-r--r-- | sound/soc/codecs/arizona.c | 530 | ||||
| -rw-r--r-- | sound/soc/codecs/arizona.h | 34 | ||||
| -rw-r--r-- | sound/soc/codecs/wm2200.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm5102.c | 129 | ||||
| -rw-r--r-- | sound/soc/codecs/wm5102.h | 6 | ||||
| -rw-r--r-- | sound/soc/codecs/wm5110.c | 54 | ||||
| -rw-r--r-- | sound/soc/codecs/wm5110.h | 6 | ||||
| -rw-r--r-- | sound/soc/codecs/wm_adsp.c | 40 | ||||
| -rw-r--r-- | sound/soc/codecs/wm_adsp.h | 3 |
13 files changed, 738 insertions, 228 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index dc357a4051f6..b28927972128 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
| @@ -100,6 +100,55 @@ static const char *arizona_cable[] = { | |||
| 100 | NULL, | 100 | NULL, |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
| 103 | static void arizona_extcon_do_magic(struct arizona_extcon_info *info, | ||
| 104 | unsigned int magic) | ||
| 105 | { | ||
| 106 | struct arizona *arizona = info->arizona; | ||
| 107 | int ret; | ||
| 108 | |||
| 109 | mutex_lock(&arizona->dapm->card->dapm_mutex); | ||
| 110 | |||
| 111 | arizona->hpdet_magic = magic; | ||
| 112 | |||
| 113 | /* Keep the HP output stages disabled while doing the magic */ | ||
| 114 | if (magic) { | ||
| 115 | ret = regmap_update_bits(arizona->regmap, | ||
| 116 | ARIZONA_OUTPUT_ENABLES_1, | ||
| 117 | ARIZONA_OUT1L_ENA | | ||
| 118 | ARIZONA_OUT1R_ENA, 0); | ||
| 119 | if (ret != 0) | ||
| 120 | dev_warn(arizona->dev, | ||
| 121 | "Failed to disable headphone outputs: %d\n", | ||
| 122 | ret); | ||
| 123 | } | ||
| 124 | |||
| 125 | ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, | ||
| 126 | magic); | ||
| 127 | if (ret != 0) | ||
| 128 | dev_warn(arizona->dev, "Failed to do magic: %d\n", | ||
| 129 | ret); | ||
| 130 | |||
| 131 | ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, | ||
| 132 | magic); | ||
| 133 | if (ret != 0) | ||
| 134 | dev_warn(arizona->dev, "Failed to do magic: %d\n", | ||
| 135 | ret); | ||
| 136 | |||
| 137 | /* Restore the desired state while not doing the magic */ | ||
| 138 | if (!magic) { | ||
| 139 | ret = regmap_update_bits(arizona->regmap, | ||
| 140 | ARIZONA_OUTPUT_ENABLES_1, | ||
| 141 | ARIZONA_OUT1L_ENA | | ||
| 142 | ARIZONA_OUT1R_ENA, arizona->hp_ena); | ||
| 143 | if (ret != 0) | ||
| 144 | dev_warn(arizona->dev, | ||
| 145 | "Failed to restore headphone outputs: %d\n", | ||
| 146 | ret); | ||
| 147 | } | ||
| 148 | |||
| 149 | mutex_unlock(&arizona->dapm->card->dapm_mutex); | ||
| 150 | } | ||
| 151 | |||
| 103 | static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) | 152 | static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode) |
| 104 | { | 153 | { |
| 105 | struct arizona *arizona = info->arizona; | 154 | struct arizona *arizona = info->arizona; |
| @@ -484,7 +533,6 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) | |||
| 484 | struct arizona *arizona = info->arizona; | 533 | struct arizona *arizona = info->arizona; |
| 485 | int id_gpio = arizona->pdata.hpdet_id_gpio; | 534 | int id_gpio = arizona->pdata.hpdet_id_gpio; |
| 486 | int report = ARIZONA_CABLE_HEADPHONE; | 535 | int report = ARIZONA_CABLE_HEADPHONE; |
| 487 | unsigned int val; | ||
| 488 | int ret, reading; | 536 | int ret, reading; |
| 489 | 537 | ||
| 490 | mutex_lock(&info->lock); | 538 | mutex_lock(&info->lock); |
| @@ -539,28 +587,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) | |||
| 539 | dev_err(arizona->dev, "Failed to report HP/line: %d\n", | 587 | dev_err(arizona->dev, "Failed to report HP/line: %d\n", |
| 540 | ret); | 588 | ret); |
| 541 | 589 | ||
| 542 | mutex_lock(&arizona->dapm->card->dapm_mutex); | 590 | arizona_extcon_do_magic(info, 0); |
| 543 | |||
| 544 | ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); | ||
| 545 | if (ret != 0) { | ||
| 546 | dev_err(arizona->dev, "Failed to read output enables: %d\n", | ||
| 547 | ret); | ||
| 548 | val = 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { | ||
| 552 | ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); | ||
| 553 | if (ret != 0) | ||
| 554 | dev_warn(arizona->dev, "Failed to undo magic: %d\n", | ||
| 555 | ret); | ||
| 556 | |||
| 557 | ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); | ||
| 558 | if (ret != 0) | ||
| 559 | dev_warn(arizona->dev, "Failed to undo magic: %d\n", | ||
| 560 | ret); | ||
| 561 | } | ||
| 562 | |||
| 563 | mutex_unlock(&arizona->dapm->card->dapm_mutex); | ||
| 564 | 591 | ||
| 565 | done: | 592 | done: |
| 566 | if (id_gpio) | 593 | if (id_gpio) |
| @@ -606,13 +633,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info) | |||
| 606 | if (info->mic) | 633 | if (info->mic) |
| 607 | arizona_stop_mic(info); | 634 | arizona_stop_mic(info); |
| 608 | 635 | ||
| 609 | ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); | 636 | arizona_extcon_do_magic(info, 0x4000); |
| 610 | if (ret != 0) | ||
| 611 | dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); | ||
| 612 | |||
| 613 | ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000); | ||
| 614 | if (ret != 0) | ||
| 615 | dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); | ||
| 616 | 637 | ||
| 617 | ret = regmap_update_bits(arizona->regmap, | 638 | ret = regmap_update_bits(arizona->regmap, |
| 618 | ARIZONA_ACCESSORY_DETECT_MODE_1, | 639 | ARIZONA_ACCESSORY_DETECT_MODE_1, |
| @@ -653,7 +674,6 @@ err: | |||
| 653 | static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) | 674 | static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) |
| 654 | { | 675 | { |
| 655 | struct arizona *arizona = info->arizona; | 676 | struct arizona *arizona = info->arizona; |
| 656 | unsigned int val; | ||
| 657 | int ret; | 677 | int ret; |
| 658 | 678 | ||
| 659 | dev_dbg(arizona->dev, "Starting identification via HPDET\n"); | 679 | dev_dbg(arizona->dev, "Starting identification via HPDET\n"); |
| @@ -665,30 +685,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) | |||
| 665 | 685 | ||
| 666 | arizona_extcon_pulse_micbias(info); | 686 | arizona_extcon_pulse_micbias(info); |
| 667 | 687 | ||
| 668 | mutex_lock(&arizona->dapm->card->dapm_mutex); | 688 | arizona_extcon_do_magic(info, 0x4000); |
| 669 | |||
| 670 | ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); | ||
| 671 | if (ret != 0) { | ||
| 672 | dev_err(arizona->dev, "Failed to read output enables: %d\n", | ||
| 673 | ret); | ||
| 674 | val = 0; | ||
| 675 | } | ||
| 676 | |||
| 677 | if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { | ||
| 678 | ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, | ||
| 679 | 0x4000); | ||
| 680 | if (ret != 0) | ||
| 681 | dev_warn(arizona->dev, "Failed to do magic: %d\n", | ||
| 682 | ret); | ||
| 683 | |||
| 684 | ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, | ||
| 685 | 0x4000); | ||
| 686 | if (ret != 0) | ||
| 687 | dev_warn(arizona->dev, "Failed to do magic: %d\n", | ||
| 688 | ret); | ||
| 689 | } | ||
| 690 | |||
| 691 | mutex_unlock(&arizona->dapm->card->dapm_mutex); | ||
| 692 | 689 | ||
| 693 | ret = regmap_update_bits(arizona->regmap, | 690 | ret = regmap_update_bits(arizona->regmap, |
| 694 | ARIZONA_ACCESSORY_DETECT_MODE_1, | 691 | ARIZONA_ACCESSORY_DETECT_MODE_1, |
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index a433f580aa4c..7d01069c09db 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
| @@ -290,12 +290,14 @@ static const struct reg_default wm5102_reg_default[] = { | |||
| 290 | { 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */ | 290 | { 0x00000176, 0x0000 }, /* R374 - FLL1 Control 6 */ |
| 291 | { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */ | 291 | { 0x00000177, 0x0181 }, /* R375 - FLL1 Loop Filter Test 1 */ |
| 292 | { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */ | 292 | { 0x00000178, 0x0000 }, /* R376 - FLL1 NCO Test 0 */ |
| 293 | { 0x00000179, 0x0000 }, /* R377 - FLL1 Control 7 */ | ||
| 293 | { 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */ | 294 | { 0x00000181, 0x0000 }, /* R385 - FLL1 Synchroniser 1 */ |
| 294 | { 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */ | 295 | { 0x00000182, 0x0000 }, /* R386 - FLL1 Synchroniser 2 */ |
| 295 | { 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */ | 296 | { 0x00000183, 0x0000 }, /* R387 - FLL1 Synchroniser 3 */ |
| 296 | { 0x00000184, 0x0000 }, /* R388 - FLL1 Synchroniser 4 */ | 297 | { 0x00000184, 0x0000 }, /* R388 - FLL1 Synchroniser 4 */ |
| 297 | { 0x00000185, 0x0000 }, /* R389 - FLL1 Synchroniser 5 */ | 298 | { 0x00000185, 0x0000 }, /* R389 - FLL1 Synchroniser 5 */ |
| 298 | { 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */ | 299 | { 0x00000186, 0x0000 }, /* R390 - FLL1 Synchroniser 6 */ |
| 300 | { 0x00000187, 0x0001 }, /* R391 - FLL1 Synchroniser 7 */ | ||
| 299 | { 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */ | 301 | { 0x00000189, 0x0000 }, /* R393 - FLL1 Spread Spectrum */ |
| 300 | { 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */ | 302 | { 0x0000018A, 0x0004 }, /* R394 - FLL1 GPIO Clock */ |
| 301 | { 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */ | 303 | { 0x00000191, 0x0000 }, /* R401 - FLL2 Control 1 */ |
| @@ -306,12 +308,14 @@ static const struct reg_default wm5102_reg_default[] = { | |||
| 306 | { 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */ | 308 | { 0x00000196, 0x0000 }, /* R406 - FLL2 Control 6 */ |
| 307 | { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */ | 309 | { 0x00000197, 0x0000 }, /* R407 - FLL2 Loop Filter Test 1 */ |
| 308 | { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */ | 310 | { 0x00000198, 0x0000 }, /* R408 - FLL2 NCO Test 0 */ |
| 311 | { 0x00000199, 0x0000 }, /* R409 - FLL2 Control 7 */ | ||
| 309 | { 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */ | 312 | { 0x000001A1, 0x0000 }, /* R417 - FLL2 Synchroniser 1 */ |
| 310 | { 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */ | 313 | { 0x000001A2, 0x0000 }, /* R418 - FLL2 Synchroniser 2 */ |
| 311 | { 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */ | 314 | { 0x000001A3, 0x0000 }, /* R419 - FLL2 Synchroniser 3 */ |
| 312 | { 0x000001A4, 0x0000 }, /* R420 - FLL2 Synchroniser 4 */ | 315 | { 0x000001A4, 0x0000 }, /* R420 - FLL2 Synchroniser 4 */ |
| 313 | { 0x000001A5, 0x0000 }, /* R421 - FLL2 Synchroniser 5 */ | 316 | { 0x000001A5, 0x0000 }, /* R421 - FLL2 Synchroniser 5 */ |
| 314 | { 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */ | 317 | { 0x000001A6, 0x0000 }, /* R422 - FLL2 Synchroniser 6 */ |
| 318 | { 0x000001A7, 0x0001 }, /* R423 - FLL2 Synchroniser 7 */ | ||
| 315 | { 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */ | 319 | { 0x000001A9, 0x0000 }, /* R425 - FLL2 Spread Spectrum */ |
| 316 | { 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */ | 320 | { 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */ |
| 317 | { 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */ | 321 | { 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */ |
| @@ -1051,12 +1055,14 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
| 1051 | case ARIZONA_FLL1_CONTROL_6: | 1055 | case ARIZONA_FLL1_CONTROL_6: |
| 1052 | case ARIZONA_FLL1_LOOP_FILTER_TEST_1: | 1056 | case ARIZONA_FLL1_LOOP_FILTER_TEST_1: |
| 1053 | case ARIZONA_FLL1_NCO_TEST_0: | 1057 | case ARIZONA_FLL1_NCO_TEST_0: |
| 1058 | case ARIZONA_FLL1_CONTROL_7: | ||
| 1054 | case ARIZONA_FLL1_SYNCHRONISER_1: | 1059 | case ARIZONA_FLL1_SYNCHRONISER_1: |
| 1055 | case ARIZONA_FLL1_SYNCHRONISER_2: | 1060 | case ARIZONA_FLL1_SYNCHRONISER_2: |
| 1056 | case ARIZONA_FLL1_SYNCHRONISER_3: | 1061 | case ARIZONA_FLL1_SYNCHRONISER_3: |
| 1057 | case ARIZONA_FLL1_SYNCHRONISER_4: | 1062 | case ARIZONA_FLL1_SYNCHRONISER_4: |
| 1058 | case ARIZONA_FLL1_SYNCHRONISER_5: | 1063 | case ARIZONA_FLL1_SYNCHRONISER_5: |
| 1059 | case ARIZONA_FLL1_SYNCHRONISER_6: | 1064 | case ARIZONA_FLL1_SYNCHRONISER_6: |
| 1065 | case ARIZONA_FLL1_SYNCHRONISER_7: | ||
| 1060 | case ARIZONA_FLL1_SPREAD_SPECTRUM: | 1066 | case ARIZONA_FLL1_SPREAD_SPECTRUM: |
| 1061 | case ARIZONA_FLL1_GPIO_CLOCK: | 1067 | case ARIZONA_FLL1_GPIO_CLOCK: |
| 1062 | case ARIZONA_FLL2_CONTROL_1: | 1068 | case ARIZONA_FLL2_CONTROL_1: |
| @@ -1067,12 +1073,14 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
| 1067 | case ARIZONA_FLL2_CONTROL_6: | 1073 | case ARIZONA_FLL2_CONTROL_6: |
| 1068 | case ARIZONA_FLL2_LOOP_FILTER_TEST_1: | 1074 | case ARIZONA_FLL2_LOOP_FILTER_TEST_1: |
| 1069 | case ARIZONA_FLL2_NCO_TEST_0: | 1075 | case ARIZONA_FLL2_NCO_TEST_0: |
| 1076 | case ARIZONA_FLL2_CONTROL_7: | ||
| 1070 | case ARIZONA_FLL2_SYNCHRONISER_1: | 1077 | case ARIZONA_FLL2_SYNCHRONISER_1: |
| 1071 | case ARIZONA_FLL2_SYNCHRONISER_2: | 1078 | case ARIZONA_FLL2_SYNCHRONISER_2: |
| 1072 | case ARIZONA_FLL2_SYNCHRONISER_3: | 1079 | case ARIZONA_FLL2_SYNCHRONISER_3: |
| 1073 | case ARIZONA_FLL2_SYNCHRONISER_4: | 1080 | case ARIZONA_FLL2_SYNCHRONISER_4: |
| 1074 | case ARIZONA_FLL2_SYNCHRONISER_5: | 1081 | case ARIZONA_FLL2_SYNCHRONISER_5: |
| 1075 | case ARIZONA_FLL2_SYNCHRONISER_6: | 1082 | case ARIZONA_FLL2_SYNCHRONISER_6: |
| 1083 | case ARIZONA_FLL2_SYNCHRONISER_7: | ||
| 1076 | case ARIZONA_FLL2_SPREAD_SPECTRUM: | 1084 | case ARIZONA_FLL2_SPREAD_SPECTRUM: |
| 1077 | case ARIZONA_FLL2_GPIO_CLOCK: | 1085 | case ARIZONA_FLL2_GPIO_CLOCK: |
| 1078 | case ARIZONA_MIC_CHARGE_PUMP_1: | 1086 | case ARIZONA_MIC_CHARGE_PUMP_1: |
| @@ -1161,6 +1169,8 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
| 1161 | case ARIZONA_NOISE_GATE_CONTROL: | 1169 | case ARIZONA_NOISE_GATE_CONTROL: |
| 1162 | case ARIZONA_PDM_SPK1_CTRL_1: | 1170 | case ARIZONA_PDM_SPK1_CTRL_1: |
| 1163 | case ARIZONA_PDM_SPK1_CTRL_2: | 1171 | case ARIZONA_PDM_SPK1_CTRL_2: |
| 1172 | case ARIZONA_SPK_CTRL_2: | ||
| 1173 | case ARIZONA_SPK_CTRL_3: | ||
| 1164 | case ARIZONA_DAC_COMP_1: | 1174 | case ARIZONA_DAC_COMP_1: |
| 1165 | case ARIZONA_DAC_COMP_2: | 1175 | case ARIZONA_DAC_COMP_2: |
| 1166 | case ARIZONA_DAC_COMP_3: | 1176 | case ARIZONA_DAC_COMP_3: |
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index a710255528d7..cc281368dc55 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h | |||
| @@ -100,6 +100,9 @@ struct arizona { | |||
| 100 | struct regmap_irq_chip_data *aod_irq_chip; | 100 | struct regmap_irq_chip_data *aod_irq_chip; |
| 101 | struct regmap_irq_chip_data *irq_chip; | 101 | struct regmap_irq_chip_data *irq_chip; |
| 102 | 102 | ||
| 103 | bool hpdet_magic; | ||
| 104 | unsigned int hp_ena; | ||
| 105 | |||
| 103 | struct mutex clk_lock; | 106 | struct mutex clk_lock; |
| 104 | int clk32k_ref; | 107 | int clk32k_ref; |
| 105 | 108 | ||
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index 340355136069..a47fd358016f 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h | |||
| @@ -85,12 +85,14 @@ | |||
| 85 | #define ARIZONA_FLL1_CONTROL_6 0x176 | 85 | #define ARIZONA_FLL1_CONTROL_6 0x176 |
| 86 | #define ARIZONA_FLL1_LOOP_FILTER_TEST_1 0x177 | 86 | #define ARIZONA_FLL1_LOOP_FILTER_TEST_1 0x177 |
| 87 | #define ARIZONA_FLL1_NCO_TEST_0 0x178 | 87 | #define ARIZONA_FLL1_NCO_TEST_0 0x178 |
| 88 | #define ARIZONA_FLL1_CONTROL_7 0x179 | ||
| 88 | #define ARIZONA_FLL1_SYNCHRONISER_1 0x181 | 89 | #define ARIZONA_FLL1_SYNCHRONISER_1 0x181 |
| 89 | #define ARIZONA_FLL1_SYNCHRONISER_2 0x182 | 90 | #define ARIZONA_FLL1_SYNCHRONISER_2 0x182 |
| 90 | #define ARIZONA_FLL1_SYNCHRONISER_3 0x183 | 91 | #define ARIZONA_FLL1_SYNCHRONISER_3 0x183 |
| 91 | #define ARIZONA_FLL1_SYNCHRONISER_4 0x184 | 92 | #define ARIZONA_FLL1_SYNCHRONISER_4 0x184 |
| 92 | #define ARIZONA_FLL1_SYNCHRONISER_5 0x185 | 93 | #define ARIZONA_FLL1_SYNCHRONISER_5 0x185 |
| 93 | #define ARIZONA_FLL1_SYNCHRONISER_6 0x186 | 94 | #define ARIZONA_FLL1_SYNCHRONISER_6 0x186 |
| 95 | #define ARIZONA_FLL1_SYNCHRONISER_7 0x187 | ||
| 94 | #define ARIZONA_FLL1_SPREAD_SPECTRUM 0x189 | 96 | #define ARIZONA_FLL1_SPREAD_SPECTRUM 0x189 |
| 95 | #define ARIZONA_FLL1_GPIO_CLOCK 0x18A | 97 | #define ARIZONA_FLL1_GPIO_CLOCK 0x18A |
| 96 | #define ARIZONA_FLL2_CONTROL_1 0x191 | 98 | #define ARIZONA_FLL2_CONTROL_1 0x191 |
| @@ -101,12 +103,14 @@ | |||
| 101 | #define ARIZONA_FLL2_CONTROL_6 0x196 | 103 | #define ARIZONA_FLL2_CONTROL_6 0x196 |
| 102 | #define ARIZONA_FLL2_LOOP_FILTER_TEST_1 0x197 | 104 | #define ARIZONA_FLL2_LOOP_FILTER_TEST_1 0x197 |
| 103 | #define ARIZONA_FLL2_NCO_TEST_0 0x198 | 105 | #define ARIZONA_FLL2_NCO_TEST_0 0x198 |
| 106 | #define ARIZONA_FLL2_CONTROL_7 0x199 | ||
| 104 | #define ARIZONA_FLL2_SYNCHRONISER_1 0x1A1 | 107 | #define ARIZONA_FLL2_SYNCHRONISER_1 0x1A1 |
| 105 | #define ARIZONA_FLL2_SYNCHRONISER_2 0x1A2 | 108 | #define ARIZONA_FLL2_SYNCHRONISER_2 0x1A2 |
| 106 | #define ARIZONA_FLL2_SYNCHRONISER_3 0x1A3 | 109 | #define ARIZONA_FLL2_SYNCHRONISER_3 0x1A3 |
| 107 | #define ARIZONA_FLL2_SYNCHRONISER_4 0x1A4 | 110 | #define ARIZONA_FLL2_SYNCHRONISER_4 0x1A4 |
| 108 | #define ARIZONA_FLL2_SYNCHRONISER_5 0x1A5 | 111 | #define ARIZONA_FLL2_SYNCHRONISER_5 0x1A5 |
| 109 | #define ARIZONA_FLL2_SYNCHRONISER_6 0x1A6 | 112 | #define ARIZONA_FLL2_SYNCHRONISER_6 0x1A6 |
| 113 | #define ARIZONA_FLL2_SYNCHRONISER_7 0x1A7 | ||
| 110 | #define ARIZONA_FLL2_SPREAD_SPECTRUM 0x1A9 | 114 | #define ARIZONA_FLL2_SPREAD_SPECTRUM 0x1A9 |
| 111 | #define ARIZONA_FLL2_GPIO_CLOCK 0x1AA | 115 | #define ARIZONA_FLL2_GPIO_CLOCK 0x1AA |
| 112 | #define ARIZONA_MIC_CHARGE_PUMP_1 0x200 | 116 | #define ARIZONA_MIC_CHARGE_PUMP_1 0x200 |
| @@ -213,6 +217,8 @@ | |||
| 213 | #define ARIZONA_PDM_SPK1_CTRL_2 0x491 | 217 | #define ARIZONA_PDM_SPK1_CTRL_2 0x491 |
| 214 | #define ARIZONA_PDM_SPK2_CTRL_1 0x492 | 218 | #define ARIZONA_PDM_SPK2_CTRL_1 0x492 |
| 215 | #define ARIZONA_PDM_SPK2_CTRL_2 0x493 | 219 | #define ARIZONA_PDM_SPK2_CTRL_2 0x493 |
| 220 | #define ARIZONA_SPK_CTRL_2 0x4B5 | ||
| 221 | #define ARIZONA_SPK_CTRL_3 0x4B6 | ||
| 216 | #define ARIZONA_DAC_COMP_1 0x4DC | 222 | #define ARIZONA_DAC_COMP_1 0x4DC |
| 217 | #define ARIZONA_DAC_COMP_2 0x4DD | 223 | #define ARIZONA_DAC_COMP_2 0x4DD |
| 218 | #define ARIZONA_DAC_COMP_3 0x4DE | 224 | #define ARIZONA_DAC_COMP_3 0x4DE |
| @@ -1678,6 +1684,13 @@ | |||
| 1678 | #define ARIZONA_FLL1_FRC_INTEG_VAL_WIDTH 12 /* FLL1_FRC_INTEG_VAL - [11:0] */ | 1684 | #define ARIZONA_FLL1_FRC_INTEG_VAL_WIDTH 12 /* FLL1_FRC_INTEG_VAL - [11:0] */ |
| 1679 | 1685 | ||
| 1680 | /* | 1686 | /* |
| 1687 | * R377 (0x179) - FLL1 Control 7 | ||
| 1688 | */ | ||
| 1689 | #define ARIZONA_FLL1_GAIN_MASK 0x003c /* FLL1_GAIN */ | ||
| 1690 | #define ARIZONA_FLL1_GAIN_SHIFT 2 /* FLL1_GAIN */ | ||
| 1691 | #define ARIZONA_FLL1_GAIN_WIDTH 4 /* FLL1_GAIN */ | ||
| 1692 | |||
| 1693 | /* | ||
| 1681 | * R385 (0x181) - FLL1 Synchroniser 1 | 1694 | * R385 (0x181) - FLL1 Synchroniser 1 |
| 1682 | */ | 1695 | */ |
| 1683 | #define ARIZONA_FLL1_SYNC_ENA 0x0001 /* FLL1_SYNC_ENA */ | 1696 | #define ARIZONA_FLL1_SYNC_ENA 0x0001 /* FLL1_SYNC_ENA */ |
| @@ -1724,6 +1737,17 @@ | |||
| 1724 | #define ARIZONA_FLL1_CLK_SYNC_SRC_WIDTH 4 /* FLL1_CLK_SYNC_SRC - [3:0] */ | 1737 | #define ARIZONA_FLL1_CLK_SYNC_SRC_WIDTH 4 /* FLL1_CLK_SYNC_SRC - [3:0] */ |
| 1725 | 1738 | ||
| 1726 | /* | 1739 | /* |
| 1740 | * R391 (0x187) - FLL1 Synchroniser 7 | ||
| 1741 | */ | ||
| 1742 | #define ARIZONA_FLL1_SYNC_GAIN_MASK 0x003c /* FLL1_SYNC_GAIN */ | ||
| 1743 | #define ARIZONA_FLL1_SYNC_GAIN_SHIFT 2 /* FLL1_SYNC_GAIN */ | ||
| 1744 | #define ARIZONA_FLL1_SYNC_GAIN_WIDTH 4 /* FLL1_SYNC_GAIN */ | ||
| 1745 | #define ARIZONA_FLL1_SYNC_BW 0x0001 /* FLL1_SYNC_BW */ | ||
| 1746 | #define ARIZONA_FLL1_SYNC_BW_MASK 0x0001 /* FLL1_SYNC_BW */ | ||
| 1747 | #define ARIZONA_FLL1_SYNC_BW_SHIFT 0 /* FLL1_SYNC_BW */ | ||
| 1748 | #define ARIZONA_FLL1_SYNC_BW_WIDTH 1 /* FLL1_SYNC_BW */ | ||
| 1749 | |||
| 1750 | /* | ||
| 1727 | * R393 (0x189) - FLL1 Spread Spectrum | 1751 | * R393 (0x189) - FLL1 Spread Spectrum |
| 1728 | */ | 1752 | */ |
| 1729 | #define ARIZONA_FLL1_SS_AMPL_MASK 0x0030 /* FLL1_SS_AMPL - [5:4] */ | 1753 | #define ARIZONA_FLL1_SS_AMPL_MASK 0x0030 /* FLL1_SS_AMPL - [5:4] */ |
| @@ -1816,6 +1840,13 @@ | |||
| 1816 | #define ARIZONA_FLL2_FRC_INTEG_VAL_WIDTH 12 /* FLL2_FRC_INTEG_VAL - [11:0] */ | 1840 | #define ARIZONA_FLL2_FRC_INTEG_VAL_WIDTH 12 /* FLL2_FRC_INTEG_VAL - [11:0] */ |
| 1817 | 1841 | ||
| 1818 | /* | 1842 | /* |
| 1843 | * R409 (0x199) - FLL2 Control 7 | ||
| 1844 | */ | ||
| 1845 | #define ARIZONA_FLL2_GAIN_MASK 0x003c /* FLL2_GAIN */ | ||
| 1846 | #define ARIZONA_FLL2_GAIN_SHIFT 2 /* FLL2_GAIN */ | ||
| 1847 | #define ARIZONA_FLL2_GAIN_WIDTH 4 /* FLL2_GAIN */ | ||
| 1848 | |||
| 1849 | /* | ||
| 1819 | * R417 (0x1A1) - FLL2 Synchroniser 1 | 1850 | * R417 (0x1A1) - FLL2 Synchroniser 1 |
| 1820 | */ | 1851 | */ |
| 1821 | #define ARIZONA_FLL2_SYNC_ENA 0x0001 /* FLL2_SYNC_ENA */ | 1852 | #define ARIZONA_FLL2_SYNC_ENA 0x0001 /* FLL2_SYNC_ENA */ |
| @@ -1862,6 +1893,17 @@ | |||
| 1862 | #define ARIZONA_FLL2_CLK_SYNC_SRC_WIDTH 4 /* FLL2_CLK_SYNC_SRC - [3:0] */ | 1893 | #define ARIZONA_FLL2_CLK_SYNC_SRC_WIDTH 4 /* FLL2_CLK_SYNC_SRC - [3:0] */ |
| 1863 | 1894 | ||
| 1864 | /* | 1895 | /* |
| 1896 | * R423 (0x1A7) - FLL2 Synchroniser 7 | ||
| 1897 | */ | ||
| 1898 | #define ARIZONA_FLL2_SYNC_GAIN_MASK 0x003c /* FLL2_SYNC_GAIN */ | ||
| 1899 | #define ARIZONA_FLL2_SYNC_GAIN_SHIFT 2 /* FLL2_SYNC_GAIN */ | ||
| 1900 | #define ARIZONA_FLL2_SYNC_GAIN_WIDTH 4 /* FLL2_SYNC_GAIN */ | ||
| 1901 | #define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */ | ||
| 1902 | #define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */ | ||
| 1903 | #define ARIZONA_FLL2_SYNC_BW_SHIFT 0 /* FLL2_SYNC_BW */ | ||
| 1904 | #define ARIZONA_FLL2_SYNC_BW_WIDTH 1 /* FLL2_SYNC_BW */ | ||
| 1905 | |||
| 1906 | /* | ||
| 1865 | * R425 (0x1A9) - FLL2 Spread Spectrum | 1907 | * R425 (0x1A9) - FLL2 Spread Spectrum |
| 1866 | */ | 1908 | */ |
| 1867 | #define ARIZONA_FLL2_SS_AMPL_MASK 0x0030 /* FLL2_SS_AMPL - [5:4] */ | 1909 | #define ARIZONA_FLL2_SS_AMPL_MASK 0x0030 /* FLL2_SS_AMPL - [5:4] */ |
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index ac948a671ea6..389f23253831 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/delay.h> | ||
| 13 | #include <linux/gcd.h> | 14 | #include <linux/gcd.h> |
| 14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 15 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
| @@ -65,6 +66,163 @@ | |||
| 65 | #define arizona_aif_dbg(_dai, fmt, ...) \ | 66 | #define arizona_aif_dbg(_dai, fmt, ...) \ |
| 66 | dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) | 67 | dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) |
| 67 | 68 | ||
| 69 | static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | ||
| 70 | struct snd_kcontrol *kcontrol, | ||
| 71 | int event) | ||
| 72 | { | ||
| 73 | struct snd_soc_codec *codec = w->codec; | ||
| 74 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | ||
| 75 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
| 76 | bool manual_ena = false; | ||
| 77 | int val; | ||
| 78 | |||
| 79 | switch (arizona->type) { | ||
| 80 | case WM5102: | ||
| 81 | switch (arizona->rev) { | ||
| 82 | case 0: | ||
| 83 | break; | ||
| 84 | default: | ||
| 85 | manual_ena = true; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | default: | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | |||
| 92 | switch (event) { | ||
| 93 | case SND_SOC_DAPM_PRE_PMU: | ||
| 94 | if (!priv->spk_ena && manual_ena) { | ||
| 95 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
| 96 | priv->spk_ena_pending = true; | ||
| 97 | } | ||
| 98 | break; | ||
| 99 | case SND_SOC_DAPM_POST_PMU: | ||
| 100 | val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3); | ||
| 101 | if (val & ARIZONA_SPK_SHUTDOWN_STS) { | ||
| 102 | dev_crit(arizona->dev, | ||
| 103 | "Speaker not enabled due to temperature\n"); | ||
| 104 | return -EBUSY; | ||
| 105 | } | ||
| 106 | |||
| 107 | snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, | ||
| 108 | 1 << w->shift, 1 << w->shift); | ||
| 109 | |||
| 110 | if (priv->spk_ena_pending) { | ||
| 111 | msleep(75); | ||
| 112 | snd_soc_write(codec, 0x4f5, 0xda); | ||
| 113 | priv->spk_ena_pending = false; | ||
| 114 | priv->spk_ena++; | ||
| 115 | } | ||
| 116 | break; | ||
| 117 | case SND_SOC_DAPM_PRE_PMD: | ||
| 118 | if (manual_ena) { | ||
| 119 | priv->spk_ena--; | ||
| 120 | if (!priv->spk_ena) | ||
| 121 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
| 122 | } | ||
| 123 | |||
| 124 | snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, | ||
| 125 | 1 << w->shift, 0); | ||
| 126 | break; | ||
| 127 | case SND_SOC_DAPM_POST_PMD: | ||
| 128 | if (manual_ena) { | ||
| 129 | if (!priv->spk_ena) | ||
| 130 | snd_soc_write(codec, 0x4f5, 0x0da); | ||
| 131 | } | ||
| 132 | break; | ||
| 133 | } | ||
| 134 | |||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | static irqreturn_t arizona_thermal_warn(int irq, void *data) | ||
| 139 | { | ||
| 140 | struct arizona *arizona = data; | ||
| 141 | unsigned int val; | ||
| 142 | int ret; | ||
| 143 | |||
| 144 | ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, | ||
| 145 | &val); | ||
| 146 | if (ret != 0) { | ||
| 147 | dev_err(arizona->dev, "Failed to read thermal status: %d\n", | ||
| 148 | ret); | ||
| 149 | } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) { | ||
| 150 | dev_crit(arizona->dev, "Thermal warning\n"); | ||
| 151 | } | ||
| 152 | |||
| 153 | return IRQ_HANDLED; | ||
| 154 | } | ||
| 155 | |||
| 156 | static irqreturn_t arizona_thermal_shutdown(int irq, void *data) | ||
| 157 | { | ||
| 158 | struct arizona *arizona = data; | ||
| 159 | unsigned int val; | ||
| 160 | int ret; | ||
| 161 | |||
| 162 | ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, | ||
| 163 | &val); | ||
| 164 | if (ret != 0) { | ||
| 165 | dev_err(arizona->dev, "Failed to read thermal status: %d\n", | ||
| 166 | ret); | ||
| 167 | } else if (val & ARIZONA_SPK_SHUTDOWN_STS) { | ||
| 168 | dev_crit(arizona->dev, "Thermal shutdown\n"); | ||
| 169 | ret = regmap_update_bits(arizona->regmap, | ||
| 170 | ARIZONA_OUTPUT_ENABLES_1, | ||
| 171 | ARIZONA_OUT4L_ENA | | ||
| 172 | ARIZONA_OUT4R_ENA, 0); | ||
| 173 | if (ret != 0) | ||
| 174 | dev_crit(arizona->dev, | ||
| 175 | "Failed to disable speaker outputs: %d\n", | ||
| 176 | ret); | ||
| 177 | } | ||
| 178 | |||
| 179 | return IRQ_HANDLED; | ||
| 180 | } | ||
| 181 | |||
| 182 | static const struct snd_soc_dapm_widget arizona_spkl = | ||
| 183 | SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, | ||
| 184 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | ||
| 185 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | ||
| 186 | |||
| 187 | static const struct snd_soc_dapm_widget arizona_spkr = | ||
| 188 | SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, | ||
| 189 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | ||
| 190 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | ||
| 191 | |||
| 192 | int arizona_init_spk(struct snd_soc_codec *codec) | ||
| 193 | { | ||
| 194 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
| 195 | struct arizona *arizona = priv->arizona; | ||
| 196 | int ret; | ||
| 197 | |||
| 198 | ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1); | ||
| 199 | if (ret != 0) | ||
| 200 | return ret; | ||
| 201 | |||
| 202 | ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1); | ||
| 203 | if (ret != 0) | ||
| 204 | return ret; | ||
| 205 | |||
| 206 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN, | ||
| 207 | "Thermal warning", arizona_thermal_warn, | ||
| 208 | arizona); | ||
| 209 | if (ret != 0) | ||
| 210 | dev_err(arizona->dev, | ||
| 211 | "Failed to get thermal warning IRQ: %d\n", | ||
| 212 | ret); | ||
| 213 | |||
| 214 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN, | ||
| 215 | "Thermal shutdown", arizona_thermal_shutdown, | ||
| 216 | arizona); | ||
| 217 | if (ret != 0) | ||
| 218 | dev_err(arizona->dev, | ||
| 219 | "Failed to get thermal shutdown IRQ: %d\n", | ||
| 220 | ret); | ||
| 221 | |||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | EXPORT_SYMBOL_GPL(arizona_init_spk); | ||
| 225 | |||
| 68 | const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { | 226 | const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { |
| 69 | "None", | 227 | "None", |
| 70 | "Tone Generator 1", | 228 | "Tone Generator 1", |
| @@ -274,6 +432,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values); | |||
| 274 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); | 432 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); |
| 275 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); | 433 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); |
| 276 | 434 | ||
| 435 | const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { | ||
| 436 | "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", | ||
| 437 | }; | ||
| 438 | EXPORT_SYMBOL_GPL(arizona_rate_text); | ||
| 439 | |||
| 440 | const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { | ||
| 441 | 0, 1, 2, 8, | ||
| 442 | }; | ||
| 443 | EXPORT_SYMBOL_GPL(arizona_rate_val); | ||
| 444 | |||
| 445 | |||
| 446 | const struct soc_enum arizona_isrc_fsl[] = { | ||
| 447 | SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2, | ||
| 448 | ARIZONA_ISRC1_FSL_SHIFT, 0xf, | ||
| 449 | ARIZONA_RATE_ENUM_SIZE, | ||
| 450 | arizona_rate_text, arizona_rate_val), | ||
| 451 | SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2, | ||
| 452 | ARIZONA_ISRC2_FSL_SHIFT, 0xf, | ||
| 453 | ARIZONA_RATE_ENUM_SIZE, | ||
| 454 | arizona_rate_text, arizona_rate_val), | ||
| 455 | SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2, | ||
| 456 | ARIZONA_ISRC3_FSL_SHIFT, 0xf, | ||
| 457 | ARIZONA_RATE_ENUM_SIZE, | ||
| 458 | arizona_rate_text, arizona_rate_val), | ||
| 459 | }; | ||
| 460 | EXPORT_SYMBOL_GPL(arizona_isrc_fsl); | ||
| 461 | |||
| 277 | static const char *arizona_vol_ramp_text[] = { | 462 | static const char *arizona_vol_ramp_text[] = { |
| 278 | "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", | 463 | "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", |
| 279 | "15ms/6dB", "30ms/6dB", | 464 | "15ms/6dB", "30ms/6dB", |
| @@ -332,9 +517,27 @@ const struct soc_enum arizona_ng_hold = | |||
| 332 | 4, arizona_ng_hold_text); | 517 | 4, arizona_ng_hold_text); |
| 333 | EXPORT_SYMBOL_GPL(arizona_ng_hold); | 518 | EXPORT_SYMBOL_GPL(arizona_ng_hold); |
| 334 | 519 | ||
| 520 | static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) | ||
| 521 | { | ||
| 522 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
| 523 | unsigned int val; | ||
| 524 | int i; | ||
| 525 | |||
| 526 | if (ena) | ||
| 527 | val = ARIZONA_IN_VU; | ||
| 528 | else | ||
| 529 | val = 0; | ||
| 530 | |||
| 531 | for (i = 0; i < priv->num_inputs; i++) | ||
| 532 | snd_soc_update_bits(codec, | ||
| 533 | ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4), | ||
| 534 | ARIZONA_IN_VU, val); | ||
| 535 | } | ||
| 536 | |||
| 335 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | 537 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, |
| 336 | int event) | 538 | int event) |
| 337 | { | 539 | { |
| 540 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | ||
| 338 | unsigned int reg; | 541 | unsigned int reg; |
| 339 | 542 | ||
| 340 | if (w->shift % 2) | 543 | if (w->shift % 2) |
| @@ -343,13 +546,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | |||
| 343 | reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); | 546 | reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); |
| 344 | 547 | ||
| 345 | switch (event) { | 548 | switch (event) { |
| 549 | case SND_SOC_DAPM_PRE_PMU: | ||
| 550 | priv->in_pending++; | ||
| 551 | break; | ||
| 346 | case SND_SOC_DAPM_POST_PMU: | 552 | case SND_SOC_DAPM_POST_PMU: |
| 347 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); | 553 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); |
| 554 | |||
| 555 | /* If this is the last input pending then allow VU */ | ||
| 556 | priv->in_pending--; | ||
| 557 | if (priv->in_pending == 0) { | ||
| 558 | msleep(1); | ||
| 559 | arizona_in_set_vu(w->codec, 1); | ||
| 560 | } | ||
| 348 | break; | 561 | break; |
| 349 | case SND_SOC_DAPM_PRE_PMD: | 562 | case SND_SOC_DAPM_PRE_PMD: |
| 350 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, | 563 | snd_soc_update_bits(w->codec, reg, |
| 351 | ARIZONA_IN1L_MUTE); | 564 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, |
| 565 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); | ||
| 352 | break; | 566 | break; |
| 567 | case SND_SOC_DAPM_POST_PMD: | ||
| 568 | /* Disable volume updates if no inputs are enabled */ | ||
| 569 | reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES); | ||
| 570 | if (reg == 0) | ||
| 571 | arizona_in_set_vu(w->codec, 0); | ||
| 353 | } | 572 | } |
| 354 | 573 | ||
| 355 | return 0; | 574 | return 0; |
| @@ -360,10 +579,61 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
| 360 | struct snd_kcontrol *kcontrol, | 579 | struct snd_kcontrol *kcontrol, |
| 361 | int event) | 580 | int event) |
| 362 | { | 581 | { |
| 582 | switch (event) { | ||
| 583 | case SND_SOC_DAPM_POST_PMU: | ||
| 584 | switch (w->shift) { | ||
| 585 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
| 586 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
| 587 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
| 588 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
| 589 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
| 590 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
| 591 | msleep(17); | ||
| 592 | break; | ||
| 593 | |||
| 594 | default: | ||
| 595 | break; | ||
| 596 | } | ||
| 597 | break; | ||
| 598 | } | ||
| 599 | |||
| 363 | return 0; | 600 | return 0; |
| 364 | } | 601 | } |
| 365 | EXPORT_SYMBOL_GPL(arizona_out_ev); | 602 | EXPORT_SYMBOL_GPL(arizona_out_ev); |
| 366 | 603 | ||
| 604 | int arizona_hp_ev(struct snd_soc_dapm_widget *w, | ||
| 605 | struct snd_kcontrol *kcontrol, | ||
| 606 | int event) | ||
| 607 | { | ||
| 608 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | ||
| 609 | unsigned int mask = 1 << w->shift; | ||
| 610 | unsigned int val; | ||
| 611 | |||
| 612 | switch (event) { | ||
| 613 | case SND_SOC_DAPM_POST_PMU: | ||
| 614 | val = mask; | ||
| 615 | break; | ||
| 616 | case SND_SOC_DAPM_PRE_PMD: | ||
| 617 | val = 0; | ||
| 618 | break; | ||
| 619 | default: | ||
| 620 | return -EINVAL; | ||
| 621 | } | ||
| 622 | |||
| 623 | /* Store the desired state for the HP outputs */ | ||
| 624 | priv->arizona->hp_ena &= ~mask; | ||
| 625 | priv->arizona->hp_ena |= val; | ||
| 626 | |||
| 627 | /* Force off if HPDET magic is active */ | ||
| 628 | if (priv->arizona->hpdet_magic) | ||
| 629 | val = 0; | ||
| 630 | |||
| 631 | snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val); | ||
| 632 | |||
| 633 | return arizona_out_ev(w, kcontrol, event); | ||
| 634 | } | ||
| 635 | EXPORT_SYMBOL_GPL(arizona_hp_ev); | ||
| 636 | |||
| 367 | static unsigned int arizona_sysclk_48k_rates[] = { | 637 | static unsigned int arizona_sysclk_48k_rates[] = { |
| 368 | 6144000, | 638 | 6144000, |
| 369 | 12288000, | 639 | 12288000, |
| @@ -469,27 +739,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
| 469 | break; | 739 | break; |
| 470 | case 11289600: | 740 | case 11289600: |
| 471 | case 12288000: | 741 | case 12288000: |
| 472 | val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; | 742 | val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
| 473 | break; | 743 | break; |
| 474 | case 22579200: | 744 | case 22579200: |
| 475 | case 24576000: | 745 | case 24576000: |
| 476 | val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; | 746 | val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
| 477 | break; | 747 | break; |
| 478 | case 45158400: | 748 | case 45158400: |
| 479 | case 49152000: | 749 | case 49152000: |
| 480 | val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; | 750 | val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
| 481 | break; | 751 | break; |
| 482 | case 67737600: | 752 | case 67737600: |
| 483 | case 73728000: | 753 | case 73728000: |
| 484 | val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; | 754 | val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
| 485 | break; | 755 | break; |
| 486 | case 90316800: | 756 | case 90316800: |
| 487 | case 98304000: | 757 | case 98304000: |
| 488 | val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; | 758 | val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
| 489 | break; | 759 | break; |
| 490 | case 135475200: | 760 | case 135475200: |
| 491 | case 147456000: | 761 | case 147456000: |
| 492 | val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; | 762 | val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
| 493 | break; | 763 | break; |
| 494 | case 0: | 764 | case 0: |
| 495 | dev_dbg(arizona->dev, "%s cleared\n", name); | 765 | dev_dbg(arizona->dev, "%s cleared\n", name); |
| @@ -783,7 +1053,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
| 783 | struct arizona *arizona = priv->arizona; | 1053 | struct arizona *arizona = priv->arizona; |
| 784 | int base = dai->driver->base; | 1054 | int base = dai->driver->base; |
| 785 | const int *rates; | 1055 | const int *rates; |
| 786 | int i, ret; | 1056 | int i, ret, val; |
| 787 | int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; | 1057 | int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; |
| 788 | int bclk, lrclk, wl, frame, bclk_target; | 1058 | int bclk, lrclk, wl, frame, bclk_target; |
| 789 | 1059 | ||
| @@ -799,6 +1069,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
| 799 | bclk_target *= chan_limit; | 1069 | bclk_target *= chan_limit; |
| 800 | } | 1070 | } |
| 801 | 1071 | ||
| 1072 | /* Force stereo for I2S mode */ | ||
| 1073 | val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT); | ||
| 1074 | if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) { | ||
| 1075 | arizona_aif_dbg(dai, "Forcing stereo mode\n"); | ||
| 1076 | bclk_target *= 2; | ||
| 1077 | } | ||
| 1078 | |||
| 802 | for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { | 1079 | for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { |
| 803 | if (rates[i] >= bclk_target && | 1080 | if (rates[i] >= bclk_target && |
| 804 | rates[i] % params_rate(params) == 0) { | 1081 | rates[i] % params_rate(params) == 0) { |
| @@ -955,6 +1232,16 @@ static struct { | |||
| 955 | { 1000000, 13500000, 0, 1 }, | 1232 | { 1000000, 13500000, 0, 1 }, |
| 956 | }; | 1233 | }; |
| 957 | 1234 | ||
| 1235 | static struct { | ||
| 1236 | unsigned int min; | ||
| 1237 | unsigned int max; | ||
| 1238 | u16 gain; | ||
| 1239 | } fll_gains[] = { | ||
| 1240 | { 0, 256000, 0 }, | ||
| 1241 | { 256000, 1000000, 2 }, | ||
| 1242 | { 1000000, 13500000, 4 }, | ||
| 1243 | }; | ||
| 1244 | |||
| 958 | struct arizona_fll_cfg { | 1245 | struct arizona_fll_cfg { |
| 959 | int n; | 1246 | int n; |
| 960 | int theta; | 1247 | int theta; |
| @@ -962,6 +1249,7 @@ struct arizona_fll_cfg { | |||
| 962 | int refdiv; | 1249 | int refdiv; |
| 963 | int outdiv; | 1250 | int outdiv; |
| 964 | int fratio; | 1251 | int fratio; |
| 1252 | int gain; | ||
| 965 | }; | 1253 | }; |
| 966 | 1254 | ||
| 967 | static int arizona_calc_fll(struct arizona_fll *fll, | 1255 | static int arizona_calc_fll(struct arizona_fll *fll, |
| @@ -1021,6 +1309,18 @@ static int arizona_calc_fll(struct arizona_fll *fll, | |||
| 1021 | return -EINVAL; | 1309 | return -EINVAL; |
| 1022 | } | 1310 | } |
| 1023 | 1311 | ||
| 1312 | for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { | ||
| 1313 | if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { | ||
| 1314 | cfg->gain = fll_gains[i].gain; | ||
| 1315 | break; | ||
| 1316 | } | ||
| 1317 | } | ||
| 1318 | if (i == ARRAY_SIZE(fll_gains)) { | ||
| 1319 | arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", | ||
| 1320 | Fref); | ||
| 1321 | return -EINVAL; | ||
| 1322 | } | ||
| 1323 | |||
| 1024 | cfg->n = target / (ratio * Fref); | 1324 | cfg->n = target / (ratio * Fref); |
| 1025 | 1325 | ||
| 1026 | if (target % (ratio * Fref)) { | 1326 | if (target % (ratio * Fref)) { |
| @@ -1048,13 +1348,15 @@ static int arizona_calc_fll(struct arizona_fll *fll, | |||
| 1048 | cfg->n, cfg->theta, cfg->lambda); | 1348 | cfg->n, cfg->theta, cfg->lambda); |
| 1049 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", | 1349 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", |
| 1050 | cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); | 1350 | cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); |
| 1351 | arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain); | ||
| 1051 | 1352 | ||
| 1052 | return 0; | 1353 | return 0; |
| 1053 | 1354 | ||
| 1054 | } | 1355 | } |
| 1055 | 1356 | ||
| 1056 | static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | 1357 | static void arizona_apply_fll(struct arizona *arizona, unsigned int base, |
| 1057 | struct arizona_fll_cfg *cfg, int source) | 1358 | struct arizona_fll_cfg *cfg, int source, |
| 1359 | bool sync) | ||
| 1058 | { | 1360 | { |
| 1059 | regmap_update_bits(arizona->regmap, base + 3, | 1361 | regmap_update_bits(arizona->regmap, base + 3, |
| 1060 | ARIZONA_FLL1_THETA_MASK, cfg->theta); | 1362 | ARIZONA_FLL1_THETA_MASK, cfg->theta); |
| @@ -1069,87 +1371,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
| 1069 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | | 1371 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | |
| 1070 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); | 1372 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); |
| 1071 | 1373 | ||
| 1374 | if (sync) | ||
| 1375 | regmap_update_bits(arizona->regmap, base + 0x7, | ||
| 1376 | ARIZONA_FLL1_GAIN_MASK, | ||
| 1377 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | ||
| 1378 | else | ||
| 1379 | regmap_update_bits(arizona->regmap, base + 0x9, | ||
| 1380 | ARIZONA_FLL1_GAIN_MASK, | ||
| 1381 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | ||
| 1382 | |||
| 1072 | regmap_update_bits(arizona->regmap, base + 2, | 1383 | regmap_update_bits(arizona->regmap, base + 2, |
| 1073 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, | 1384 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, |
| 1074 | ARIZONA_FLL1_CTRL_UPD | cfg->n); | 1385 | ARIZONA_FLL1_CTRL_UPD | cfg->n); |
| 1075 | } | 1386 | } |
| 1076 | 1387 | ||
| 1077 | int arizona_set_fll(struct arizona_fll *fll, int source, | 1388 | static bool arizona_is_enabled_fll(struct arizona_fll *fll) |
| 1078 | unsigned int Fref, unsigned int Fout) | ||
| 1079 | { | 1389 | { |
| 1080 | struct arizona *arizona = fll->arizona; | 1390 | struct arizona *arizona = fll->arizona; |
| 1081 | struct arizona_fll_cfg cfg, sync; | 1391 | unsigned int reg; |
| 1082 | unsigned int reg, val; | ||
| 1083 | int syncsrc; | ||
| 1084 | bool ena; | ||
| 1085 | int ret; | 1392 | int ret; |
| 1086 | 1393 | ||
| 1087 | if (fll->fref == Fref && fll->fout == Fout) | ||
| 1088 | return 0; | ||
| 1089 | |||
| 1090 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); | 1394 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); |
| 1091 | if (ret != 0) { | 1395 | if (ret != 0) { |
| 1092 | arizona_fll_err(fll, "Failed to read current state: %d\n", | 1396 | arizona_fll_err(fll, "Failed to read current state: %d\n", |
| 1093 | ret); | 1397 | ret); |
| 1094 | return ret; | 1398 | return ret; |
| 1095 | } | 1399 | } |
| 1096 | ena = reg & ARIZONA_FLL1_ENA; | ||
| 1097 | 1400 | ||
| 1098 | if (Fout) { | 1401 | return reg & ARIZONA_FLL1_ENA; |
| 1099 | /* Do we have a 32kHz reference? */ | 1402 | } |
| 1100 | regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); | ||
| 1101 | switch (val & ARIZONA_CLK_32K_SRC_MASK) { | ||
| 1102 | case ARIZONA_CLK_SRC_MCLK1: | ||
| 1103 | case ARIZONA_CLK_SRC_MCLK2: | ||
| 1104 | syncsrc = val & ARIZONA_CLK_32K_SRC_MASK; | ||
| 1105 | break; | ||
| 1106 | default: | ||
| 1107 | syncsrc = -1; | ||
| 1108 | } | ||
| 1109 | 1403 | ||
| 1110 | if (source == syncsrc) | 1404 | static void arizona_enable_fll(struct arizona_fll *fll, |
| 1111 | syncsrc = -1; | 1405 | struct arizona_fll_cfg *ref, |
| 1406 | struct arizona_fll_cfg *sync) | ||
| 1407 | { | ||
| 1408 | struct arizona *arizona = fll->arizona; | ||
| 1409 | int ret; | ||
| 1112 | 1410 | ||
| 1113 | if (syncsrc >= 0) { | 1411 | /* |
| 1114 | ret = arizona_calc_fll(fll, &sync, Fref, Fout); | 1412 | * If we have both REFCLK and SYNCCLK then enable both, |
| 1115 | if (ret != 0) | 1413 | * otherwise apply the SYNCCLK settings to REFCLK. |
| 1116 | return ret; | 1414 | */ |
| 1415 | if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) { | ||
| 1416 | regmap_update_bits(arizona->regmap, fll->base + 5, | ||
| 1417 | ARIZONA_FLL1_OUTDIV_MASK, | ||
| 1418 | ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
| 1419 | |||
| 1420 | arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, | ||
| 1421 | false); | ||
| 1422 | if (fll->sync_src >= 0) | ||
| 1423 | arizona_apply_fll(arizona, fll->base + 0x10, sync, | ||
| 1424 | fll->sync_src, true); | ||
| 1425 | } else if (fll->sync_src >= 0) { | ||
| 1426 | regmap_update_bits(arizona->regmap, fll->base + 5, | ||
| 1427 | ARIZONA_FLL1_OUTDIV_MASK, | ||
| 1428 | sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
| 1429 | |||
| 1430 | arizona_apply_fll(arizona, fll->base, sync, | ||
| 1431 | fll->sync_src, false); | ||
| 1117 | 1432 | ||
| 1118 | ret = arizona_calc_fll(fll, &cfg, 32768, Fout); | ||
| 1119 | if (ret != 0) | ||
| 1120 | return ret; | ||
| 1121 | } else { | ||
| 1122 | ret = arizona_calc_fll(fll, &cfg, Fref, Fout); | ||
| 1123 | if (ret != 0) | ||
| 1124 | return ret; | ||
| 1125 | } | ||
| 1126 | } else { | ||
| 1127 | regmap_update_bits(arizona->regmap, fll->base + 1, | ||
| 1128 | ARIZONA_FLL1_ENA, 0); | ||
| 1129 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1433 | regmap_update_bits(arizona->regmap, fll->base + 0x11, |
| 1130 | ARIZONA_FLL1_SYNC_ENA, 0); | 1434 | ARIZONA_FLL1_SYNC_ENA, 0); |
| 1131 | |||
| 1132 | if (ena) | ||
| 1133 | pm_runtime_put_autosuspend(arizona->dev); | ||
| 1134 | |||
| 1135 | fll->fref = Fref; | ||
| 1136 | fll->fout = Fout; | ||
| 1137 | |||
| 1138 | return 0; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | regmap_update_bits(arizona->regmap, fll->base + 5, | ||
| 1142 | ARIZONA_FLL1_OUTDIV_MASK, | ||
| 1143 | cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
| 1144 | |||
| 1145 | if (syncsrc >= 0) { | ||
| 1146 | arizona_apply_fll(arizona, fll->base, &cfg, syncsrc); | ||
| 1147 | arizona_apply_fll(arizona, fll->base + 0x10, &sync, source); | ||
| 1148 | } else { | 1435 | } else { |
| 1149 | arizona_apply_fll(arizona, fll->base, &cfg, source); | 1436 | arizona_fll_err(fll, "No clocks provided\n"); |
| 1437 | return; | ||
| 1150 | } | 1438 | } |
| 1151 | 1439 | ||
| 1152 | if (!ena) | 1440 | /* |
| 1441 | * Increase the bandwidth if we're not using a low frequency | ||
| 1442 | * sync source. | ||
| 1443 | */ | ||
| 1444 | if (fll->sync_src >= 0 && fll->sync_freq > 100000) | ||
| 1445 | regmap_update_bits(arizona->regmap, fll->base + 0x17, | ||
| 1446 | ARIZONA_FLL1_SYNC_BW, 0); | ||
| 1447 | else | ||
| 1448 | regmap_update_bits(arizona->regmap, fll->base + 0x17, | ||
| 1449 | ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); | ||
| 1450 | |||
| 1451 | if (!arizona_is_enabled_fll(fll)) | ||
| 1153 | pm_runtime_get(arizona->dev); | 1452 | pm_runtime_get(arizona->dev); |
| 1154 | 1453 | ||
| 1155 | /* Clear any pending completions */ | 1454 | /* Clear any pending completions */ |
| @@ -1157,7 +1456,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
| 1157 | 1456 | ||
| 1158 | regmap_update_bits(arizona->regmap, fll->base + 1, | 1457 | regmap_update_bits(arizona->regmap, fll->base + 1, |
| 1159 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | 1458 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); |
| 1160 | if (syncsrc >= 0) | 1459 | if (fll->ref_src >= 0 && fll->sync_src >= 0 && |
| 1460 | fll->ref_src != fll->sync_src) | ||
| 1161 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1461 | regmap_update_bits(arizona->regmap, fll->base + 0x11, |
| 1162 | ARIZONA_FLL1_SYNC_ENA, | 1462 | ARIZONA_FLL1_SYNC_ENA, |
| 1163 | ARIZONA_FLL1_SYNC_ENA); | 1463 | ARIZONA_FLL1_SYNC_ENA); |
| @@ -1166,10 +1466,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
| 1166 | msecs_to_jiffies(250)); | 1466 | msecs_to_jiffies(250)); |
| 1167 | if (ret == 0) | 1467 | if (ret == 0) |
| 1168 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); | 1468 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); |
| 1469 | } | ||
| 1470 | |||
| 1471 | static void arizona_disable_fll(struct arizona_fll *fll) | ||
| 1472 | { | ||
| 1473 | struct arizona *arizona = fll->arizona; | ||
| 1474 | bool change; | ||
| 1475 | |||
| 1476 | regmap_update_bits_check(arizona->regmap, fll->base + 1, | ||
| 1477 | ARIZONA_FLL1_ENA, 0, &change); | ||
| 1478 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | ||
| 1479 | ARIZONA_FLL1_SYNC_ENA, 0); | ||
| 1480 | |||
| 1481 | if (change) | ||
| 1482 | pm_runtime_put_autosuspend(arizona->dev); | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | ||
| 1486 | unsigned int Fref, unsigned int Fout) | ||
| 1487 | { | ||
| 1488 | struct arizona_fll_cfg ref, sync; | ||
| 1489 | int ret; | ||
| 1490 | |||
| 1491 | if (fll->ref_src == source && fll->ref_freq == Fref) | ||
| 1492 | return 0; | ||
| 1493 | |||
| 1494 | if (fll->fout && Fref > 0) { | ||
| 1495 | ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); | ||
| 1496 | if (ret != 0) | ||
| 1497 | return ret; | ||
| 1498 | |||
| 1499 | if (fll->sync_src >= 0) { | ||
| 1500 | ret = arizona_calc_fll(fll, &sync, fll->sync_freq, | ||
| 1501 | fll->fout); | ||
| 1502 | if (ret != 0) | ||
| 1503 | return ret; | ||
| 1504 | } | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | fll->ref_src = source; | ||
| 1508 | fll->ref_freq = Fref; | ||
| 1169 | 1509 | ||
| 1170 | fll->fref = Fref; | 1510 | if (fll->fout && Fref > 0) { |
| 1511 | arizona_enable_fll(fll, &ref, &sync); | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | return 0; | ||
| 1515 | } | ||
| 1516 | EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); | ||
| 1517 | |||
| 1518 | int arizona_set_fll(struct arizona_fll *fll, int source, | ||
| 1519 | unsigned int Fref, unsigned int Fout) | ||
| 1520 | { | ||
| 1521 | struct arizona_fll_cfg ref, sync; | ||
| 1522 | int ret; | ||
| 1523 | |||
| 1524 | if (fll->sync_src == source && | ||
| 1525 | fll->sync_freq == Fref && fll->fout == Fout) | ||
| 1526 | return 0; | ||
| 1527 | |||
| 1528 | if (Fout) { | ||
| 1529 | if (fll->ref_src >= 0) { | ||
| 1530 | ret = arizona_calc_fll(fll, &ref, fll->ref_freq, | ||
| 1531 | Fout); | ||
| 1532 | if (ret != 0) | ||
| 1533 | return ret; | ||
| 1534 | } | ||
| 1535 | |||
| 1536 | ret = arizona_calc_fll(fll, &sync, Fref, Fout); | ||
| 1537 | if (ret != 0) | ||
| 1538 | return ret; | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | fll->sync_src = source; | ||
| 1542 | fll->sync_freq = Fref; | ||
| 1171 | fll->fout = Fout; | 1543 | fll->fout = Fout; |
| 1172 | 1544 | ||
| 1545 | if (Fout) { | ||
| 1546 | arizona_enable_fll(fll, &ref, &sync); | ||
| 1547 | } else { | ||
| 1548 | arizona_disable_fll(fll); | ||
| 1549 | } | ||
| 1550 | |||
| 1173 | return 0; | 1551 | return 0; |
| 1174 | } | 1552 | } |
| 1175 | EXPORT_SYMBOL_GPL(arizona_set_fll); | 1553 | EXPORT_SYMBOL_GPL(arizona_set_fll); |
| @@ -1178,12 +1556,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, | |||
| 1178 | int ok_irq, struct arizona_fll *fll) | 1556 | int ok_irq, struct arizona_fll *fll) |
| 1179 | { | 1557 | { |
| 1180 | int ret; | 1558 | int ret; |
| 1559 | unsigned int val; | ||
| 1181 | 1560 | ||
| 1182 | init_completion(&fll->ok); | 1561 | init_completion(&fll->ok); |
| 1183 | 1562 | ||
| 1184 | fll->id = id; | 1563 | fll->id = id; |
| 1185 | fll->base = base; | 1564 | fll->base = base; |
| 1186 | fll->arizona = arizona; | 1565 | fll->arizona = arizona; |
| 1566 | fll->sync_src = ARIZONA_FLL_SRC_NONE; | ||
| 1567 | |||
| 1568 | /* Configure default refclk to 32kHz if we have one */ | ||
| 1569 | regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); | ||
| 1570 | switch (val & ARIZONA_CLK_32K_SRC_MASK) { | ||
| 1571 | case ARIZONA_CLK_SRC_MCLK1: | ||
| 1572 | case ARIZONA_CLK_SRC_MCLK2: | ||
| 1573 | fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; | ||
| 1574 | break; | ||
| 1575 | default: | ||
| 1576 | fll->ref_src = ARIZONA_FLL_SRC_NONE; | ||
| 1577 | } | ||
| 1578 | fll->ref_freq = 32768; | ||
| 1187 | 1579 | ||
| 1188 | snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); | 1580 | snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); |
| 1189 | snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), | 1581 | snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 116372c91f5d..af39f1006427 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define ARIZONA_CLK_SRC_AIF2BCLK 0x9 | 32 | #define ARIZONA_CLK_SRC_AIF2BCLK 0x9 |
| 33 | #define ARIZONA_CLK_SRC_AIF3BCLK 0xa | 33 | #define ARIZONA_CLK_SRC_AIF3BCLK 0xa |
| 34 | 34 | ||
| 35 | #define ARIZONA_FLL_SRC_NONE -1 | ||
| 35 | #define ARIZONA_FLL_SRC_MCLK1 0 | 36 | #define ARIZONA_FLL_SRC_MCLK1 0 |
| 36 | #define ARIZONA_FLL_SRC_MCLK2 1 | 37 | #define ARIZONA_FLL_SRC_MCLK2 1 |
| 37 | #define ARIZONA_FLL_SRC_SLIMCLK 3 | 38 | #define ARIZONA_FLL_SRC_SLIMCLK 3 |
| @@ -48,6 +49,14 @@ | |||
| 48 | #define ARIZONA_MIXER_VOL_SHIFT 1 | 49 | #define ARIZONA_MIXER_VOL_SHIFT 1 |
| 49 | #define ARIZONA_MIXER_VOL_WIDTH 7 | 50 | #define ARIZONA_MIXER_VOL_WIDTH 7 |
| 50 | 51 | ||
| 52 | #define ARIZONA_CLK_6MHZ 0 | ||
| 53 | #define ARIZONA_CLK_12MHZ 1 | ||
| 54 | #define ARIZONA_CLK_24MHZ 2 | ||
| 55 | #define ARIZONA_CLK_49MHZ 3 | ||
| 56 | #define ARIZONA_CLK_73MHZ 4 | ||
| 57 | #define ARIZONA_CLK_98MHZ 5 | ||
| 58 | #define ARIZONA_CLK_147MHZ 6 | ||
| 59 | |||
| 51 | #define ARIZONA_MAX_DAI 4 | 60 | #define ARIZONA_MAX_DAI 4 |
| 52 | #define ARIZONA_MAX_ADSP 4 | 61 | #define ARIZONA_MAX_ADSP 4 |
| 53 | 62 | ||
| @@ -64,6 +73,12 @@ struct arizona_priv { | |||
| 64 | int sysclk; | 73 | int sysclk; |
| 65 | int asyncclk; | 74 | int asyncclk; |
| 66 | struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; | 75 | struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; |
| 76 | |||
| 77 | int num_inputs; | ||
| 78 | unsigned int in_pending; | ||
| 79 | |||
| 80 | unsigned int spk_ena:2; | ||
| 81 | unsigned int spk_ena_pending:1; | ||
| 67 | }; | 82 | }; |
| 68 | 83 | ||
| 69 | #define ARIZONA_NUM_MIXER_INPUTS 99 | 84 | #define ARIZONA_NUM_MIXER_INPUTS 99 |
| @@ -165,6 +180,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
| 165 | ARIZONA_MIXER_ROUTES(name, name "L"), \ | 180 | ARIZONA_MIXER_ROUTES(name, name "L"), \ |
| 166 | ARIZONA_MIXER_ROUTES(name, name "R") | 181 | ARIZONA_MIXER_ROUTES(name, name "R") |
| 167 | 182 | ||
| 183 | #define ARIZONA_RATE_ENUM_SIZE 4 | ||
| 184 | extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; | ||
| 185 | extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; | ||
| 186 | |||
| 187 | extern const struct soc_enum arizona_isrc_fsl[]; | ||
| 188 | |||
| 168 | extern const struct soc_enum arizona_in_vi_ramp; | 189 | extern const struct soc_enum arizona_in_vi_ramp; |
| 169 | extern const struct soc_enum arizona_in_vd_ramp; | 190 | extern const struct soc_enum arizona_in_vd_ramp; |
| 170 | 191 | ||
| @@ -184,6 +205,9 @@ extern int arizona_in_ev(struct snd_soc_dapm_widget *w, | |||
| 184 | extern int arizona_out_ev(struct snd_soc_dapm_widget *w, | 205 | extern int arizona_out_ev(struct snd_soc_dapm_widget *w, |
| 185 | struct snd_kcontrol *kcontrol, | 206 | struct snd_kcontrol *kcontrol, |
| 186 | int event); | 207 | int event); |
| 208 | extern int arizona_hp_ev(struct snd_soc_dapm_widget *w, | ||
| 209 | struct snd_kcontrol *kcontrol, | ||
| 210 | int event); | ||
| 187 | 211 | ||
| 188 | extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 212 | extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
| 189 | int source, unsigned int freq, int dir); | 213 | int source, unsigned int freq, int dir); |
| @@ -198,8 +222,12 @@ struct arizona_fll { | |||
| 198 | unsigned int base; | 222 | unsigned int base; |
| 199 | unsigned int vco_mult; | 223 | unsigned int vco_mult; |
| 200 | struct completion ok; | 224 | struct completion ok; |
| 201 | unsigned int fref; | 225 | |
| 202 | unsigned int fout; | 226 | unsigned int fout; |
| 227 | int sync_src; | ||
| 228 | unsigned int sync_freq; | ||
| 229 | int ref_src; | ||
| 230 | unsigned int ref_freq; | ||
| 203 | 231 | ||
| 204 | char lock_name[ARIZONA_FLL_NAME_LEN]; | 232 | char lock_name[ARIZONA_FLL_NAME_LEN]; |
| 205 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; | 233 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; |
| @@ -207,9 +235,13 @@ struct arizona_fll { | |||
| 207 | 235 | ||
| 208 | extern int arizona_init_fll(struct arizona *arizona, int id, int base, | 236 | extern int arizona_init_fll(struct arizona *arizona, int id, int base, |
| 209 | int lock_irq, int ok_irq, struct arizona_fll *fll); | 237 | int lock_irq, int ok_irq, struct arizona_fll *fll); |
| 238 | extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | ||
| 239 | unsigned int Fref, unsigned int Fout); | ||
| 210 | extern int arizona_set_fll(struct arizona_fll *fll, int source, | 240 | extern int arizona_set_fll(struct arizona_fll *fll, int source, |
| 211 | unsigned int Fref, unsigned int Fout); | 241 | unsigned int Fref, unsigned int Fout); |
| 212 | 242 | ||
| 243 | extern int arizona_init_spk(struct snd_soc_codec *codec); | ||
| 244 | |||
| 213 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); | 245 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); |
| 214 | 246 | ||
| 215 | int arizona_set_output_mode(struct snd_soc_codec *codec, int output, | 247 | int arizona_set_output_mode(struct snd_soc_codec *codec, int output, |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index ddc98f02ecbd..57ba315d0c84 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
| @@ -1565,7 +1565,7 @@ static int wm2200_probe(struct snd_soc_codec *codec) | |||
| 1565 | return ret; | 1565 | return ret; |
| 1566 | } | 1566 | } |
| 1567 | 1567 | ||
| 1568 | ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); | 1568 | ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); |
| 1569 | if (ret != 0) | 1569 | if (ret != 0) |
| 1570 | return ret; | 1570 | return ret; |
| 1571 | 1571 | ||
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 34d0201d6a78..e895d3939eef 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
| @@ -36,9 +36,6 @@ | |||
| 36 | struct wm5102_priv { | 36 | struct wm5102_priv { |
| 37 | struct arizona_priv core; | 37 | struct arizona_priv core; |
| 38 | struct arizona_fll fll[2]; | 38 | struct arizona_fll fll[2]; |
| 39 | |||
| 40 | unsigned int spk_ena:2; | ||
| 41 | unsigned int spk_ena_pending:1; | ||
| 42 | }; | 39 | }; |
| 43 | 40 | ||
| 44 | static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); | 41 | static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); |
| @@ -615,6 +612,26 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
| 615 | return 0; | 612 | return 0; |
| 616 | } | 613 | } |
| 617 | 614 | ||
| 615 | static const char *wm5102_osr_text[] = { | ||
| 616 | "Low power", "Normal", "High performance", | ||
| 617 | }; | ||
| 618 | |||
| 619 | static const unsigned int wm5102_osr_val[] = { | ||
| 620 | 0x0, 0x3, 0x5, | ||
| 621 | }; | ||
| 622 | |||
| 623 | static const struct soc_enum wm5102_hpout_osr[] = { | ||
| 624 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, | ||
| 625 | ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, | ||
| 626 | wm5102_osr_text, wm5102_osr_val), | ||
| 627 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, | ||
| 628 | ARIZONA_OUT2_OSR_SHIFT, 0x7, 3, | ||
| 629 | wm5102_osr_text, wm5102_osr_val), | ||
| 630 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, | ||
| 631 | ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, | ||
| 632 | wm5102_osr_text, wm5102_osr_val), | ||
| 633 | }; | ||
| 634 | |||
| 618 | #define WM5102_NG_SRC(name, base) \ | 635 | #define WM5102_NG_SRC(name, base) \ |
| 619 | SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ | 636 | SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ |
| 620 | SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ | 637 | SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ |
| @@ -745,6 +762,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | |||
| 745 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 762 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
| 746 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), | 763 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), |
| 747 | 764 | ||
| 765 | SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), | ||
| 766 | SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), | ||
| 767 | |||
| 748 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), | 768 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), |
| 749 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), | 769 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), |
| 750 | 770 | ||
| @@ -761,6 +781,8 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), | |||
| 761 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), | 781 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), |
| 762 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), | 782 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), |
| 763 | 783 | ||
| 784 | SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, | ||
| 785 | ARIZONA_OUT4_OSR_SHIFT, 1, 0), | ||
| 764 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, | 786 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, |
| 765 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), | 787 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), |
| 766 | 788 | ||
| @@ -790,6 +812,10 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, | |||
| 790 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, | 812 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, |
| 791 | 0xbf, 0, digital_tlv), | 813 | 0xbf, 0, digital_tlv), |
| 792 | 814 | ||
| 815 | SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), | ||
| 816 | SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), | ||
| 817 | SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]), | ||
| 818 | |||
| 793 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), | 819 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), |
| 794 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), | 820 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), |
| 795 | 821 | ||
| @@ -828,47 +854,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), | |||
| 828 | ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), | 854 | ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), |
| 829 | }; | 855 | }; |
| 830 | 856 | ||
| 831 | static int wm5102_spk_ev(struct snd_soc_dapm_widget *w, | ||
| 832 | struct snd_kcontrol *kcontrol, | ||
| 833 | int event) | ||
| 834 | { | ||
| 835 | struct snd_soc_codec *codec = w->codec; | ||
| 836 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | ||
| 837 | struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec); | ||
| 838 | |||
| 839 | if (arizona->rev < 1) | ||
| 840 | return 0; | ||
| 841 | |||
| 842 | switch (event) { | ||
| 843 | case SND_SOC_DAPM_PRE_PMU: | ||
| 844 | if (!wm5102->spk_ena) { | ||
| 845 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
| 846 | wm5102->spk_ena_pending = true; | ||
| 847 | } | ||
| 848 | break; | ||
| 849 | case SND_SOC_DAPM_POST_PMU: | ||
| 850 | if (wm5102->spk_ena_pending) { | ||
| 851 | msleep(75); | ||
| 852 | snd_soc_write(codec, 0x4f5, 0xda); | ||
| 853 | wm5102->spk_ena_pending = false; | ||
| 854 | wm5102->spk_ena++; | ||
| 855 | } | ||
| 856 | break; | ||
| 857 | case SND_SOC_DAPM_PRE_PMD: | ||
| 858 | wm5102->spk_ena--; | ||
| 859 | if (!wm5102->spk_ena) | ||
| 860 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
| 861 | break; | ||
| 862 | case SND_SOC_DAPM_POST_PMD: | ||
| 863 | if (!wm5102->spk_ena) | ||
| 864 | snd_soc_write(codec, 0x4f5, 0x0da); | ||
| 865 | break; | ||
| 866 | } | ||
| 867 | |||
| 868 | return 0; | ||
| 869 | } | ||
| 870 | |||
| 871 | |||
| 872 | ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); | 857 | ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); |
| 873 | ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); | 858 | ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); |
| 874 | ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); | 859 | ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); |
| @@ -984,22 +969,28 @@ SND_SOC_DAPM_INPUT("IN3R"), | |||
| 984 | 969 | ||
| 985 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, | 970 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, |
| 986 | 0, NULL, 0, arizona_in_ev, | 971 | 0, NULL, 0, arizona_in_ev, |
| 987 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 972 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 973 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 988 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, | 974 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, |
| 989 | 0, NULL, 0, arizona_in_ev, | 975 | 0, NULL, 0, arizona_in_ev, |
| 990 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 976 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 977 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 991 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, | 978 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, |
| 992 | 0, NULL, 0, arizona_in_ev, | 979 | 0, NULL, 0, arizona_in_ev, |
| 993 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 980 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 981 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 994 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, | 982 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, |
| 995 | 0, NULL, 0, arizona_in_ev, | 983 | 0, NULL, 0, arizona_in_ev, |
| 996 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 984 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 985 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 997 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, | 986 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, |
| 998 | 0, NULL, 0, arizona_in_ev, | 987 | 0, NULL, 0, arizona_in_ev, |
| 999 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 988 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 989 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 1000 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | 990 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, |
| 1001 | 0, NULL, 0, arizona_in_ev, | 991 | 0, NULL, 0, arizona_in_ev, |
| 1002 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 992 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 993 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 1003 | 994 | ||
| 1004 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 995 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, |
| 1005 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 996 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), |
| @@ -1131,11 +1122,11 @@ ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), | |||
| 1131 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | 1122 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, |
| 1132 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), | 1123 | ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), |
| 1133 | 1124 | ||
| 1134 | SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, | 1125 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, |
| 1135 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1126 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
| 1136 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1127 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| 1137 | SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, | 1128 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, |
| 1138 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1129 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
| 1139 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1130 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| 1140 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, | 1131 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, |
| 1141 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1132 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
| @@ -1146,12 +1137,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, | |||
| 1146 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 1137 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, |
| 1147 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1138 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
| 1148 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1139 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| 1149 | SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, | ||
| 1150 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, | ||
| 1151 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
| 1152 | SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, | ||
| 1153 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, | ||
| 1154 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
| 1155 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 1140 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
| 1156 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1141 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
| 1157 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1142 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| @@ -1494,6 +1479,12 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
| 1494 | return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); | 1479 | return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); |
| 1495 | case WM5102_FLL2: | 1480 | case WM5102_FLL2: |
| 1496 | return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); | 1481 | return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); |
| 1482 | case WM5102_FLL1_REFCLK: | ||
| 1483 | return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref, | ||
| 1484 | Fout); | ||
| 1485 | case WM5102_FLL2_REFCLK: | ||
| 1486 | return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref, | ||
| 1487 | Fout); | ||
| 1497 | default: | 1488 | default: |
| 1498 | return -EINVAL; | 1489 | return -EINVAL; |
| 1499 | } | 1490 | } |
| @@ -1581,10 +1572,12 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) | |||
| 1581 | if (ret != 0) | 1572 | if (ret != 0) |
| 1582 | return ret; | 1573 | return ret; |
| 1583 | 1574 | ||
| 1584 | ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1); | 1575 | ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); |
| 1585 | if (ret != 0) | 1576 | if (ret != 0) |
| 1586 | return ret; | 1577 | return ret; |
| 1587 | 1578 | ||
| 1579 | arizona_init_spk(codec); | ||
| 1580 | |||
| 1588 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); | 1581 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); |
| 1589 | 1582 | ||
| 1590 | priv->core.arizona->dapm = &codec->dapm; | 1583 | priv->core.arizona->dapm = &codec->dapm; |
| @@ -1604,13 +1597,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec) | |||
| 1604 | #define WM5102_DIG_VU 0x0200 | 1597 | #define WM5102_DIG_VU 0x0200 |
| 1605 | 1598 | ||
| 1606 | static unsigned int wm5102_digital_vu[] = { | 1599 | static unsigned int wm5102_digital_vu[] = { |
| 1607 | ARIZONA_ADC_DIGITAL_VOLUME_1L, | ||
| 1608 | ARIZONA_ADC_DIGITAL_VOLUME_1R, | ||
| 1609 | ARIZONA_ADC_DIGITAL_VOLUME_2L, | ||
| 1610 | ARIZONA_ADC_DIGITAL_VOLUME_2R, | ||
| 1611 | ARIZONA_ADC_DIGITAL_VOLUME_3L, | ||
| 1612 | ARIZONA_ADC_DIGITAL_VOLUME_3R, | ||
| 1613 | |||
| 1614 | ARIZONA_DAC_DIGITAL_VOLUME_1L, | 1600 | ARIZONA_DAC_DIGITAL_VOLUME_1L, |
| 1615 | ARIZONA_DAC_DIGITAL_VOLUME_1R, | 1601 | ARIZONA_DAC_DIGITAL_VOLUME_1R, |
| 1616 | ARIZONA_DAC_DIGITAL_VOLUME_2L, | 1602 | ARIZONA_DAC_DIGITAL_VOLUME_2L, |
| @@ -1653,6 +1639,7 @@ static int wm5102_probe(struct platform_device *pdev) | |||
| 1653 | platform_set_drvdata(pdev, wm5102); | 1639 | platform_set_drvdata(pdev, wm5102); |
| 1654 | 1640 | ||
| 1655 | wm5102->core.arizona = arizona; | 1641 | wm5102->core.arizona = arizona; |
| 1642 | wm5102->core.num_inputs = 6; | ||
| 1656 | 1643 | ||
| 1657 | wm5102->core.adsp[0].part = "wm5102"; | 1644 | wm5102->core.adsp[0].part = "wm5102"; |
| 1658 | wm5102->core.adsp[0].num = 1; | 1645 | wm5102->core.adsp[0].num = 1; |
| @@ -1677,6 +1664,12 @@ static int wm5102_probe(struct platform_device *pdev) | |||
| 1677 | ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, | 1664 | ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, |
| 1678 | &wm5102->fll[1]); | 1665 | &wm5102->fll[1]); |
| 1679 | 1666 | ||
| 1667 | /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */ | ||
| 1668 | regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2, | ||
| 1669 | ARIZONA_SAMPLE_RATE_2_MASK, 0x11); | ||
| 1670 | regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3, | ||
| 1671 | ARIZONA_SAMPLE_RATE_3_MASK, 0x12); | ||
| 1672 | |||
| 1680 | for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) | 1673 | for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) |
| 1681 | arizona_init_dai(&wm5102->core, i); | 1674 | arizona_init_dai(&wm5102->core, i); |
| 1682 | 1675 | ||
diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h index d30477f3070c..adb38040f661 100644 --- a/sound/soc/codecs/wm5102.h +++ b/sound/soc/codecs/wm5102.h | |||
| @@ -15,7 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | #include "arizona.h" | 16 | #include "arizona.h" |
| 17 | 17 | ||
| 18 | #define WM5102_FLL1 1 | 18 | #define WM5102_FLL1 1 |
| 19 | #define WM5102_FLL2 2 | 19 | #define WM5102_FLL2 2 |
| 20 | #define WM5102_FLL1_REFCLK 3 | ||
| 21 | #define WM5102_FLL2_REFCLK 4 | ||
| 20 | 22 | ||
| 21 | #endif | 23 | #endif |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index cdeb301da1f6..731884e04776 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
| @@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"), | |||
| 416 | 416 | ||
| 417 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, | 417 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, |
| 418 | 0, NULL, 0, arizona_in_ev, | 418 | 0, NULL, 0, arizona_in_ev, |
| 419 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 419 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 420 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 420 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, | 421 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, |
| 421 | 0, NULL, 0, arizona_in_ev, | 422 | 0, NULL, 0, arizona_in_ev, |
| 422 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 423 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 424 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 423 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, | 425 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, |
| 424 | 0, NULL, 0, arizona_in_ev, | 426 | 0, NULL, 0, arizona_in_ev, |
| 425 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 427 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 428 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 426 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, | 429 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, |
| 427 | 0, NULL, 0, arizona_in_ev, | 430 | 0, NULL, 0, arizona_in_ev, |
| 428 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 431 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 432 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 429 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, | 433 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, |
| 430 | 0, NULL, 0, arizona_in_ev, | 434 | 0, NULL, 0, arizona_in_ev, |
| 431 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 435 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 436 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 432 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | 437 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, |
| 433 | 0, NULL, 0, arizona_in_ev, | 438 | 0, NULL, 0, arizona_in_ev, |
| 434 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 439 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 440 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 435 | SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, | 441 | SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, |
| 436 | 0, NULL, 0, arizona_in_ev, | 442 | 0, NULL, 0, arizona_in_ev, |
| 437 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 443 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 444 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 438 | SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, | 445 | SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, |
| 439 | 0, NULL, 0, arizona_in_ev, | 446 | 0, NULL, 0, arizona_in_ev, |
| 440 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 447 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
| 448 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
| 441 | 449 | ||
| 442 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 450 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, |
| 443 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 451 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), |
| @@ -551,11 +559,11 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, | |||
| 551 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, | 559 | SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, |
| 552 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), | 560 | ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), |
| 553 | 561 | ||
| 554 | SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, | 562 | SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, |
| 555 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 563 | ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
| 556 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 564 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| 557 | SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, | 565 | SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, |
| 558 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 566 | ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, |
| 559 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 567 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| 560 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, | 568 | SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, |
| 561 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 569 | ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
| @@ -569,12 +577,6 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | |||
| 569 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, | 577 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, |
| 570 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 578 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
| 571 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 579 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| 572 | SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, | ||
| 573 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | ||
| 574 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
| 575 | SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, | ||
| 576 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | ||
| 577 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
| 578 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 580 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
| 579 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 581 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
| 580 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 582 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
| @@ -880,6 +882,12 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
| 880 | return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); | 882 | return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); |
| 881 | case WM5110_FLL2: | 883 | case WM5110_FLL2: |
| 882 | return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); | 884 | return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); |
| 885 | case WM5110_FLL1_REFCLK: | ||
| 886 | return arizona_set_fll_refclk(&wm5110->fll[0], source, Fref, | ||
| 887 | Fout); | ||
| 888 | case WM5110_FLL2_REFCLK: | ||
| 889 | return arizona_set_fll_refclk(&wm5110->fll[1], source, Fref, | ||
| 890 | Fout); | ||
| 883 | default: | 891 | default: |
| 884 | return -EINVAL; | 892 | return -EINVAL; |
| 885 | } | 893 | } |
| @@ -987,15 +995,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec) | |||
| 987 | #define WM5110_DIG_VU 0x0200 | 995 | #define WM5110_DIG_VU 0x0200 |
| 988 | 996 | ||
| 989 | static unsigned int wm5110_digital_vu[] = { | 997 | static unsigned int wm5110_digital_vu[] = { |
| 990 | ARIZONA_ADC_DIGITAL_VOLUME_1L, | ||
| 991 | ARIZONA_ADC_DIGITAL_VOLUME_1R, | ||
| 992 | ARIZONA_ADC_DIGITAL_VOLUME_2L, | ||
| 993 | ARIZONA_ADC_DIGITAL_VOLUME_2R, | ||
| 994 | ARIZONA_ADC_DIGITAL_VOLUME_3L, | ||
| 995 | ARIZONA_ADC_DIGITAL_VOLUME_3R, | ||
| 996 | ARIZONA_ADC_DIGITAL_VOLUME_4L, | ||
| 997 | ARIZONA_ADC_DIGITAL_VOLUME_4R, | ||
| 998 | |||
| 999 | ARIZONA_DAC_DIGITAL_VOLUME_1L, | 998 | ARIZONA_DAC_DIGITAL_VOLUME_1L, |
| 1000 | ARIZONA_DAC_DIGITAL_VOLUME_1R, | 999 | ARIZONA_DAC_DIGITAL_VOLUME_1R, |
| 1001 | ARIZONA_DAC_DIGITAL_VOLUME_2L, | 1000 | ARIZONA_DAC_DIGITAL_VOLUME_2L, |
| @@ -1040,6 +1039,7 @@ static int wm5110_probe(struct platform_device *pdev) | |||
| 1040 | platform_set_drvdata(pdev, wm5110); | 1039 | platform_set_drvdata(pdev, wm5110); |
| 1041 | 1040 | ||
| 1042 | wm5110->core.arizona = arizona; | 1041 | wm5110->core.arizona = arizona; |
| 1042 | wm5110->core.num_inputs = 8; | ||
| 1043 | 1043 | ||
| 1044 | for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) | 1044 | for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) |
| 1045 | wm5110->fll[i].vco_mult = 3; | 1045 | wm5110->fll[i].vco_mult = 3; |
diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h index 75e9351ccab0..e6c0cd4235c5 100644 --- a/sound/soc/codecs/wm5110.h +++ b/sound/soc/codecs/wm5110.h | |||
| @@ -15,7 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | #include "arizona.h" | 16 | #include "arizona.h" |
| 17 | 17 | ||
| 18 | #define WM5110_FLL1 1 | 18 | #define WM5110_FLL1 1 |
| 19 | #define WM5110_FLL2 2 | 19 | #define WM5110_FLL2 2 |
| 20 | #define WM5110_FLL1_REFCLK 3 | ||
| 21 | #define WM5110_FLL2_REFCLK 4 | ||
| 20 | 22 | ||
| 21 | #endif | 23 | #endif |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 34f2905f0158..3470b649c0b2 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | #include <linux/mfd/arizona/registers.h> | 32 | #include <linux/mfd/arizona/registers.h> |
| 33 | 33 | ||
| 34 | #include "arizona.h" | ||
| 34 | #include "wm_adsp.h" | 35 | #include "wm_adsp.h" |
| 35 | 36 | ||
| 36 | #define adsp_crit(_dsp, fmt, ...) \ | 37 | #define adsp_crit(_dsp, fmt, ...) \ |
| @@ -254,17 +255,52 @@ static const struct soc_enum wm_adsp_fw_enum[] = { | |||
| 254 | SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), | 255 | SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), |
| 255 | }; | 256 | }; |
| 256 | 257 | ||
| 257 | const struct snd_kcontrol_new wm_adsp_fw_controls[] = { | 258 | const struct snd_kcontrol_new wm_adsp1_fw_controls[] = { |
| 258 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], | 259 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], |
| 259 | wm_adsp_fw_get, wm_adsp_fw_put), | 260 | wm_adsp_fw_get, wm_adsp_fw_put), |
| 260 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], | 261 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], |
| 261 | wm_adsp_fw_get, wm_adsp_fw_put), | 262 | wm_adsp_fw_get, wm_adsp_fw_put), |
| 262 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], | 263 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], |
| 263 | wm_adsp_fw_get, wm_adsp_fw_put), | 264 | wm_adsp_fw_get, wm_adsp_fw_put), |
| 265 | }; | ||
| 266 | EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); | ||
| 267 | |||
| 268 | #if IS_ENABLED(CONFIG_SND_SOC_ARIZONA) | ||
| 269 | static const struct soc_enum wm_adsp2_rate_enum[] = { | ||
| 270 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, | ||
| 271 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
| 272 | ARIZONA_RATE_ENUM_SIZE, | ||
| 273 | arizona_rate_text, arizona_rate_val), | ||
| 274 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1, | ||
| 275 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
| 276 | ARIZONA_RATE_ENUM_SIZE, | ||
| 277 | arizona_rate_text, arizona_rate_val), | ||
| 278 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, | ||
| 279 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
| 280 | ARIZONA_RATE_ENUM_SIZE, | ||
| 281 | arizona_rate_text, arizona_rate_val), | ||
| 282 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, | ||
| 283 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
| 284 | ARIZONA_RATE_ENUM_SIZE, | ||
| 285 | arizona_rate_text, arizona_rate_val), | ||
| 286 | }; | ||
| 287 | |||
| 288 | const struct snd_kcontrol_new wm_adsp2_fw_controls[] = { | ||
| 289 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], | ||
| 290 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
| 291 | SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), | ||
| 292 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], | ||
| 293 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
| 294 | SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), | ||
| 295 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], | ||
| 296 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
| 297 | SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), | ||
| 264 | SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], | 298 | SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], |
| 265 | wm_adsp_fw_get, wm_adsp_fw_put), | 299 | wm_adsp_fw_get, wm_adsp_fw_put), |
| 300 | SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), | ||
| 266 | }; | 301 | }; |
| 267 | EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); | 302 | EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls); |
| 303 | #endif | ||
| 268 | 304 | ||
| 269 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, | 305 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, |
| 270 | int type) | 306 | int type) |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index d6fd8af53b5d..fea514627526 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
| @@ -67,7 +67,8 @@ struct wm_adsp { | |||
| 67 | .shift = num, .event = wm_adsp2_event, \ | 67 | .shift = num, .event = wm_adsp2_event, \ |
| 68 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | 68 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } |
| 69 | 69 | ||
| 70 | extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; | 70 | extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; |
| 71 | extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; | ||
| 71 | 72 | ||
| 72 | int wm_adsp1_init(struct wm_adsp *adsp); | 73 | int wm_adsp1_init(struct wm_adsp *adsp); |
| 73 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); | 74 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); |
