diff options
author | Mark Brown <broonie@linaro.org> | 2013-06-30 07:42:24 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-30 07:42:24 -0400 |
commit | 233d6a903e5efd1eb4d4ee245ab79c12d2f8df73 (patch) | |
tree | edb72ae5443deac4e8546d11581e62731c65968f /sound | |
parent | e4ca49d5d832c3eff23a44aacf21387629b1207b (diff) | |
parent | a975873a9acc0788c1aee5ca183deb420b5c00e5 (diff) |
Merge remote-tracking branch 'asoc/topic/tas5086' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/tas5086.c | 330 |
1 files changed, 326 insertions, 4 deletions
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index d447c4aa1d5e..6d31d88f7204 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c | |||
@@ -83,6 +83,14 @@ | |||
83 | #define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ | 83 | #define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ |
84 | #define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ | 84 | #define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ |
85 | #define TAS5086_BKNDERR 0x1c | 85 | #define TAS5086_BKNDERR 0x1c |
86 | #define TAS5086_INPUT_MUX 0x20 | ||
87 | #define TAS5086_PWM_OUTPUT_MUX 0x25 | ||
88 | |||
89 | #define TAS5086_MAX_REGISTER TAS5086_PWM_OUTPUT_MUX | ||
90 | |||
91 | #define TAS5086_PWM_START_MIDZ_FOR_START_1 (1 << 7) | ||
92 | #define TAS5086_PWM_START_MIDZ_FOR_START_2 (1 << 6) | ||
93 | #define TAS5086_PWM_START_CHANNEL_MASK (0x3f) | ||
86 | 94 | ||
87 | /* | 95 | /* |
88 | * Default TAS5086 power-up configuration | 96 | * Default TAS5086 power-up configuration |
@@ -119,9 +127,30 @@ static const struct reg_default tas5086_reg_defaults[] = { | |||
119 | { 0x1c, 0x05 }, | 127 | { 0x1c, 0x05 }, |
120 | }; | 128 | }; |
121 | 129 | ||
130 | static int tas5086_register_size(struct device *dev, unsigned int reg) | ||
131 | { | ||
132 | switch (reg) { | ||
133 | case TAS5086_CLOCK_CONTROL ... TAS5086_BKNDERR: | ||
134 | return 1; | ||
135 | case TAS5086_INPUT_MUX: | ||
136 | case TAS5086_PWM_OUTPUT_MUX: | ||
137 | return 4; | ||
138 | } | ||
139 | |||
140 | dev_err(dev, "Unsupported register address: %d\n", reg); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
122 | static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) | 144 | static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) |
123 | { | 145 | { |
124 | return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); | 146 | switch (reg) { |
147 | case 0x0f: | ||
148 | case 0x11 ... 0x17: | ||
149 | case 0x1d ... 0x1f: | ||
150 | return false; | ||
151 | default: | ||
152 | return true; | ||
153 | } | ||
125 | } | 154 | } |
126 | 155 | ||
127 | static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) | 156 | static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) |
@@ -140,6 +169,76 @@ static bool tas5086_writeable_reg(struct device *dev, unsigned int reg) | |||
140 | return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); | 169 | return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); |
141 | } | 170 | } |
142 | 171 | ||
172 | static int tas5086_reg_write(void *context, unsigned int reg, | ||
173 | unsigned int value) | ||
174 | { | ||
175 | struct i2c_client *client = context; | ||
176 | unsigned int i, size; | ||
177 | uint8_t buf[5]; | ||
178 | int ret; | ||
179 | |||
180 | size = tas5086_register_size(&client->dev, reg); | ||
181 | if (size == 0) | ||
182 | return -EINVAL; | ||
183 | |||
184 | buf[0] = reg; | ||
185 | |||
186 | for (i = size; i >= 1; --i) { | ||
187 | buf[i] = value; | ||
188 | value >>= 8; | ||
189 | } | ||
190 | |||
191 | ret = i2c_master_send(client, buf, size + 1); | ||
192 | if (ret == size + 1) | ||
193 | return 0; | ||
194 | else if (ret < 0) | ||
195 | return ret; | ||
196 | else | ||
197 | return -EIO; | ||
198 | } | ||
199 | |||
200 | static int tas5086_reg_read(void *context, unsigned int reg, | ||
201 | unsigned int *value) | ||
202 | { | ||
203 | struct i2c_client *client = context; | ||
204 | uint8_t send_buf, recv_buf[4]; | ||
205 | struct i2c_msg msgs[2]; | ||
206 | unsigned int size; | ||
207 | unsigned int i; | ||
208 | int ret; | ||
209 | |||
210 | size = tas5086_register_size(&client->dev, reg); | ||
211 | if (size == 0) | ||
212 | return -EINVAL; | ||
213 | |||
214 | send_buf = reg; | ||
215 | |||
216 | msgs[0].addr = client->addr; | ||
217 | msgs[0].len = sizeof(send_buf); | ||
218 | msgs[0].buf = &send_buf; | ||
219 | msgs[0].flags = 0; | ||
220 | |||
221 | msgs[1].addr = client->addr; | ||
222 | msgs[1].len = size; | ||
223 | msgs[1].buf = recv_buf; | ||
224 | msgs[1].flags = I2C_M_RD; | ||
225 | |||
226 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
227 | if (ret < 0) | ||
228 | return ret; | ||
229 | else if (ret != ARRAY_SIZE(msgs)) | ||
230 | return -EIO; | ||
231 | |||
232 | *value = 0; | ||
233 | |||
234 | for (i = 0; i < size; i++) { | ||
235 | *value <<= 8; | ||
236 | *value |= recv_buf[i]; | ||
237 | } | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
143 | struct tas5086_private { | 242 | struct tas5086_private { |
144 | struct regmap *regmap; | 243 | struct regmap *regmap; |
145 | unsigned int mclk, sclk; | 244 | unsigned int mclk, sclk; |
@@ -376,6 +475,202 @@ static const struct snd_kcontrol_new tas5086_controls[] = { | |||
376 | tas5086_get_deemph, tas5086_put_deemph), | 475 | tas5086_get_deemph, tas5086_put_deemph), |
377 | }; | 476 | }; |
378 | 477 | ||
478 | /* Input mux controls */ | ||
479 | static const char *tas5086_dapm_sdin_texts[] = | ||
480 | { | ||
481 | "SDIN1-L", "SDIN1-R", "SDIN2-L", "SDIN2-R", | ||
482 | "SDIN3-L", "SDIN3-R", "Ground (0)", "nc" | ||
483 | }; | ||
484 | |||
485 | static const struct soc_enum tas5086_dapm_input_mux_enum[] = { | ||
486 | SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 20, 8, tas5086_dapm_sdin_texts), | ||
487 | SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 16, 8, tas5086_dapm_sdin_texts), | ||
488 | SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 12, 8, tas5086_dapm_sdin_texts), | ||
489 | SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 8, 8, tas5086_dapm_sdin_texts), | ||
490 | SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 4, 8, tas5086_dapm_sdin_texts), | ||
491 | SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 0, 8, tas5086_dapm_sdin_texts), | ||
492 | }; | ||
493 | |||
494 | static const struct snd_kcontrol_new tas5086_dapm_input_mux_controls[] = { | ||
495 | SOC_DAPM_ENUM("Channel 1 input", tas5086_dapm_input_mux_enum[0]), | ||
496 | SOC_DAPM_ENUM("Channel 2 input", tas5086_dapm_input_mux_enum[1]), | ||
497 | SOC_DAPM_ENUM("Channel 3 input", tas5086_dapm_input_mux_enum[2]), | ||
498 | SOC_DAPM_ENUM("Channel 4 input", tas5086_dapm_input_mux_enum[3]), | ||
499 | SOC_DAPM_ENUM("Channel 5 input", tas5086_dapm_input_mux_enum[4]), | ||
500 | SOC_DAPM_ENUM("Channel 6 input", tas5086_dapm_input_mux_enum[5]), | ||
501 | }; | ||
502 | |||
503 | /* Output mux controls */ | ||
504 | static const char *tas5086_dapm_channel_texts[] = | ||
505 | { "Channel 1 Mux", "Channel 2 Mux", "Channel 3 Mux", | ||
506 | "Channel 4 Mux", "Channel 5 Mux", "Channel 6 Mux" }; | ||
507 | |||
508 | static const struct soc_enum tas5086_dapm_output_mux_enum[] = { | ||
509 | SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 20, 6, tas5086_dapm_channel_texts), | ||
510 | SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 16, 6, tas5086_dapm_channel_texts), | ||
511 | SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 12, 6, tas5086_dapm_channel_texts), | ||
512 | SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 8, 6, tas5086_dapm_channel_texts), | ||
513 | SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 4, 6, tas5086_dapm_channel_texts), | ||
514 | SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 0, 6, tas5086_dapm_channel_texts), | ||
515 | }; | ||
516 | |||
517 | static const struct snd_kcontrol_new tas5086_dapm_output_mux_controls[] = { | ||
518 | SOC_DAPM_ENUM("PWM1 Output", tas5086_dapm_output_mux_enum[0]), | ||
519 | SOC_DAPM_ENUM("PWM2 Output", tas5086_dapm_output_mux_enum[1]), | ||
520 | SOC_DAPM_ENUM("PWM3 Output", tas5086_dapm_output_mux_enum[2]), | ||
521 | SOC_DAPM_ENUM("PWM4 Output", tas5086_dapm_output_mux_enum[3]), | ||
522 | SOC_DAPM_ENUM("PWM5 Output", tas5086_dapm_output_mux_enum[4]), | ||
523 | SOC_DAPM_ENUM("PWM6 Output", tas5086_dapm_output_mux_enum[5]), | ||
524 | }; | ||
525 | |||
526 | static const struct snd_soc_dapm_widget tas5086_dapm_widgets[] = { | ||
527 | SND_SOC_DAPM_INPUT("SDIN1-L"), | ||
528 | SND_SOC_DAPM_INPUT("SDIN1-R"), | ||
529 | SND_SOC_DAPM_INPUT("SDIN2-L"), | ||
530 | SND_SOC_DAPM_INPUT("SDIN2-R"), | ||
531 | SND_SOC_DAPM_INPUT("SDIN3-L"), | ||
532 | SND_SOC_DAPM_INPUT("SDIN3-R"), | ||
533 | SND_SOC_DAPM_INPUT("SDIN4-L"), | ||
534 | SND_SOC_DAPM_INPUT("SDIN4-R"), | ||
535 | |||
536 | SND_SOC_DAPM_OUTPUT("PWM1"), | ||
537 | SND_SOC_DAPM_OUTPUT("PWM2"), | ||
538 | SND_SOC_DAPM_OUTPUT("PWM3"), | ||
539 | SND_SOC_DAPM_OUTPUT("PWM4"), | ||
540 | SND_SOC_DAPM_OUTPUT("PWM5"), | ||
541 | SND_SOC_DAPM_OUTPUT("PWM6"), | ||
542 | |||
543 | SND_SOC_DAPM_MUX("Channel 1 Mux", SND_SOC_NOPM, 0, 0, | ||
544 | &tas5086_dapm_input_mux_controls[0]), | ||
545 | SND_SOC_DAPM_MUX("Channel 2 Mux", SND_SOC_NOPM, 0, 0, | ||
546 | &tas5086_dapm_input_mux_controls[1]), | ||
547 | SND_SOC_DAPM_MUX("Channel 3 Mux", SND_SOC_NOPM, 0, 0, | ||
548 | &tas5086_dapm_input_mux_controls[2]), | ||
549 | SND_SOC_DAPM_MUX("Channel 4 Mux", SND_SOC_NOPM, 0, 0, | ||
550 | &tas5086_dapm_input_mux_controls[3]), | ||
551 | SND_SOC_DAPM_MUX("Channel 5 Mux", SND_SOC_NOPM, 0, 0, | ||
552 | &tas5086_dapm_input_mux_controls[4]), | ||
553 | SND_SOC_DAPM_MUX("Channel 6 Mux", SND_SOC_NOPM, 0, 0, | ||
554 | &tas5086_dapm_input_mux_controls[5]), | ||
555 | |||
556 | SND_SOC_DAPM_MUX("PWM1 Mux", SND_SOC_NOPM, 0, 0, | ||
557 | &tas5086_dapm_output_mux_controls[0]), | ||
558 | SND_SOC_DAPM_MUX("PWM2 Mux", SND_SOC_NOPM, 0, 0, | ||
559 | &tas5086_dapm_output_mux_controls[1]), | ||
560 | SND_SOC_DAPM_MUX("PWM3 Mux", SND_SOC_NOPM, 0, 0, | ||
561 | &tas5086_dapm_output_mux_controls[2]), | ||
562 | SND_SOC_DAPM_MUX("PWM4 Mux", SND_SOC_NOPM, 0, 0, | ||
563 | &tas5086_dapm_output_mux_controls[3]), | ||
564 | SND_SOC_DAPM_MUX("PWM5 Mux", SND_SOC_NOPM, 0, 0, | ||
565 | &tas5086_dapm_output_mux_controls[4]), | ||
566 | SND_SOC_DAPM_MUX("PWM6 Mux", SND_SOC_NOPM, 0, 0, | ||
567 | &tas5086_dapm_output_mux_controls[5]), | ||
568 | }; | ||
569 | |||
570 | static const struct snd_soc_dapm_route tas5086_dapm_routes[] = { | ||
571 | /* SDIN inputs -> channel muxes */ | ||
572 | { "Channel 1 Mux", "SDIN1-L", "SDIN1-L" }, | ||
573 | { "Channel 1 Mux", "SDIN1-R", "SDIN1-R" }, | ||
574 | { "Channel 1 Mux", "SDIN2-L", "SDIN2-L" }, | ||
575 | { "Channel 1 Mux", "SDIN2-R", "SDIN2-R" }, | ||
576 | { "Channel 1 Mux", "SDIN3-L", "SDIN3-L" }, | ||
577 | { "Channel 1 Mux", "SDIN3-R", "SDIN3-R" }, | ||
578 | |||
579 | { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" }, | ||
580 | { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" }, | ||
581 | { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" }, | ||
582 | { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" }, | ||
583 | { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" }, | ||
584 | { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" }, | ||
585 | |||
586 | { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" }, | ||
587 | { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" }, | ||
588 | { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" }, | ||
589 | { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" }, | ||
590 | { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" }, | ||
591 | { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" }, | ||
592 | |||
593 | { "Channel 3 Mux", "SDIN1-L", "SDIN1-L" }, | ||
594 | { "Channel 3 Mux", "SDIN1-R", "SDIN1-R" }, | ||
595 | { "Channel 3 Mux", "SDIN2-L", "SDIN2-L" }, | ||
596 | { "Channel 3 Mux", "SDIN2-R", "SDIN2-R" }, | ||
597 | { "Channel 3 Mux", "SDIN3-L", "SDIN3-L" }, | ||
598 | { "Channel 3 Mux", "SDIN3-R", "SDIN3-R" }, | ||
599 | |||
600 | { "Channel 4 Mux", "SDIN1-L", "SDIN1-L" }, | ||
601 | { "Channel 4 Mux", "SDIN1-R", "SDIN1-R" }, | ||
602 | { "Channel 4 Mux", "SDIN2-L", "SDIN2-L" }, | ||
603 | { "Channel 4 Mux", "SDIN2-R", "SDIN2-R" }, | ||
604 | { "Channel 4 Mux", "SDIN3-L", "SDIN3-L" }, | ||
605 | { "Channel 4 Mux", "SDIN3-R", "SDIN3-R" }, | ||
606 | |||
607 | { "Channel 5 Mux", "SDIN1-L", "SDIN1-L" }, | ||
608 | { "Channel 5 Mux", "SDIN1-R", "SDIN1-R" }, | ||
609 | { "Channel 5 Mux", "SDIN2-L", "SDIN2-L" }, | ||
610 | { "Channel 5 Mux", "SDIN2-R", "SDIN2-R" }, | ||
611 | { "Channel 5 Mux", "SDIN3-L", "SDIN3-L" }, | ||
612 | { "Channel 5 Mux", "SDIN3-R", "SDIN3-R" }, | ||
613 | |||
614 | { "Channel 6 Mux", "SDIN1-L", "SDIN1-L" }, | ||
615 | { "Channel 6 Mux", "SDIN1-R", "SDIN1-R" }, | ||
616 | { "Channel 6 Mux", "SDIN2-L", "SDIN2-L" }, | ||
617 | { "Channel 6 Mux", "SDIN2-R", "SDIN2-R" }, | ||
618 | { "Channel 6 Mux", "SDIN3-L", "SDIN3-L" }, | ||
619 | { "Channel 6 Mux", "SDIN3-R", "SDIN3-R" }, | ||
620 | |||
621 | /* Channel muxes -> PWM muxes */ | ||
622 | { "PWM1 Mux", "Channel 1 Mux", "Channel 1 Mux" }, | ||
623 | { "PWM2 Mux", "Channel 1 Mux", "Channel 1 Mux" }, | ||
624 | { "PWM3 Mux", "Channel 1 Mux", "Channel 1 Mux" }, | ||
625 | { "PWM4 Mux", "Channel 1 Mux", "Channel 1 Mux" }, | ||
626 | { "PWM5 Mux", "Channel 1 Mux", "Channel 1 Mux" }, | ||
627 | { "PWM6 Mux", "Channel 1 Mux", "Channel 1 Mux" }, | ||
628 | |||
629 | { "PWM1 Mux", "Channel 2 Mux", "Channel 2 Mux" }, | ||
630 | { "PWM2 Mux", "Channel 2 Mux", "Channel 2 Mux" }, | ||
631 | { "PWM3 Mux", "Channel 2 Mux", "Channel 2 Mux" }, | ||
632 | { "PWM4 Mux", "Channel 2 Mux", "Channel 2 Mux" }, | ||
633 | { "PWM5 Mux", "Channel 2 Mux", "Channel 2 Mux" }, | ||
634 | { "PWM6 Mux", "Channel 2 Mux", "Channel 2 Mux" }, | ||
635 | |||
636 | { "PWM1 Mux", "Channel 3 Mux", "Channel 3 Mux" }, | ||
637 | { "PWM2 Mux", "Channel 3 Mux", "Channel 3 Mux" }, | ||
638 | { "PWM3 Mux", "Channel 3 Mux", "Channel 3 Mux" }, | ||
639 | { "PWM4 Mux", "Channel 3 Mux", "Channel 3 Mux" }, | ||
640 | { "PWM5 Mux", "Channel 3 Mux", "Channel 3 Mux" }, | ||
641 | { "PWM6 Mux", "Channel 3 Mux", "Channel 3 Mux" }, | ||
642 | |||
643 | { "PWM1 Mux", "Channel 4 Mux", "Channel 4 Mux" }, | ||
644 | { "PWM2 Mux", "Channel 4 Mux", "Channel 4 Mux" }, | ||
645 | { "PWM3 Mux", "Channel 4 Mux", "Channel 4 Mux" }, | ||
646 | { "PWM4 Mux", "Channel 4 Mux", "Channel 4 Mux" }, | ||
647 | { "PWM5 Mux", "Channel 4 Mux", "Channel 4 Mux" }, | ||
648 | { "PWM6 Mux", "Channel 4 Mux", "Channel 4 Mux" }, | ||
649 | |||
650 | { "PWM1 Mux", "Channel 5 Mux", "Channel 5 Mux" }, | ||
651 | { "PWM2 Mux", "Channel 5 Mux", "Channel 5 Mux" }, | ||
652 | { "PWM3 Mux", "Channel 5 Mux", "Channel 5 Mux" }, | ||
653 | { "PWM4 Mux", "Channel 5 Mux", "Channel 5 Mux" }, | ||
654 | { "PWM5 Mux", "Channel 5 Mux", "Channel 5 Mux" }, | ||
655 | { "PWM6 Mux", "Channel 5 Mux", "Channel 5 Mux" }, | ||
656 | |||
657 | { "PWM1 Mux", "Channel 6 Mux", "Channel 6 Mux" }, | ||
658 | { "PWM2 Mux", "Channel 6 Mux", "Channel 6 Mux" }, | ||
659 | { "PWM3 Mux", "Channel 6 Mux", "Channel 6 Mux" }, | ||
660 | { "PWM4 Mux", "Channel 6 Mux", "Channel 6 Mux" }, | ||
661 | { "PWM5 Mux", "Channel 6 Mux", "Channel 6 Mux" }, | ||
662 | { "PWM6 Mux", "Channel 6 Mux", "Channel 6 Mux" }, | ||
663 | |||
664 | /* The PWM muxes are directly connected to the PWM outputs */ | ||
665 | { "PWM1", NULL, "PWM1 Mux" }, | ||
666 | { "PWM2", NULL, "PWM2 Mux" }, | ||
667 | { "PWM3", NULL, "PWM3 Mux" }, | ||
668 | { "PWM4", NULL, "PWM4 Mux" }, | ||
669 | { "PWM5", NULL, "PWM5 Mux" }, | ||
670 | { "PWM6", NULL, "PWM6 Mux" }, | ||
671 | |||
672 | }; | ||
673 | |||
379 | static const struct snd_soc_dai_ops tas5086_dai_ops = { | 674 | static const struct snd_soc_dai_ops tas5086_dai_ops = { |
380 | .hw_params = tas5086_hw_params, | 675 | .hw_params = tas5086_hw_params, |
381 | .set_sysclk = tas5086_set_dai_sysclk, | 676 | .set_sysclk = tas5086_set_dai_sysclk, |
@@ -426,13 +721,34 @@ static int tas5086_probe(struct snd_soc_codec *codec) | |||
426 | { | 721 | { |
427 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | 722 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); |
428 | int charge_period = 1300000; /* hardware default is 1300 ms */ | 723 | int charge_period = 1300000; /* hardware default is 1300 ms */ |
724 | u8 pwm_start_mid_z = 0; | ||
429 | int i, ret; | 725 | int i, ret; |
430 | 726 | ||
431 | if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) { | 727 | if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) { |
432 | struct device_node *of_node = codec->dev->of_node; | 728 | struct device_node *of_node = codec->dev->of_node; |
433 | of_property_read_u32(of_node, "ti,charge-period", &charge_period); | 729 | of_property_read_u32(of_node, "ti,charge-period", &charge_period); |
730 | |||
731 | for (i = 0; i < 6; i++) { | ||
732 | char name[25]; | ||
733 | |||
734 | snprintf(name, sizeof(name), | ||
735 | "ti,mid-z-channel-%d", i + 1); | ||
736 | |||
737 | if (of_get_property(of_node, name, NULL) != NULL) | ||
738 | pwm_start_mid_z |= 1 << i; | ||
739 | } | ||
434 | } | 740 | } |
435 | 741 | ||
742 | /* | ||
743 | * If any of the channels is configured to start in Mid-Z mode, | ||
744 | * configure 'part 1' of the PWM starts to use Mid-Z, and tell | ||
745 | * all configured mid-z channels to start start under 'part 1'. | ||
746 | */ | ||
747 | if (pwm_start_mid_z) | ||
748 | regmap_write(priv->regmap, TAS5086_PWM_START, | ||
749 | TAS5086_PWM_START_MIDZ_FOR_START_1 | | ||
750 | pwm_start_mid_z); | ||
751 | |||
436 | /* lookup and set split-capacitor charge period */ | 752 | /* lookup and set split-capacitor charge period */ |
437 | if (charge_period == 0) { | 753 | if (charge_period == 0) { |
438 | regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); | 754 | regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); |
@@ -490,6 +806,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { | |||
490 | .resume = tas5086_soc_resume, | 806 | .resume = tas5086_soc_resume, |
491 | .controls = tas5086_controls, | 807 | .controls = tas5086_controls, |
492 | .num_controls = ARRAY_SIZE(tas5086_controls), | 808 | .num_controls = ARRAY_SIZE(tas5086_controls), |
809 | .dapm_widgets = tas5086_dapm_widgets, | ||
810 | .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), | ||
811 | .dapm_routes = tas5086_dapm_routes, | ||
812 | .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), | ||
493 | }; | 813 | }; |
494 | 814 | ||
495 | static const struct i2c_device_id tas5086_i2c_id[] = { | 815 | static const struct i2c_device_id tas5086_i2c_id[] = { |
@@ -500,14 +820,16 @@ MODULE_DEVICE_TABLE(i2c, tas5086_i2c_id); | |||
500 | 820 | ||
501 | static const struct regmap_config tas5086_regmap = { | 821 | static const struct regmap_config tas5086_regmap = { |
502 | .reg_bits = 8, | 822 | .reg_bits = 8, |
503 | .val_bits = 8, | 823 | .val_bits = 32, |
504 | .max_register = ARRAY_SIZE(tas5086_reg_defaults), | 824 | .max_register = TAS5086_MAX_REGISTER, |
505 | .reg_defaults = tas5086_reg_defaults, | 825 | .reg_defaults = tas5086_reg_defaults, |
506 | .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), | 826 | .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), |
507 | .cache_type = REGCACHE_RBTREE, | 827 | .cache_type = REGCACHE_RBTREE, |
508 | .volatile_reg = tas5086_volatile_reg, | 828 | .volatile_reg = tas5086_volatile_reg, |
509 | .writeable_reg = tas5086_writeable_reg, | 829 | .writeable_reg = tas5086_writeable_reg, |
510 | .readable_reg = tas5086_accessible_reg, | 830 | .readable_reg = tas5086_accessible_reg, |
831 | .reg_read = tas5086_reg_read, | ||
832 | .reg_write = tas5086_reg_write, | ||
511 | }; | 833 | }; |
512 | 834 | ||
513 | static int tas5086_i2c_probe(struct i2c_client *i2c, | 835 | static int tas5086_i2c_probe(struct i2c_client *i2c, |
@@ -522,7 +844,7 @@ static int tas5086_i2c_probe(struct i2c_client *i2c, | |||
522 | if (!priv) | 844 | if (!priv) |
523 | return -ENOMEM; | 845 | return -ENOMEM; |
524 | 846 | ||
525 | priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap); | 847 | priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap); |
526 | if (IS_ERR(priv->regmap)) { | 848 | if (IS_ERR(priv->regmap)) { |
527 | ret = PTR_ERR(priv->regmap); | 849 | ret = PTR_ERR(priv->regmap); |
528 | dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); | 850 | dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); |