| .. | .. |
|---|
| 44 | 44 | #include <sound/tlv.h> |
|---|
| 45 | 45 | |
|---|
| 46 | 46 | #include "rk3308_codec.h" |
|---|
| 47 | | -#include "rk3308_codec_provider.h" |
|---|
| 48 | 47 | |
|---|
| 49 | 48 | #if defined(CONFIG_DEBUG_FS) |
|---|
| 50 | 49 | #include <linux/fs.h> |
|---|
| .. | .. |
|---|
| 96 | 95 | |
|---|
| 97 | 96 | #define ACODEC_VERSION_A 0xa |
|---|
| 98 | 97 | #define ACODEC_VERSION_B 0xb |
|---|
| 98 | +#define ACODEC_VERSION_C 0xc |
|---|
| 99 | 99 | |
|---|
| 100 | 100 | enum { |
|---|
| 101 | 101 | ACODEC_TO_I2S2_8CH = 0, |
|---|
| .. | .. |
|---|
| 194 | 194 | int ext_micbias; |
|---|
| 195 | 195 | int pm_state; |
|---|
| 196 | 196 | |
|---|
| 197 | | - /* AGC L/R Off/on */ |
|---|
| 198 | | - unsigned int agc_l[ADC_LR_GROUP_MAX]; |
|---|
| 199 | | - unsigned int agc_r[ADC_LR_GROUP_MAX]; |
|---|
| 200 | | - |
|---|
| 201 | | - /* AGC L/R Approximate Sample Rate */ |
|---|
| 202 | | - unsigned int agc_asr_l[ADC_LR_GROUP_MAX]; |
|---|
| 203 | | - unsigned int agc_asr_r[ADC_LR_GROUP_MAX]; |
|---|
| 204 | | - |
|---|
| 205 | 197 | /* ADC MIC Mute/Work */ |
|---|
| 206 | 198 | unsigned int mic_mute_l[ADC_LR_GROUP_MAX]; |
|---|
| 207 | 199 | unsigned int mic_mute_r[ADC_LR_GROUP_MAX]; |
|---|
| .. | .. |
|---|
| 232 | 224 | #endif |
|---|
| 233 | 225 | }; |
|---|
| 234 | 226 | |
|---|
| 235 | | -static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_gain_tlv, |
|---|
| 236 | | - -1800, 150, 2850); |
|---|
| 237 | | -static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_max_gain_tlv, |
|---|
| 238 | | - -1350, 600, 2850); |
|---|
| 239 | | -static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_min_gain_tlv, |
|---|
| 240 | | - -1800, 600, 2400); |
|---|
| 241 | 227 | static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv, |
|---|
| 242 | 228 | -1800, 150, 2850); |
|---|
| 243 | 229 | static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_lineout_gain_tlv, |
|---|
| .. | .. |
|---|
| 263 | 249 | |
|---|
| 264 | 250 | static int check_micbias(int micbias); |
|---|
| 265 | 251 | |
|---|
| 252 | +static void rk3308_codec_dac_mclk_enable(struct rk3308_codec_priv *rk3308); |
|---|
| 253 | + |
|---|
| 266 | 254 | static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308, |
|---|
| 267 | 255 | int micbias); |
|---|
| 268 | 256 | static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308); |
|---|
| .. | .. |
|---|
| 279 | 267 | struct snd_ctl_elem_value *ucontrol); |
|---|
| 280 | 268 | static int rk3308_codec_hpf_put(struct snd_kcontrol *kcontrol, |
|---|
| 281 | 269 | struct snd_ctl_elem_value *ucontrol); |
|---|
| 282 | | -static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol, |
|---|
| 283 | | - struct snd_ctl_elem_value *ucontrol); |
|---|
| 284 | | -static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol, |
|---|
| 285 | | - struct snd_ctl_elem_value *ucontrol); |
|---|
| 286 | | -static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol, |
|---|
| 287 | | - struct snd_ctl_elem_value *ucontrol); |
|---|
| 288 | | -static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol, |
|---|
| 289 | | - struct snd_ctl_elem_value *ucontrol); |
|---|
| 290 | 270 | static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol, |
|---|
| 291 | 271 | struct snd_ctl_elem_value *ucontrol); |
|---|
| 292 | 272 | static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol, |
|---|
| .. | .. |
|---|
| 353 | 333 | SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 354 | 334 | }; |
|---|
| 355 | 335 | |
|---|
| 356 | | -/* ALC AGC Switch */ |
|---|
| 357 | | -static const struct soc_enum rk3308_agc_enum_array[] = { |
|---|
| 358 | | - SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 359 | | - SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 360 | | - SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 361 | | - SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 362 | | - SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 363 | | - SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 364 | | - SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 365 | | - SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(offon_text), offon_text), |
|---|
| 366 | | -}; |
|---|
| 367 | | - |
|---|
| 368 | 336 | /* ADC MIC Mute/Work Switch */ |
|---|
| 369 | 337 | static const struct soc_enum rk3308_mic_mute_enum_array[] = { |
|---|
| 370 | 338 | SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(mute_text), mute_text), |
|---|
| .. | .. |
|---|
| 375 | 343 | SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(mute_text), mute_text), |
|---|
| 376 | 344 | SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(mute_text), mute_text), |
|---|
| 377 | 345 | SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(mute_text), mute_text), |
|---|
| 378 | | -}; |
|---|
| 379 | | - |
|---|
| 380 | | -/* ALC AGC Approximate Sample Rate */ |
|---|
| 381 | | -#define AGC_ASR_NUM 8 |
|---|
| 382 | | - |
|---|
| 383 | | -#define AGC_ASR_96KHZ 0 |
|---|
| 384 | | -#define AGC_ASR_48KHZ 1 |
|---|
| 385 | | -#define AGC_ASR_44_1KHZ 2 |
|---|
| 386 | | -#define AGC_ASR_32KHZ 3 |
|---|
| 387 | | -#define AGC_ASR_24KHZ 4 |
|---|
| 388 | | -#define AGC_ASR_16KHZ 5 |
|---|
| 389 | | -#define AGC_ASR_12KHZ 6 |
|---|
| 390 | | -#define AGC_ASR_8KHZ 7 |
|---|
| 391 | | - |
|---|
| 392 | | -static const char *agc_asr_text[AGC_ASR_NUM] = { |
|---|
| 393 | | - [AGC_ASR_96KHZ] = "96KHz", |
|---|
| 394 | | - [AGC_ASR_48KHZ] = "48KHz", |
|---|
| 395 | | - [AGC_ASR_44_1KHZ] = "44.1KHz", |
|---|
| 396 | | - [AGC_ASR_32KHZ] = "32KHz", |
|---|
| 397 | | - [AGC_ASR_24KHZ] = "24KHz", |
|---|
| 398 | | - [AGC_ASR_16KHZ] = "16KHz", |
|---|
| 399 | | - [AGC_ASR_12KHZ] = "12KHz", |
|---|
| 400 | | - [AGC_ASR_8KHZ] = "8KHz", |
|---|
| 401 | | -}; |
|---|
| 402 | | - |
|---|
| 403 | | -static const struct soc_enum rk3308_agc_asr_enum_array[] = { |
|---|
| 404 | | - SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 405 | | - SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 406 | | - SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 407 | | - SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 408 | | - SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 409 | | - SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 410 | | - SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 411 | | - SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text), |
|---|
| 412 | 346 | }; |
|---|
| 413 | 347 | |
|---|
| 414 | 348 | static const struct snd_kcontrol_new mic_gains_a[] = { |
|---|
| .. | .. |
|---|
| 548 | 482 | }; |
|---|
| 549 | 483 | |
|---|
| 550 | 484 | static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = { |
|---|
| 551 | | - /* ALC AGC Group */ |
|---|
| 552 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Volume", |
|---|
| 553 | | - RK3308_ALC_L_DIG_CON03(0), |
|---|
| 554 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 555 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 556 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 557 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 558 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Volume", |
|---|
| 559 | | - RK3308_ALC_R_DIG_CON03(0), |
|---|
| 560 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 561 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 562 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 563 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 564 | | - |
|---|
| 565 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Volume", |
|---|
| 566 | | - RK3308_ALC_L_DIG_CON03(1), |
|---|
| 567 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 568 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 569 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 570 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 571 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Volume", |
|---|
| 572 | | - RK3308_ALC_R_DIG_CON03(1), |
|---|
| 573 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 574 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 575 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 576 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 577 | | - |
|---|
| 578 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Volume", |
|---|
| 579 | | - RK3308_ALC_L_DIG_CON03(2), |
|---|
| 580 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 581 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 582 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 583 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 584 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Volume", |
|---|
| 585 | | - RK3308_ALC_R_DIG_CON03(2), |
|---|
| 586 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 587 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 588 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 589 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 590 | | - |
|---|
| 591 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Volume", |
|---|
| 592 | | - RK3308_ALC_L_DIG_CON03(3), |
|---|
| 593 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 594 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 595 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 596 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 597 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Volume", |
|---|
| 598 | | - RK3308_ALC_R_DIG_CON03(3), |
|---|
| 599 | | - RK3308_AGC_PGA_GAIN_SFT, |
|---|
| 600 | | - RK3308_AGC_PGA_GAIN_MIN, |
|---|
| 601 | | - RK3308_AGC_PGA_GAIN_MAX, |
|---|
| 602 | | - 0, rk3308_codec_alc_agc_grp_gain_tlv), |
|---|
| 603 | | - |
|---|
| 604 | | - /* ALC AGC MAX */ |
|---|
| 605 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Max Volume", |
|---|
| 606 | | - RK3308_ALC_L_DIG_CON09(0), |
|---|
| 607 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 608 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 609 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 610 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 611 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Max Volume", |
|---|
| 612 | | - RK3308_ALC_R_DIG_CON09(0), |
|---|
| 613 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 614 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 615 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 616 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 617 | | - |
|---|
| 618 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Max Volume", |
|---|
| 619 | | - RK3308_ALC_L_DIG_CON09(1), |
|---|
| 620 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 621 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 622 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 623 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 624 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Max Volume", |
|---|
| 625 | | - RK3308_ALC_R_DIG_CON09(1), |
|---|
| 626 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 627 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 628 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 629 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 630 | | - |
|---|
| 631 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Max Volume", |
|---|
| 632 | | - RK3308_ALC_L_DIG_CON09(2), |
|---|
| 633 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 634 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 635 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 636 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 637 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Max Volume", |
|---|
| 638 | | - RK3308_ALC_R_DIG_CON09(2), |
|---|
| 639 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 640 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 641 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 642 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 643 | | - |
|---|
| 644 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Max Volume", |
|---|
| 645 | | - RK3308_ALC_L_DIG_CON09(3), |
|---|
| 646 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 647 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 648 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 649 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 650 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Max Volume", |
|---|
| 651 | | - RK3308_ALC_R_DIG_CON09(3), |
|---|
| 652 | | - RK3308_AGC_MAX_GAIN_PGA_SFT, |
|---|
| 653 | | - RK3308_AGC_MAX_GAIN_PGA_MIN, |
|---|
| 654 | | - RK3308_AGC_MAX_GAIN_PGA_MAX, |
|---|
| 655 | | - 0, rk3308_codec_alc_agc_grp_max_gain_tlv), |
|---|
| 656 | | - |
|---|
| 657 | | - /* ALC AGC MIN */ |
|---|
| 658 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Min Volume", |
|---|
| 659 | | - RK3308_ALC_L_DIG_CON09(0), |
|---|
| 660 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 661 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 662 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 663 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 664 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Min Volume", |
|---|
| 665 | | - RK3308_ALC_R_DIG_CON09(0), |
|---|
| 666 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 667 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 668 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 669 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 670 | | - |
|---|
| 671 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Min Volume", |
|---|
| 672 | | - RK3308_ALC_L_DIG_CON09(1), |
|---|
| 673 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 674 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 675 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 676 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 677 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Min Volume", |
|---|
| 678 | | - RK3308_ALC_R_DIG_CON09(1), |
|---|
| 679 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 680 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 681 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 682 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 683 | | - |
|---|
| 684 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Min Volume", |
|---|
| 685 | | - RK3308_ALC_L_DIG_CON09(2), |
|---|
| 686 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 687 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 688 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 689 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 690 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Min Volume", |
|---|
| 691 | | - RK3308_ALC_R_DIG_CON09(2), |
|---|
| 692 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 693 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 694 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 695 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 696 | | - |
|---|
| 697 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Min Volume", |
|---|
| 698 | | - RK3308_ALC_L_DIG_CON09(3), |
|---|
| 699 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 700 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 701 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 702 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 703 | | - SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Min Volume", |
|---|
| 704 | | - RK3308_ALC_R_DIG_CON09(3), |
|---|
| 705 | | - RK3308_AGC_MIN_GAIN_PGA_SFT, |
|---|
| 706 | | - RK3308_AGC_MIN_GAIN_PGA_MIN, |
|---|
| 707 | | - RK3308_AGC_MIN_GAIN_PGA_MAX, |
|---|
| 708 | | - 0, rk3308_codec_alc_agc_grp_min_gain_tlv), |
|---|
| 709 | | - |
|---|
| 710 | | - /* ALC AGC Switch */ |
|---|
| 711 | | - SOC_ENUM_EXT("ALC AGC Group 0 Left Switch", rk3308_agc_enum_array[0], |
|---|
| 712 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 713 | | - SOC_ENUM_EXT("ALC AGC Group 0 Right Switch", rk3308_agc_enum_array[1], |
|---|
| 714 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 715 | | - SOC_ENUM_EXT("ALC AGC Group 1 Left Switch", rk3308_agc_enum_array[2], |
|---|
| 716 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 717 | | - SOC_ENUM_EXT("ALC AGC Group 1 Right Switch", rk3308_agc_enum_array[3], |
|---|
| 718 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 719 | | - SOC_ENUM_EXT("ALC AGC Group 2 Left Switch", rk3308_agc_enum_array[4], |
|---|
| 720 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 721 | | - SOC_ENUM_EXT("ALC AGC Group 2 Right Switch", rk3308_agc_enum_array[5], |
|---|
| 722 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 723 | | - SOC_ENUM_EXT("ALC AGC Group 3 Left Switch", rk3308_agc_enum_array[6], |
|---|
| 724 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 725 | | - SOC_ENUM_EXT("ALC AGC Group 3 Right Switch", rk3308_agc_enum_array[7], |
|---|
| 726 | | - rk3308_codec_agc_get, rk3308_codec_agc_put), |
|---|
| 727 | | - |
|---|
| 728 | | - /* ALC AGC Approximate Sample Rate */ |
|---|
| 729 | | - SOC_ENUM_EXT("AGC Group 0 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[0], |
|---|
| 730 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 731 | | - SOC_ENUM_EXT("AGC Group 0 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[1], |
|---|
| 732 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 733 | | - SOC_ENUM_EXT("AGC Group 1 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[2], |
|---|
| 734 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 735 | | - SOC_ENUM_EXT("AGC Group 1 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[3], |
|---|
| 736 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 737 | | - SOC_ENUM_EXT("AGC Group 2 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[4], |
|---|
| 738 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 739 | | - SOC_ENUM_EXT("AGC Group 2 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[5], |
|---|
| 740 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 741 | | - SOC_ENUM_EXT("AGC Group 3 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[6], |
|---|
| 742 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 743 | | - SOC_ENUM_EXT("AGC Group 3 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[7], |
|---|
| 744 | | - rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put), |
|---|
| 745 | | - |
|---|
| 746 | 485 | /* ADC MICBIAS Voltage */ |
|---|
| 747 | 486 | SOC_ENUM_EXT("ADC MICBIAS Voltage", rk3308_micbias_volts_enum_array[0], |
|---|
| 748 | 487 | rk3308_codec_micbias_volts_get, rk3308_codec_micbias_volts_put), |
|---|
| .. | .. |
|---|
| 879 | 618 | RK3308_DAC_R_HPMIX_GAIN_MAX, |
|---|
| 880 | 619 | 0, rk3308_codec_dac_hpmix_gain_tlv), |
|---|
| 881 | 620 | }; |
|---|
| 882 | | - |
|---|
| 883 | | -static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol, |
|---|
| 884 | | - struct snd_ctl_elem_value *ucontrol) |
|---|
| 885 | | -{ |
|---|
| 886 | | - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
|---|
| 887 | | - struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); |
|---|
| 888 | | - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
|---|
| 889 | | - |
|---|
| 890 | | - if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { |
|---|
| 891 | | - dev_err(rk3308->plat_dev, |
|---|
| 892 | | - "%s: Invalid ADC grp: %d\n", __func__, e->reg); |
|---|
| 893 | | - return -EINVAL; |
|---|
| 894 | | - } |
|---|
| 895 | | - |
|---|
| 896 | | - if (e->shift_l) |
|---|
| 897 | | - ucontrol->value.integer.value[0] = rk3308->agc_r[e->reg]; |
|---|
| 898 | | - else |
|---|
| 899 | | - ucontrol->value.integer.value[0] = rk3308->agc_l[e->reg]; |
|---|
| 900 | | - |
|---|
| 901 | | - return 0; |
|---|
| 902 | | -} |
|---|
| 903 | | - |
|---|
| 904 | | -static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol, |
|---|
| 905 | | - struct snd_ctl_elem_value *ucontrol) |
|---|
| 906 | | -{ |
|---|
| 907 | | - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
|---|
| 908 | | - struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); |
|---|
| 909 | | - |
|---|
| 910 | | - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
|---|
| 911 | | - unsigned int value = ucontrol->value.integer.value[0]; |
|---|
| 912 | | - int grp = e->reg; |
|---|
| 913 | | - |
|---|
| 914 | | - if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { |
|---|
| 915 | | - dev_err(rk3308->plat_dev, |
|---|
| 916 | | - "%s: Invalid ADC grp: %d\n", __func__, e->reg); |
|---|
| 917 | | - return -EINVAL; |
|---|
| 918 | | - } |
|---|
| 919 | | - |
|---|
| 920 | | - if (value) { |
|---|
| 921 | | - /* ALC AGC On */ |
|---|
| 922 | | - if (e->shift_l) { |
|---|
| 923 | | - /* ALC AGC Right On */ |
|---|
| 924 | | - regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp), |
|---|
| 925 | | - RK3308_AGC_FUNC_SEL_MSK, |
|---|
| 926 | | - RK3308_AGC_FUNC_SEL_EN); |
|---|
| 927 | | - regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), |
|---|
| 928 | | - RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, |
|---|
| 929 | | - RK3308_ADC_ALCR_CON_GAIN_PGAR_EN); |
|---|
| 930 | | - |
|---|
| 931 | | - rk3308->agc_r[e->reg] = 1; |
|---|
| 932 | | - } else { |
|---|
| 933 | | - /* ALC AGC Left On */ |
|---|
| 934 | | - regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp), |
|---|
| 935 | | - RK3308_AGC_FUNC_SEL_MSK, |
|---|
| 936 | | - RK3308_AGC_FUNC_SEL_EN); |
|---|
| 937 | | - regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), |
|---|
| 938 | | - RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK, |
|---|
| 939 | | - RK3308_ADC_ALCL_CON_GAIN_PGAL_EN); |
|---|
| 940 | | - |
|---|
| 941 | | - rk3308->agc_l[e->reg] = 1; |
|---|
| 942 | | - } |
|---|
| 943 | | - } else { |
|---|
| 944 | | - /* ALC AGC Off */ |
|---|
| 945 | | - if (e->shift_l) { |
|---|
| 946 | | - /* ALC AGC Right Off */ |
|---|
| 947 | | - regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp), |
|---|
| 948 | | - RK3308_AGC_FUNC_SEL_MSK, |
|---|
| 949 | | - RK3308_AGC_FUNC_SEL_DIS); |
|---|
| 950 | | - regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), |
|---|
| 951 | | - RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK, |
|---|
| 952 | | - RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS); |
|---|
| 953 | | - |
|---|
| 954 | | - rk3308->agc_r[e->reg] = 0; |
|---|
| 955 | | - } else { |
|---|
| 956 | | - /* ALC AGC Left Off */ |
|---|
| 957 | | - regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp), |
|---|
| 958 | | - RK3308_AGC_FUNC_SEL_MSK, |
|---|
| 959 | | - RK3308_AGC_FUNC_SEL_DIS); |
|---|
| 960 | | - regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp), |
|---|
| 961 | | - RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK, |
|---|
| 962 | | - RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS); |
|---|
| 963 | | - |
|---|
| 964 | | - rk3308->agc_l[e->reg] = 0; |
|---|
| 965 | | - } |
|---|
| 966 | | - } |
|---|
| 967 | | - |
|---|
| 968 | | - return 0; |
|---|
| 969 | | -} |
|---|
| 970 | | - |
|---|
| 971 | | -static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol, |
|---|
| 972 | | - struct snd_ctl_elem_value *ucontrol) |
|---|
| 973 | | -{ |
|---|
| 974 | | - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
|---|
| 975 | | - struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); |
|---|
| 976 | | - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
|---|
| 977 | | - unsigned int value; |
|---|
| 978 | | - int grp = e->reg; |
|---|
| 979 | | - |
|---|
| 980 | | - if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { |
|---|
| 981 | | - dev_err(rk3308->plat_dev, |
|---|
| 982 | | - "%s: Invalid ADC grp: %d\n", __func__, e->reg); |
|---|
| 983 | | - return -EINVAL; |
|---|
| 984 | | - } |
|---|
| 985 | | - |
|---|
| 986 | | - if (e->shift_l) { |
|---|
| 987 | | - regmap_read(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp), &value); |
|---|
| 988 | | - rk3308->agc_asr_r[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT; |
|---|
| 989 | | - ucontrol->value.integer.value[0] = rk3308->agc_asr_r[e->reg]; |
|---|
| 990 | | - } else { |
|---|
| 991 | | - regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp), &value); |
|---|
| 992 | | - rk3308->agc_asr_l[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT; |
|---|
| 993 | | - ucontrol->value.integer.value[0] = rk3308->agc_asr_l[e->reg]; |
|---|
| 994 | | - } |
|---|
| 995 | | - |
|---|
| 996 | | - return 0; |
|---|
| 997 | | -} |
|---|
| 998 | | - |
|---|
| 999 | | -static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol, |
|---|
| 1000 | | - struct snd_ctl_elem_value *ucontrol) |
|---|
| 1001 | | -{ |
|---|
| 1002 | | - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
|---|
| 1003 | | - struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); |
|---|
| 1004 | | - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
|---|
| 1005 | | - unsigned int value; |
|---|
| 1006 | | - int grp = e->reg; |
|---|
| 1007 | | - |
|---|
| 1008 | | - if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) { |
|---|
| 1009 | | - dev_err(rk3308->plat_dev, |
|---|
| 1010 | | - "%s: Invalid ADC grp: %d\n", __func__, e->reg); |
|---|
| 1011 | | - return -EINVAL; |
|---|
| 1012 | | - } |
|---|
| 1013 | | - |
|---|
| 1014 | | - value = ucontrol->value.integer.value[0] << RK3308_AGC_APPROX_RATE_SFT; |
|---|
| 1015 | | - |
|---|
| 1016 | | - if (e->shift_l) { |
|---|
| 1017 | | - /* ALC AGC Right Approximate Sample Rate */ |
|---|
| 1018 | | - regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp), |
|---|
| 1019 | | - RK3308_AGC_APPROX_RATE_MSK, |
|---|
| 1020 | | - value); |
|---|
| 1021 | | - rk3308->agc_asr_r[e->reg] = ucontrol->value.integer.value[0]; |
|---|
| 1022 | | - } else { |
|---|
| 1023 | | - /* ALC AGC Left Approximate Sample Rate */ |
|---|
| 1024 | | - regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp), |
|---|
| 1025 | | - RK3308_AGC_APPROX_RATE_MSK, |
|---|
| 1026 | | - value); |
|---|
| 1027 | | - rk3308->agc_asr_l[e->reg] = ucontrol->value.integer.value[0]; |
|---|
| 1028 | | - } |
|---|
| 1029 | | - |
|---|
| 1030 | | - return 0; |
|---|
| 1031 | | -} |
|---|
| 1032 | 621 | |
|---|
| 1033 | 622 | static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol, |
|---|
| 1034 | 623 | struct snd_ctl_elem_value *ucontrol) |
|---|
| .. | .. |
|---|
| 1487 | 1076 | case SND_SOC_DAIFMT_CBS_CFS: |
|---|
| 1488 | 1077 | adc_aif2 |= RK3308_ADC_IO_MODE_SLAVE; |
|---|
| 1489 | 1078 | adc_aif2 |= RK3308_ADC_MODE_SLAVE; |
|---|
| 1490 | | - dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE; |
|---|
| 1491 | | - dac_aif2 |= RK3308_DAC_MODE_SLAVE; |
|---|
| 1079 | + if (rk3308->codec_ver == ACODEC_VERSION_C) { |
|---|
| 1080 | + dac_aif2 |= RK3308BS_DAC_IO_MODE_SLAVE; |
|---|
| 1081 | + dac_aif2 |= RK3308BS_DAC_MODE_SLAVE; |
|---|
| 1082 | + } else { |
|---|
| 1083 | + dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE; |
|---|
| 1084 | + dac_aif2 |= RK3308_DAC_MODE_SLAVE; |
|---|
| 1085 | + } |
|---|
| 1492 | 1086 | is_master = 0; |
|---|
| 1493 | 1087 | break; |
|---|
| 1494 | 1088 | case SND_SOC_DAIFMT_CBM_CFM: |
|---|
| 1495 | 1089 | adc_aif2 |= RK3308_ADC_IO_MODE_MASTER; |
|---|
| 1496 | 1090 | adc_aif2 |= RK3308_ADC_MODE_MASTER; |
|---|
| 1497 | | - dac_aif2 |= RK3308_DAC_IO_MODE_MASTER; |
|---|
| 1498 | | - dac_aif2 |= RK3308_DAC_MODE_MASTER; |
|---|
| 1091 | + if (rk3308->codec_ver == ACODEC_VERSION_C) { |
|---|
| 1092 | + dac_aif2 |= RK3308BS_DAC_IO_MODE_MASTER; |
|---|
| 1093 | + dac_aif2 |= RK3308BS_DAC_MODE_MASTER; |
|---|
| 1094 | + } else { |
|---|
| 1095 | + dac_aif2 |= RK3308_DAC_IO_MODE_MASTER; |
|---|
| 1096 | + dac_aif2 |= RK3308_DAC_MODE_MASTER; |
|---|
| 1097 | + } |
|---|
| 1499 | 1098 | is_master = 1; |
|---|
| 1500 | 1099 | break; |
|---|
| 1501 | 1100 | default: |
|---|
| .. | .. |
|---|
| 1589 | 1188 | RK3308_DAC_I2S_LRC_POL_MSK | |
|---|
| 1590 | 1189 | RK3308_DAC_I2S_MODE_MSK, |
|---|
| 1591 | 1190 | dac_aif1); |
|---|
| 1592 | | - regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, |
|---|
| 1191 | + if (rk3308->codec_ver == ACODEC_VERSION_C) { |
|---|
| 1192 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, |
|---|
| 1193 | + RK3308BS_DAC_IO_MODE_MSK | |
|---|
| 1194 | + RK3308BS_DAC_MODE_MSK | |
|---|
| 1195 | + RK3308_DAC_I2S_BIT_CLK_POL_MSK, |
|---|
| 1196 | + dac_aif2); |
|---|
| 1197 | + } else { |
|---|
| 1198 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, |
|---|
| 1593 | 1199 | RK3308_DAC_IO_MODE_MSK | |
|---|
| 1594 | 1200 | RK3308_DAC_MODE_MSK | |
|---|
| 1595 | 1201 | RK3308_DAC_I2S_BIT_CLK_POL_MSK, |
|---|
| 1596 | 1202 | dac_aif2); |
|---|
| 1203 | + } |
|---|
| 1597 | 1204 | |
|---|
| 1598 | 1205 | return 0; |
|---|
| 1599 | 1206 | } |
|---|
| .. | .. |
|---|
| 1729 | 1336 | int dgain; |
|---|
| 1730 | 1337 | |
|---|
| 1731 | 1338 | if (mute) { |
|---|
| 1732 | | - for (dgain = 0x2; dgain <= 0x7; dgain++) { |
|---|
| 1733 | | - /* |
|---|
| 1734 | | - * Keep the max -> min digital CIC interpolation |
|---|
| 1735 | | - * filter gain step by step. |
|---|
| 1736 | | - * |
|---|
| 1737 | | - * loud: 0x2; whisper: 0x7 |
|---|
| 1738 | | - */ |
|---|
| 1739 | | - regmap_update_bits(rk3308->regmap, |
|---|
| 1740 | | - RK3308_DAC_DIG_CON04, |
|---|
| 1741 | | - RK3308_DAC_CIC_IF_GAIN_MSK, |
|---|
| 1742 | | - dgain); |
|---|
| 1743 | | - usleep_range(200, 300); /* estimated value */ |
|---|
| 1339 | + if (rk3308->codec_ver <= ACODEC_VERSION_B) { |
|---|
| 1340 | + for (dgain = 0x2; dgain <= 0x7; dgain++) { |
|---|
| 1341 | + /* |
|---|
| 1342 | + * Keep the max -> min digital CIC interpolation |
|---|
| 1343 | + * filter gain step by step. |
|---|
| 1344 | + * |
|---|
| 1345 | + * loud: 0x2; whisper: 0x7 |
|---|
| 1346 | + */ |
|---|
| 1347 | + regmap_update_bits(rk3308->regmap, |
|---|
| 1348 | + RK3308_DAC_DIG_CON04, |
|---|
| 1349 | + RK3308_DAC_CIC_IF_GAIN_MSK, |
|---|
| 1350 | + dgain); |
|---|
| 1351 | + usleep_range(200, 300); /* estimated value */ |
|---|
| 1352 | + } |
|---|
| 1744 | 1353 | } |
|---|
| 1745 | 1354 | |
|---|
| 1746 | 1355 | #if !DEBUG_POP_ALWAYS |
|---|
| .. | .. |
|---|
| 1757 | 1366 | if (rk3308->delay_start_play_ms) |
|---|
| 1758 | 1367 | msleep(rk3308->delay_start_play_ms); |
|---|
| 1759 | 1368 | #endif |
|---|
| 1760 | | - for (dgain = 0x7; dgain >= 0x2; dgain--) { |
|---|
| 1761 | | - /* |
|---|
| 1762 | | - * Keep the min -> max digital CIC interpolation |
|---|
| 1763 | | - * filter gain step by step |
|---|
| 1764 | | - * |
|---|
| 1765 | | - * loud: 0x2; whisper: 0x7 |
|---|
| 1766 | | - */ |
|---|
| 1767 | | - regmap_update_bits(rk3308->regmap, |
|---|
| 1768 | | - RK3308_DAC_DIG_CON04, |
|---|
| 1769 | | - RK3308_DAC_CIC_IF_GAIN_MSK, |
|---|
| 1770 | | - dgain); |
|---|
| 1771 | | - usleep_range(200, 300); /* estimated value */ |
|---|
| 1369 | + if (rk3308->codec_ver <= ACODEC_VERSION_B) { |
|---|
| 1370 | + for (dgain = 0x7; dgain >= 0x2; dgain--) { |
|---|
| 1371 | + /* |
|---|
| 1372 | + * Keep the min -> max digital CIC interpolation |
|---|
| 1373 | + * filter gain step by step |
|---|
| 1374 | + * |
|---|
| 1375 | + * loud: 0x2; whisper: 0x7 |
|---|
| 1376 | + */ |
|---|
| 1377 | + regmap_update_bits(rk3308->regmap, |
|---|
| 1378 | + RK3308_DAC_DIG_CON04, |
|---|
| 1379 | + RK3308_DAC_CIC_IF_GAIN_MSK, |
|---|
| 1380 | + dgain); |
|---|
| 1381 | + usleep_range(200, 300); /* estimated value */ |
|---|
| 1382 | + } |
|---|
| 1772 | 1383 | } |
|---|
| 1773 | 1384 | } |
|---|
| 1774 | 1385 | } |
|---|
| .. | .. |
|---|
| 1856 | 1467 | |
|---|
| 1857 | 1468 | static int rk3308_codec_dac_lineout_enable(struct rk3308_codec_priv *rk3308) |
|---|
| 1858 | 1469 | { |
|---|
| 1470 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, |
|---|
| 1471 | + RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | |
|---|
| 1472 | + RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, |
|---|
| 1473 | + RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL | |
|---|
| 1474 | + RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL); |
|---|
| 1475 | + |
|---|
| 1476 | + udelay(20); |
|---|
| 1477 | + |
|---|
| 1859 | 1478 | /* Step 07 */ |
|---|
| 1860 | 1479 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, |
|---|
| 1861 | 1480 | RK3308_DAC_L_LINEOUT_EN | |
|---|
| .. | .. |
|---|
| 1892 | 1511 | RK3308_DAC_L_LINEOUT_DIS | |
|---|
| 1893 | 1512 | RK3308_DAC_R_LINEOUT_DIS); |
|---|
| 1894 | 1513 | |
|---|
| 1514 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, |
|---|
| 1515 | + RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | |
|---|
| 1516 | + RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, |
|---|
| 1517 | + RK3308_DAC_L_SEL_DC_FROM_INTERNAL | |
|---|
| 1518 | + RK3308_DAC_R_SEL_DC_FROM_INTERNAL); |
|---|
| 1519 | + |
|---|
| 1895 | 1520 | return 0; |
|---|
| 1896 | 1521 | } |
|---|
| 1897 | 1522 | |
|---|
| 1898 | 1523 | static int rk3308_codec_dac_hpout_enable(struct rk3308_codec_priv *rk3308) |
|---|
| 1899 | 1524 | { |
|---|
| 1525 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, |
|---|
| 1526 | + RK3308_DAC_HPOUT_POP_SOUND_L_MSK | |
|---|
| 1527 | + RK3308_DAC_HPOUT_POP_SOUND_R_MSK, |
|---|
| 1528 | + RK3308_DAC_HPOUT_POP_SOUND_L_WORK | |
|---|
| 1529 | + RK3308_DAC_HPOUT_POP_SOUND_R_WORK); |
|---|
| 1900 | 1530 | udelay(20); |
|---|
| 1901 | 1531 | |
|---|
| 1902 | 1532 | /* Step 07 */ |
|---|
| .. | .. |
|---|
| 1952 | 1582 | RK3308_DAC_L_HPOUT_MUTE | |
|---|
| 1953 | 1583 | RK3308_DAC_R_HPOUT_MUTE); |
|---|
| 1954 | 1584 | |
|---|
| 1585 | + udelay(20); |
|---|
| 1586 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, |
|---|
| 1587 | + RK3308_DAC_HPOUT_POP_SOUND_L_MSK | |
|---|
| 1588 | + RK3308_DAC_HPOUT_POP_SOUND_R_MSK, |
|---|
| 1589 | + RK3308_DAC_HPOUT_POP_SOUND_L_DIS | |
|---|
| 1590 | + RK3308_DAC_HPOUT_POP_SOUND_R_DIS); |
|---|
| 1955 | 1591 | return 0; |
|---|
| 1956 | 1592 | } |
|---|
| 1957 | 1593 | |
|---|
| .. | .. |
|---|
| 2075 | 1711 | |
|---|
| 2076 | 1712 | udelay(20); |
|---|
| 2077 | 1713 | |
|---|
| 2078 | | - if (rk3308->codec_ver == ACODEC_VERSION_B && |
|---|
| 1714 | + if (rk3308->codec_ver >= ACODEC_VERSION_B && |
|---|
| 2079 | 1715 | (rk3308->dac_output == DAC_LINEOUT || |
|---|
| 2080 | 1716 | rk3308->dac_output == DAC_LINEOUT_HPOUT)) { |
|---|
| 2081 | 1717 | /* Step 04 */ |
|---|
| .. | .. |
|---|
| 2146 | 1782 | udelay(20); |
|---|
| 2147 | 1783 | } |
|---|
| 2148 | 1784 | |
|---|
| 2149 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 1785 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2150 | 1786 | /* Step 10 */ |
|---|
| 2151 | | - regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, |
|---|
| 1787 | + if (rk3308->dac_output == DAC_HPOUT) { |
|---|
| 1788 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, |
|---|
| 1789 | + RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | |
|---|
| 1790 | + RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, |
|---|
| 1791 | + RK3308_DAC_L_SEL_DC_FROM_INTERNAL | |
|---|
| 1792 | + RK3308_DAC_R_SEL_DC_FROM_INTERNAL); |
|---|
| 1793 | + } else { |
|---|
| 1794 | + /* LINEOUT and LINEOUT + HPOUT */ |
|---|
| 1795 | + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, |
|---|
| 2152 | 1796 | RK3308_DAC_LINEOUT_POP_SOUND_L_MSK | |
|---|
| 2153 | 1797 | RK3308_DAC_LINEOUT_POP_SOUND_R_MSK, |
|---|
| 2154 | 1798 | RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL | |
|---|
| 2155 | 1799 | RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL); |
|---|
| 1800 | + } |
|---|
| 2156 | 1801 | |
|---|
| 2157 | 1802 | udelay(20); |
|---|
| 2158 | 1803 | } |
|---|
| .. | .. |
|---|
| 2352 | 1997 | RK3308_DAC_HPOUT_POP_SOUND_R_INIT); |
|---|
| 2353 | 1998 | |
|---|
| 2354 | 1999 | /* Step 15 */ |
|---|
| 2355 | | - if (rk3308->codec_ver == ACODEC_VERSION_B && |
|---|
| 2000 | + if (rk3308->codec_ver >= ACODEC_VERSION_B && |
|---|
| 2356 | 2001 | (rk3308->dac_output == DAC_LINEOUT || |
|---|
| 2357 | 2002 | rk3308->dac_output == DAC_LINEOUT_HPOUT)) { |
|---|
| 2358 | 2003 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15, |
|---|
| .. | .. |
|---|
| 2422 | 2067 | RK3308_DAC_HPOUT_POP_SOUND_R_MSK, |
|---|
| 2423 | 2068 | RK3308_DAC_HPOUT_POP_SOUND_R_INIT); |
|---|
| 2424 | 2069 | |
|---|
| 2425 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2070 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2426 | 2071 | /* |
|---|
| 2427 | 2072 | * 2. Configure ACODEC_DAC_ANA_CON15[1:0] and |
|---|
| 2428 | 2073 | * ACODEC_DAC_ANA_CON15[5:4] to 0x1, to setup dc voltage of |
|---|
| .. | .. |
|---|
| 2443 | 2088 | RK3308_ADC_CURRENT_CHARGE_MSK, |
|---|
| 2444 | 2089 | RK3308_ADC_SEL_I(0x1)); |
|---|
| 2445 | 2090 | |
|---|
| 2446 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2091 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2447 | 2092 | /* |
|---|
| 2448 | 2093 | * 4. Configure the register ACODEC_ADC_ANA_CON14[3:0] to |
|---|
| 2449 | 2094 | * 4’b0001. |
|---|
| .. | .. |
|---|
| 2462 | 2107 | regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), |
|---|
| 2463 | 2108 | RK3308_ADC_REF_EN, RK3308_ADC_REF_EN); |
|---|
| 2464 | 2109 | |
|---|
| 2465 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2110 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2466 | 2111 | /* |
|---|
| 2467 | 2112 | * 7. Configure the register ACODEC_ADC_ANA_CON14[4] to 0x1 to |
|---|
| 2468 | 2113 | * setup reference voltage |
|---|
| .. | .. |
|---|
| 2484 | 2129 | udelay(200); |
|---|
| 2485 | 2130 | } |
|---|
| 2486 | 2131 | |
|---|
| 2487 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2132 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2488 | 2133 | /* |
|---|
| 2489 | 2134 | * 9. Change the register ACODEC_ADC_ANA_CON14[3:0] from the 0x1 |
|---|
| 2490 | 2135 | * to 0xf step by step or configure the |
|---|
| .. | .. |
|---|
| 2509 | 2154 | regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), |
|---|
| 2510 | 2155 | RK3308_ADC_CURRENT_CHARGE_MSK, 0x7c); |
|---|
| 2511 | 2156 | |
|---|
| 2512 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2157 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2513 | 2158 | /* |
|---|
| 2514 | 2159 | * 12. Configure the register ACODEC_DAC_ANA_CON14[6:0] to the |
|---|
| 2515 | 2160 | * appropriate value(expect 0x0) for reducing power. |
|---|
| 2516 | 2161 | */ |
|---|
| 2517 | 2162 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, |
|---|
| 2518 | 2163 | RK3308_DAC_CURRENT_CHARGE_MSK, 0xf); |
|---|
| 2164 | + } |
|---|
| 2165 | + |
|---|
| 2166 | + if (rk3308->codec_ver == ACODEC_VERSION_C) { |
|---|
| 2167 | + /* Using large driver strength for HPOUT and LINEOUT */ |
|---|
| 2168 | + regmap_write(rk3308->regmap, RK3308_DAC_ANA_CON07, 0x11); |
|---|
| 2169 | + regmap_write(rk3308->regmap, RK3308_DAC_ANA_CON08, 0x11); |
|---|
| 2519 | 2170 | } |
|---|
| 2520 | 2171 | |
|---|
| 2521 | 2172 | return 0; |
|---|
| .. | .. |
|---|
| 2537 | 2188 | RK3308_ADC_CURRENT_CHARGE_MSK, |
|---|
| 2538 | 2189 | RK3308_ADC_SEL_I(0x1)); |
|---|
| 2539 | 2190 | |
|---|
| 2540 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2191 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2541 | 2192 | /* |
|---|
| 2542 | 2193 | * 2. Configure the register ACODEC_DAC_ANA_CON14[3:0] to |
|---|
| 2543 | 2194 | * 4’b0001. |
|---|
| .. | .. |
|---|
| 2552 | 2203 | RK3308_ADC_REF_EN, |
|---|
| 2553 | 2204 | RK3308_ADC_REF_DIS); |
|---|
| 2554 | 2205 | |
|---|
| 2555 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2206 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2556 | 2207 | /* 4. Configure the register ACODEC_DAC_ANA_CON14[7] to 0x0 */ |
|---|
| 2557 | 2208 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14, |
|---|
| 2558 | 2209 | RK3308_DAC_VCM_LINEOUT_EN, |
|---|
| .. | .. |
|---|
| 2571 | 2222 | udelay(200); |
|---|
| 2572 | 2223 | } |
|---|
| 2573 | 2224 | |
|---|
| 2574 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 2225 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 2575 | 2226 | /* |
|---|
| 2576 | 2227 | * 6. Change the register ACODEC_DAC_ANA_CON14[3:0] from the 0x1 |
|---|
| 2577 | 2228 | * to 0xf step by step or configure the |
|---|
| .. | .. |
|---|
| 2600 | 2251 | |
|---|
| 2601 | 2252 | static int rk3308_codec_headset_detect_enable(struct rk3308_codec_priv *rk3308) |
|---|
| 2602 | 2253 | { |
|---|
| 2254 | + if (rk3308->codec_ver == ACODEC_VERSION_C) |
|---|
| 2255 | + rk3308_codec_dac_mclk_enable(rk3308); |
|---|
| 2256 | + |
|---|
| 2603 | 2257 | /* |
|---|
| 2604 | 2258 | * Set ACODEC_DAC_ANA_CON0[1] to 0x1, to enable the headset insert |
|---|
| 2605 | 2259 | * detection |
|---|
| .. | .. |
|---|
| 2792 | 2446 | static bool handle_loopback(struct rk3308_codec_priv *rk3308) |
|---|
| 2793 | 2447 | { |
|---|
| 2794 | 2448 | /* The version B doesn't need to handle loopback. */ |
|---|
| 2795 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) |
|---|
| 2449 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) |
|---|
| 2796 | 2450 | return false; |
|---|
| 2797 | 2451 | |
|---|
| 2798 | 2452 | switch (rk3308->loopback_grp) { |
|---|
| .. | .. |
|---|
| 3426 | 3080 | |
|---|
| 3427 | 3081 | static void rk3308_codec_dac_mclk_disable(struct rk3308_codec_priv *rk3308) |
|---|
| 3428 | 3082 | { |
|---|
| 3083 | + if (!rk3308->no_hp_det && rk3308->codec_ver == ACODEC_VERSION_C) |
|---|
| 3084 | + return; |
|---|
| 3085 | + |
|---|
| 3429 | 3086 | regmap_update_bits(rk3308->regmap, RK3308_GLB_CON, |
|---|
| 3430 | 3087 | RK3308_DAC_MCLK_MSK, |
|---|
| 3431 | 3088 | RK3308_DAC_MCLK_DIS); |
|---|
| .. | .. |
|---|
| 3849 | 3506 | RK3308_ADC_CH2_ALC_GAIN_0DB); |
|---|
| 3850 | 3507 | } |
|---|
| 3851 | 3508 | |
|---|
| 3509 | + if (rk3308->codec_ver == ACODEC_VERSION_C) { |
|---|
| 3510 | + /* recover ADC digtial volume to 0dB */ |
|---|
| 3511 | + for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { |
|---|
| 3512 | + /* DIG_VOL: -97dB ~ +32dB */ |
|---|
| 3513 | + regmap_write(rk3308->regmap, RK3308BS_ADC_DIG_CON05(grp), |
|---|
| 3514 | + RK3308_ADC_DIG_VOL_CON_L(RK3308_ADC_DIG_VOL_0DB)); |
|---|
| 3515 | + regmap_write(rk3308->regmap, RK3308BS_ADC_DIG_CON06(grp), |
|---|
| 3516 | + RK3308_ADC_DIG_VOL_CON_R(RK3308_ADC_DIG_VOL_0DB)); |
|---|
| 3517 | + } |
|---|
| 3518 | + } |
|---|
| 3519 | + |
|---|
| 3852 | 3520 | /* Prepare DAC gains */ |
|---|
| 3853 | 3521 | /* Step 15, set HPMIX default gains */ |
|---|
| 3854 | 3522 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, |
|---|
| 3855 | 3523 | RK3308_DAC_L_HPMIX_GAIN_MSK | |
|---|
| 3856 | 3524 | RK3308_DAC_R_HPMIX_GAIN_MSK, |
|---|
| 3857 | | - RK3308_DAC_L_HPMIX_GAIN_NDB_6 | |
|---|
| 3858 | | - RK3308_DAC_R_HPMIX_GAIN_NDB_6); |
|---|
| 3525 | + RK3308_DAC_L_HPMIX_GAIN_0DB | |
|---|
| 3526 | + RK3308_DAC_R_HPMIX_GAIN_0DB); |
|---|
| 3859 | 3527 | |
|---|
| 3860 | 3528 | /* Step 18, set HPOUT default gains */ |
|---|
| 3861 | 3529 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05, |
|---|
| 3862 | 3530 | RK3308_DAC_L_HPOUT_GAIN_MSK, |
|---|
| 3863 | | - RK3308_DAC_L_HPOUT_GAIN_NDB_39); |
|---|
| 3531 | + RK3308_DAC_L_HPOUT_GAIN_0DB); |
|---|
| 3864 | 3532 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06, |
|---|
| 3865 | 3533 | RK3308_DAC_R_HPOUT_GAIN_MSK, |
|---|
| 3866 | | - RK3308_DAC_R_HPOUT_GAIN_NDB_39); |
|---|
| 3534 | + RK3308_DAC_R_HPOUT_GAIN_0DB); |
|---|
| 3867 | 3535 | |
|---|
| 3868 | 3536 | /* Using the same gain to HPOUT LR channels */ |
|---|
| 3869 | | - rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_NDB_39; |
|---|
| 3537 | + rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_0DB; |
|---|
| 3538 | + rk3308->hpout_r_dgain = RK3308_DAC_R_HPOUT_GAIN_0DB; |
|---|
| 3870 | 3539 | |
|---|
| 3871 | 3540 | /* Step 19, set LINEOUT default gains */ |
|---|
| 3872 | 3541 | regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04, |
|---|
| 3873 | 3542 | RK3308_DAC_L_LINEOUT_GAIN_MSK | |
|---|
| 3874 | 3543 | RK3308_DAC_R_LINEOUT_GAIN_MSK, |
|---|
| 3875 | | - RK3308_DAC_L_LINEOUT_GAIN_NDB_6 | |
|---|
| 3876 | | - RK3308_DAC_R_LINEOUT_GAIN_NDB_6); |
|---|
| 3544 | + RK3308_DAC_L_LINEOUT_GAIN_0DB | |
|---|
| 3545 | + RK3308_DAC_R_LINEOUT_GAIN_0DB); |
|---|
| 3546 | + |
|---|
| 3547 | + if (rk3308->codec_ver == ACODEC_VERSION_C) { |
|---|
| 3548 | + /* recover DAC digtial gain to 0dB */ |
|---|
| 3549 | + regmap_write(rk3308->regmap, RK3308BS_DAC_DIG_CON04, |
|---|
| 3550 | + RK3308BS_DAC_DIG_GAIN(RK3308BS_DAC_DIG_0DB)); |
|---|
| 3551 | + } |
|---|
| 3877 | 3552 | |
|---|
| 3878 | 3553 | return 0; |
|---|
| 3879 | 3554 | } |
|---|
| .. | .. |
|---|
| 3935 | 3610 | { |
|---|
| 3936 | 3611 | int ret; |
|---|
| 3937 | 3612 | |
|---|
| 3938 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 3613 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 3939 | 3614 | ret = snd_soc_add_component_controls(rk3308->component, |
|---|
| 3940 | 3615 | mic_gains_b, |
|---|
| 3941 | 3616 | ARRAY_SIZE(mic_gains_b)); |
|---|
| .. | .. |
|---|
| 4020 | 3695 | { |
|---|
| 4021 | 3696 | int grp; |
|---|
| 4022 | 3697 | |
|---|
| 4023 | | - for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { |
|---|
| 3698 | + for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) |
|---|
| 4024 | 3699 | rk3308->hpf_cutoff[grp] = 0; |
|---|
| 4025 | | - rk3308->agc_l[grp] = 0; |
|---|
| 4026 | | - rk3308->agc_r[grp] = 0; |
|---|
| 4027 | | - rk3308->agc_asr_l[grp] = AGC_ASR_96KHZ; |
|---|
| 4028 | | - rk3308->agc_asr_r[grp] = AGC_ASR_96KHZ; |
|---|
| 4029 | | - } |
|---|
| 4030 | 3700 | |
|---|
| 4031 | 3701 | rk3308_codec_dapm_mic_gains(rk3308); |
|---|
| 4032 | 3702 | |
|---|
| .. | .. |
|---|
| 4089 | 3759 | regcache_sync(rk3308->regmap); |
|---|
| 4090 | 3760 | } |
|---|
| 4091 | 3761 | |
|---|
| 3762 | +static int rk3308_codec_set_jack(struct snd_soc_component *component, |
|---|
| 3763 | + struct snd_soc_jack *jack, void *data) |
|---|
| 3764 | +{ |
|---|
| 3765 | + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); |
|---|
| 3766 | + |
|---|
| 3767 | + /* Return directly if the DUT don't need to support headphone detection */ |
|---|
| 3768 | + if (rk3308->no_hp_det) |
|---|
| 3769 | + return 0; |
|---|
| 3770 | + |
|---|
| 3771 | + rk3308->hpdet_jack = jack; |
|---|
| 3772 | + |
|---|
| 3773 | + /* To detect jack once during startup */ |
|---|
| 3774 | + disable_irq_nosync(rk3308->irq); |
|---|
| 3775 | + queue_delayed_work(system_power_efficient_wq, |
|---|
| 3776 | + &rk3308->hpdet_work, msecs_to_jiffies(10)); |
|---|
| 3777 | + |
|---|
| 3778 | + dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n", |
|---|
| 3779 | + __func__); |
|---|
| 3780 | + |
|---|
| 3781 | + return 0; |
|---|
| 3782 | +} |
|---|
| 3783 | + |
|---|
| 4092 | 3784 | static const struct snd_soc_component_driver soc_codec_dev_rk3308 = { |
|---|
| 4093 | 3785 | .probe = rk3308_probe, |
|---|
| 4094 | 3786 | .remove = rk3308_remove, |
|---|
| .. | .. |
|---|
| 4097 | 3789 | .set_bias_level = rk3308_set_bias_level, |
|---|
| 4098 | 3790 | .controls = rk3308_codec_dapm_controls, |
|---|
| 4099 | 3791 | .num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls), |
|---|
| 3792 | + .set_jack = rk3308_codec_set_jack, |
|---|
| 4100 | 3793 | }; |
|---|
| 4101 | 3794 | |
|---|
| 4102 | 3795 | static const struct reg_default rk3308_codec_reg_defaults[] = { |
|---|
| .. | .. |
|---|
| 4118 | 3811 | { |
|---|
| 4119 | 3812 | struct rk3308_codec_priv *rk3308 = |
|---|
| 4120 | 3813 | container_of(work, struct rk3308_codec_priv, hpdet_work.work); |
|---|
| 4121 | | - unsigned int val; |
|---|
| 3814 | + unsigned int val, headphone_con = RK3308_CODEC_HEADPHONE_CON; |
|---|
| 4122 | 3815 | int need_poll = 0, need_irq = 0; |
|---|
| 4123 | 3816 | int need_report = 0, report_type = 0; |
|---|
| 4124 | 3817 | int dac_output = DAC_LINEOUT; |
|---|
| 4125 | 3818 | |
|---|
| 4126 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 3819 | + if (rk3308->codec_ver == ACODEC_VERSION_C) |
|---|
| 3820 | + headphone_con = RK3308BS_CODEC_HEADPHONE_CON; |
|---|
| 3821 | + |
|---|
| 3822 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 4127 | 3823 | /* Check headphone plugged/unplugged directly. */ |
|---|
| 4128 | 3824 | regmap_read(rk3308->detect_grf, |
|---|
| 4129 | 3825 | DETECT_GRF_ACODEC_HPDET_STATUS, &val); |
|---|
| .. | .. |
|---|
| 4164 | 3860 | } |
|---|
| 4165 | 3861 | |
|---|
| 4166 | 3862 | /* Check headphone unplugged via poll. */ |
|---|
| 4167 | | - regmap_read(rk3308->regmap, RK3308_DAC_DIG_CON14, &val); |
|---|
| 3863 | + regmap_read(rk3308->regmap, headphone_con, &val); |
|---|
| 4168 | 3864 | |
|---|
| 4169 | 3865 | if (rk3308->hp_jack_reversed) { |
|---|
| 4170 | 3866 | if (!val) { |
|---|
| .. | .. |
|---|
| 4259 | 3955 | &rk3308->hpdet_work, msecs_to_jiffies(10)); |
|---|
| 4260 | 3956 | |
|---|
| 4261 | 3957 | return IRQ_HANDLED; |
|---|
| 4262 | | -} |
|---|
| 4263 | | - |
|---|
| 4264 | | -void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_component *component, |
|---|
| 4265 | | - struct snd_soc_jack *hpdet_jack); |
|---|
| 4266 | | -EXPORT_SYMBOL_GPL(rk3308_codec_set_jack_detect_cb); |
|---|
| 4267 | | - |
|---|
| 4268 | | -static void rk3308_codec_set_jack_detect(struct snd_soc_component *component, |
|---|
| 4269 | | - struct snd_soc_jack *hpdet_jack) |
|---|
| 4270 | | -{ |
|---|
| 4271 | | - struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); |
|---|
| 4272 | | - |
|---|
| 4273 | | - rk3308->hpdet_jack = hpdet_jack; |
|---|
| 4274 | | - |
|---|
| 4275 | | - /* To detect jack once during startup */ |
|---|
| 4276 | | - disable_irq_nosync(rk3308->irq); |
|---|
| 4277 | | - queue_delayed_work(system_power_efficient_wq, |
|---|
| 4278 | | - &rk3308->hpdet_work, msecs_to_jiffies(10)); |
|---|
| 4279 | | - |
|---|
| 4280 | | - dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n", |
|---|
| 4281 | | - __func__); |
|---|
| 4282 | 3958 | } |
|---|
| 4283 | 3959 | |
|---|
| 4284 | 3960 | static const struct regmap_config rk3308_codec_regmap_config = { |
|---|
| .. | .. |
|---|
| 4721 | 4397 | return 0; |
|---|
| 4722 | 4398 | } |
|---|
| 4723 | 4399 | |
|---|
| 4400 | +static void rk3308_codec_sysfs_exit(struct rk3308_codec_priv *rk3308) |
|---|
| 4401 | +{ |
|---|
| 4402 | + struct device *dev = &rk3308->dev; |
|---|
| 4403 | + unsigned int i; |
|---|
| 4404 | + |
|---|
| 4405 | + for (i = 0; i < ARRAY_SIZE(acodec_attrs); i++) |
|---|
| 4406 | + device_remove_file(dev, &acodec_attrs[i]); |
|---|
| 4407 | + device_unregister(dev); |
|---|
| 4408 | +} |
|---|
| 4409 | + |
|---|
| 4724 | 4410 | #if defined(CONFIG_DEBUG_FS) |
|---|
| 4725 | 4411 | static int rk3308_codec_debugfs_reg_show(struct seq_file *s, void *v) |
|---|
| 4726 | 4412 | { |
|---|
| .. | .. |
|---|
| 4808 | 4494 | case 0x3308: |
|---|
| 4809 | 4495 | rk3308->codec_ver = ACODEC_VERSION_B; |
|---|
| 4810 | 4496 | break; |
|---|
| 4497 | + case 0x3308c: |
|---|
| 4498 | + rk3308->codec_ver = ACODEC_VERSION_C; |
|---|
| 4499 | + break; |
|---|
| 4811 | 4500 | default: |
|---|
| 4812 | 4501 | pr_err("Unknown chip_id: %d / 0x%x\n", chip_id, chip_id); |
|---|
| 4813 | 4502 | return -EFAULT; |
|---|
| .. | .. |
|---|
| 4836 | 4525 | return PTR_ERR(rk3308->grf); |
|---|
| 4837 | 4526 | } |
|---|
| 4838 | 4527 | |
|---|
| 4528 | + ret = rk3308_codec_get_version(rk3308); |
|---|
| 4529 | + if (ret < 0) |
|---|
| 4530 | + return dev_err_probe(&pdev->dev, ret, "Failed to get acodec version\n"); |
|---|
| 4531 | + |
|---|
| 4839 | 4532 | ret = rk3308_codec_sysfs_init(pdev, rk3308); |
|---|
| 4840 | 4533 | if (ret < 0) { |
|---|
| 4841 | 4534 | dev_err(&pdev->dev, "Sysfs init failed\n"); |
|---|
| .. | .. |
|---|
| 4857 | 4550 | if (IS_ERR(rk3308->reset)) { |
|---|
| 4858 | 4551 | ret = PTR_ERR(rk3308->reset); |
|---|
| 4859 | 4552 | if (ret != -ENOENT) |
|---|
| 4860 | | - return ret; |
|---|
| 4553 | + goto out_sysfs; |
|---|
| 4861 | 4554 | |
|---|
| 4862 | 4555 | dev_dbg(&pdev->dev, "No reset control found\n"); |
|---|
| 4863 | 4556 | rk3308->reset = NULL; |
|---|
| .. | .. |
|---|
| 4870 | 4563 | } else if (IS_ERR(rk3308->hp_ctl_gpio)) { |
|---|
| 4871 | 4564 | ret = PTR_ERR(rk3308->hp_ctl_gpio); |
|---|
| 4872 | 4565 | dev_err(&pdev->dev, "Unable to claim gpio hp-ctl\n"); |
|---|
| 4873 | | - return ret; |
|---|
| 4566 | + goto out_sysfs; |
|---|
| 4874 | 4567 | } |
|---|
| 4875 | 4568 | |
|---|
| 4876 | 4569 | rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk-ctl", |
|---|
| .. | .. |
|---|
| 4881 | 4574 | } else if (IS_ERR(rk3308->spk_ctl_gpio)) { |
|---|
| 4882 | 4575 | ret = PTR_ERR(rk3308->spk_ctl_gpio); |
|---|
| 4883 | 4576 | dev_err(&pdev->dev, "Unable to claim gpio spk-ctl\n"); |
|---|
| 4884 | | - return ret; |
|---|
| 4577 | + goto out_sysfs; |
|---|
| 4885 | 4578 | } |
|---|
| 4886 | 4579 | |
|---|
| 4887 | 4580 | rk3308->pa_drv_gpio = devm_gpiod_get_optional(&pdev->dev, "pa-drv", |
|---|
| .. | .. |
|---|
| 4892 | 4585 | } else if (IS_ERR(rk3308->pa_drv_gpio)) { |
|---|
| 4893 | 4586 | ret = PTR_ERR(rk3308->pa_drv_gpio); |
|---|
| 4894 | 4587 | dev_err(&pdev->dev, "Unable to claim gpio pa-drv\n"); |
|---|
| 4895 | | - return ret; |
|---|
| 4588 | + goto out_sysfs; |
|---|
| 4896 | 4589 | } |
|---|
| 4897 | 4590 | |
|---|
| 4898 | 4591 | if (rk3308->pa_drv_gpio) { |
|---|
| .. | .. |
|---|
| 4914 | 4607 | rk3308->pclk = devm_clk_get(&pdev->dev, "acodec"); |
|---|
| 4915 | 4608 | if (IS_ERR(rk3308->pclk)) { |
|---|
| 4916 | 4609 | dev_err(&pdev->dev, "Can't get acodec pclk\n"); |
|---|
| 4917 | | - return PTR_ERR(rk3308->pclk); |
|---|
| 4610 | + ret = PTR_ERR(rk3308->pclk); |
|---|
| 4611 | + goto out_sysfs; |
|---|
| 4918 | 4612 | } |
|---|
| 4919 | 4613 | |
|---|
| 4920 | 4614 | rk3308->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx"); |
|---|
| 4921 | 4615 | if (IS_ERR(rk3308->mclk_rx)) { |
|---|
| 4922 | 4616 | dev_err(&pdev->dev, "Can't get acodec mclk_rx\n"); |
|---|
| 4923 | | - return PTR_ERR(rk3308->mclk_rx); |
|---|
| 4617 | + ret = PTR_ERR(rk3308->mclk_rx); |
|---|
| 4618 | + goto out_sysfs; |
|---|
| 4924 | 4619 | } |
|---|
| 4925 | 4620 | |
|---|
| 4926 | 4621 | rk3308->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx"); |
|---|
| 4927 | 4622 | if (IS_ERR(rk3308->mclk_tx)) { |
|---|
| 4928 | 4623 | dev_err(&pdev->dev, "Can't get acodec mclk_tx\n"); |
|---|
| 4929 | | - return PTR_ERR(rk3308->mclk_tx); |
|---|
| 4624 | + ret = PTR_ERR(rk3308->mclk_tx); |
|---|
| 4625 | + goto out_sysfs; |
|---|
| 4930 | 4626 | } |
|---|
| 4931 | 4627 | |
|---|
| 4932 | 4628 | ret = clk_prepare_enable(rk3308->pclk); |
|---|
| 4933 | 4629 | if (ret < 0) { |
|---|
| 4934 | 4630 | dev_err(&pdev->dev, "Failed to enable acodec pclk: %d\n", ret); |
|---|
| 4935 | | - return ret; |
|---|
| 4631 | + goto out_sysfs; |
|---|
| 4936 | 4632 | } |
|---|
| 4937 | 4633 | |
|---|
| 4938 | 4634 | ret = clk_prepare_enable(rk3308->mclk_rx); |
|---|
| 4939 | 4635 | if (ret < 0) { |
|---|
| 4940 | 4636 | dev_err(&pdev->dev, "Failed to enable i2s mclk_rx: %d\n", ret); |
|---|
| 4941 | | - return ret; |
|---|
| 4637 | + goto out_pclk; |
|---|
| 4942 | 4638 | } |
|---|
| 4943 | 4639 | |
|---|
| 4944 | 4640 | ret = clk_prepare_enable(rk3308->mclk_tx); |
|---|
| 4945 | 4641 | if (ret < 0) { |
|---|
| 4946 | 4642 | dev_err(&pdev->dev, "Failed to enable i2s mclk_tx: %d\n", ret); |
|---|
| 4947 | | - return ret; |
|---|
| 4643 | + goto out_mclk_rx; |
|---|
| 4948 | 4644 | } |
|---|
| 4949 | 4645 | |
|---|
| 4950 | 4646 | rk3308_codec_check_micbias(rk3308, np); |
|---|
| .. | .. |
|---|
| 4979 | 4675 | if (ret < 0 && ret != -EINVAL) { |
|---|
| 4980 | 4676 | dev_err(&pdev->dev, "Failed to read loopback property: %d\n", |
|---|
| 4981 | 4677 | ret); |
|---|
| 4982 | | - return ret; |
|---|
| 4678 | + goto failed; |
|---|
| 4983 | 4679 | } |
|---|
| 4984 | 4680 | |
|---|
| 4985 | 4681 | ret = rk3308_codec_adc_grps_route(rk3308, np); |
|---|
| 4986 | 4682 | if (ret < 0) { |
|---|
| 4987 | 4683 | dev_err(&pdev->dev, "Failed to route ADC groups: %d\n", |
|---|
| 4988 | 4684 | ret); |
|---|
| 4989 | | - return ret; |
|---|
| 4685 | + goto failed; |
|---|
| 4990 | 4686 | } |
|---|
| 4991 | 4687 | |
|---|
| 4992 | 4688 | ret = rk3308_codec_setup_en_always_adcs(rk3308, np); |
|---|
| 4993 | 4689 | if (ret < 0) { |
|---|
| 4994 | 4690 | dev_err(&pdev->dev, "Failed to setup enabled always ADCs: %d\n", |
|---|
| 4995 | 4691 | ret); |
|---|
| 4996 | | - return ret; |
|---|
| 4997 | | - } |
|---|
| 4998 | | - |
|---|
| 4999 | | - ret = rk3308_codec_get_version(rk3308); |
|---|
| 5000 | | - if (ret < 0) { |
|---|
| 5001 | | - dev_err(&pdev->dev, "Failed to get acodec version: %d\n", |
|---|
| 5002 | | - ret); |
|---|
| 5003 | | - return ret; |
|---|
| 4692 | + goto failed; |
|---|
| 5004 | 4693 | } |
|---|
| 5005 | 4694 | |
|---|
| 5006 | 4695 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| .. | .. |
|---|
| 5022 | 4711 | if (!rk3308->no_hp_det) { |
|---|
| 5023 | 4712 | int index = 0; |
|---|
| 5024 | 4713 | |
|---|
| 5025 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) |
|---|
| 4714 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) |
|---|
| 5026 | 4715 | index = 1; |
|---|
| 5027 | 4716 | |
|---|
| 5028 | 4717 | rk3308->irq = platform_get_irq(pdev, index); |
|---|
| .. | .. |
|---|
| 5043 | 4732 | goto failed; |
|---|
| 5044 | 4733 | } |
|---|
| 5045 | 4734 | |
|---|
| 5046 | | - if (rk3308->codec_ver == ACODEC_VERSION_B) { |
|---|
| 4735 | + if (rk3308->codec_ver >= ACODEC_VERSION_B) { |
|---|
| 5047 | 4736 | rk3308->detect_grf = |
|---|
| 5048 | 4737 | syscon_regmap_lookup_by_phandle(np, "rockchip,detect-grf"); |
|---|
| 5049 | 4738 | if (IS_ERR(rk3308->detect_grf)) { |
|---|
| 5050 | 4739 | dev_err(&pdev->dev, |
|---|
| 5051 | 4740 | "Missing 'rockchip,detect-grf' property\n"); |
|---|
| 5052 | | - return PTR_ERR(rk3308->detect_grf); |
|---|
| 4741 | + ret = PTR_ERR(rk3308->detect_grf); |
|---|
| 4742 | + goto failed; |
|---|
| 5053 | 4743 | } |
|---|
| 5054 | 4744 | |
|---|
| 5055 | 4745 | /* Configure filter count and enable hpdet irq. */ |
|---|
| .. | .. |
|---|
| 5061 | 4751 | (HPDET_BOTH_NEG_POS << 16) | |
|---|
| 5062 | 4752 | HPDET_BOTH_NEG_POS); |
|---|
| 5063 | 4753 | } |
|---|
| 5064 | | - |
|---|
| 5065 | | - rk3308_codec_set_jack_detect_cb = rk3308_codec_set_jack_detect; |
|---|
| 5066 | 4754 | } |
|---|
| 5067 | 4755 | |
|---|
| 5068 | 4756 | if (rk3308->codec_ver == ACODEC_VERSION_A) |
|---|
| .. | .. |
|---|
| 5086 | 4774 | return ret; |
|---|
| 5087 | 4775 | |
|---|
| 5088 | 4776 | failed: |
|---|
| 5089 | | - clk_disable_unprepare(rk3308->mclk_rx); |
|---|
| 5090 | 4777 | clk_disable_unprepare(rk3308->mclk_tx); |
|---|
| 4778 | +out_mclk_rx: |
|---|
| 4779 | + clk_disable_unprepare(rk3308->mclk_rx); |
|---|
| 4780 | +out_pclk: |
|---|
| 5091 | 4781 | clk_disable_unprepare(rk3308->pclk); |
|---|
| 5092 | | - device_unregister(&rk3308->dev); |
|---|
| 4782 | +out_sysfs: |
|---|
| 4783 | + rk3308_codec_sysfs_exit(rk3308); |
|---|
| 5093 | 4784 | |
|---|
| 5094 | 4785 | return ret; |
|---|
| 5095 | 4786 | } |
|---|