diff options
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r-- | sound/soc/codecs/rt5645.c | 187 |
1 files changed, 122 insertions, 65 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index edc152c8a1fe..8f140c8b93ac 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -1943,6 +1943,56 @@ static int rt5650_hp_event(struct snd_soc_dapm_widget *w, | |||
1943 | return 0; | 1943 | return 0; |
1944 | } | 1944 | } |
1945 | 1945 | ||
1946 | static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w, | ||
1947 | struct snd_kcontrol *k, int event) | ||
1948 | { | ||
1949 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1950 | |||
1951 | switch (event) { | ||
1952 | case SND_SOC_DAPM_PRE_PMU: | ||
1953 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1954 | RT5645_MICBIAS1_POW_CTRL_SEL_MASK, | ||
1955 | RT5645_MICBIAS1_POW_CTRL_SEL_M); | ||
1956 | break; | ||
1957 | |||
1958 | case SND_SOC_DAPM_POST_PMD: | ||
1959 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1960 | RT5645_MICBIAS1_POW_CTRL_SEL_MASK, | ||
1961 | RT5645_MICBIAS1_POW_CTRL_SEL_A); | ||
1962 | break; | ||
1963 | |||
1964 | default: | ||
1965 | return 0; | ||
1966 | } | ||
1967 | |||
1968 | return 0; | ||
1969 | } | ||
1970 | |||
1971 | static int rt5645_set_micbias2_event(struct snd_soc_dapm_widget *w, | ||
1972 | struct snd_kcontrol *k, int event) | ||
1973 | { | ||
1974 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1975 | |||
1976 | switch (event) { | ||
1977 | case SND_SOC_DAPM_PRE_PMU: | ||
1978 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1979 | RT5645_MICBIAS2_POW_CTRL_SEL_MASK, | ||
1980 | RT5645_MICBIAS2_POW_CTRL_SEL_M); | ||
1981 | break; | ||
1982 | |||
1983 | case SND_SOC_DAPM_POST_PMD: | ||
1984 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1985 | RT5645_MICBIAS2_POW_CTRL_SEL_MASK, | ||
1986 | RT5645_MICBIAS2_POW_CTRL_SEL_A); | ||
1987 | break; | ||
1988 | |||
1989 | default: | ||
1990 | return 0; | ||
1991 | } | ||
1992 | |||
1993 | return 0; | ||
1994 | } | ||
1995 | |||
1946 | static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | 1996 | static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { |
1947 | SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER, | 1997 | SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER, |
1948 | RT5645_PWR_LDO2_BIT, 0, NULL, 0), | 1998 | RT5645_PWR_LDO2_BIT, 0, NULL, 0), |
@@ -1980,10 +2030,12 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1980 | 2030 | ||
1981 | /* Input Side */ | 2031 | /* Input Side */ |
1982 | /* micbias */ | 2032 | /* micbias */ |
1983 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, | 2033 | SND_SOC_DAPM_SUPPLY("micbias1", RT5645_PWR_ANLG2, |
1984 | RT5645_PWR_MB1_BIT, 0), | 2034 | RT5645_PWR_MB1_BIT, 0, rt5645_set_micbias1_event, |
1985 | SND_SOC_DAPM_MICBIAS("micbias2", RT5645_PWR_ANLG2, | 2035 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1986 | RT5645_PWR_MB2_BIT, 0), | 2036 | SND_SOC_DAPM_SUPPLY("micbias2", RT5645_PWR_ANLG2, |
2037 | RT5645_PWR_MB2_BIT, 0, rt5645_set_micbias2_event, | ||
2038 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
1987 | /* Input Lines */ | 2039 | /* Input Lines */ |
1988 | SND_SOC_DAPM_INPUT("DMIC L1"), | 2040 | SND_SOC_DAPM_INPUT("DMIC L1"), |
1989 | SND_SOC_DAPM_INPUT("DMIC R1"), | 2041 | SND_SOC_DAPM_INPUT("DMIC R1"), |
@@ -3394,6 +3446,9 @@ static int rt5645_probe(struct snd_soc_codec *codec) | |||
3394 | snd_soc_dapm_sync(dapm); | 3446 | snd_soc_dapm_sync(dapm); |
3395 | } | 3447 | } |
3396 | 3448 | ||
3449 | if (rt5645->pdata.long_name) | ||
3450 | codec->component.card->long_name = rt5645->pdata.long_name; | ||
3451 | |||
3397 | rt5645->eq_param = devm_kzalloc(codec->dev, | 3452 | rt5645->eq_param = devm_kzalloc(codec->dev, |
3398 | RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); | 3453 | RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); |
3399 | 3454 | ||
@@ -3570,63 +3625,74 @@ static const struct acpi_device_id rt5645_acpi_match[] = { | |||
3570 | MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); | 3625 | MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); |
3571 | #endif | 3626 | #endif |
3572 | 3627 | ||
3573 | static const struct rt5645_platform_data general_platform_data = { | 3628 | static const struct rt5645_platform_data intel_braswell_platform_data = { |
3574 | .dmic1_data_pin = RT5645_DMIC1_DISABLE, | 3629 | .dmic1_data_pin = RT5645_DMIC1_DISABLE, |
3575 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | 3630 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, |
3576 | .jd_mode = 3, | 3631 | .jd_mode = 3, |
3577 | }; | 3632 | }; |
3578 | 3633 | ||
3579 | static const struct dmi_system_id dmi_platform_intel_braswell[] = { | 3634 | static const struct rt5645_platform_data buddy_platform_data = { |
3635 | .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, | ||
3636 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | ||
3637 | .jd_mode = 3, | ||
3638 | .level_trigger_irq = true, | ||
3639 | }; | ||
3640 | |||
3641 | static const struct rt5645_platform_data gpd_win_platform_data = { | ||
3642 | .jd_mode = 3, | ||
3643 | .inv_jd1_1 = true, | ||
3644 | .long_name = "gpd-win-pocket-rt5645", | ||
3645 | /* The GPD pocket has a diff. mic, for the win this does not matter. */ | ||
3646 | .in2_diff = true, | ||
3647 | }; | ||
3648 | |||
3649 | static const struct rt5645_platform_data asus_t100ha_platform_data = { | ||
3650 | .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, | ||
3651 | .dmic2_data_pin = RT5645_DMIC2_DISABLE, | ||
3652 | .jd_mode = 3, | ||
3653 | .inv_jd1_1 = true, | ||
3654 | }; | ||
3655 | |||
3656 | static const struct rt5645_platform_data jd_mode3_platform_data = { | ||
3657 | .jd_mode = 3, | ||
3658 | }; | ||
3659 | |||
3660 | static const struct dmi_system_id dmi_platform_data[] = { | ||
3661 | { | ||
3662 | .ident = "Chrome Buddy", | ||
3663 | .matches = { | ||
3664 | DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), | ||
3665 | }, | ||
3666 | .driver_data = (void *)&buddy_platform_data, | ||
3667 | }, | ||
3580 | { | 3668 | { |
3581 | .ident = "Intel Strago", | 3669 | .ident = "Intel Strago", |
3582 | .matches = { | 3670 | .matches = { |
3583 | DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), | 3671 | DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), |
3584 | }, | 3672 | }, |
3673 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3585 | }, | 3674 | }, |
3586 | { | 3675 | { |
3587 | .ident = "Google Chrome", | 3676 | .ident = "Google Chrome", |
3588 | .matches = { | 3677 | .matches = { |
3589 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), | 3678 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), |
3590 | }, | 3679 | }, |
3680 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3591 | }, | 3681 | }, |
3592 | { | 3682 | { |
3593 | .ident = "Google Setzer", | 3683 | .ident = "Google Setzer", |
3594 | .matches = { | 3684 | .matches = { |
3595 | DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), | 3685 | DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), |
3596 | }, | 3686 | }, |
3687 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3597 | }, | 3688 | }, |
3598 | { | 3689 | { |
3599 | .ident = "Microsoft Surface 3", | 3690 | .ident = "Microsoft Surface 3", |
3600 | .matches = { | 3691 | .matches = { |
3601 | DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), | 3692 | DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), |
3602 | }, | 3693 | }, |
3694 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3603 | }, | 3695 | }, |
3604 | { } | ||
3605 | }; | ||
3606 | |||
3607 | static const struct rt5645_platform_data buddy_platform_data = { | ||
3608 | .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, | ||
3609 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | ||
3610 | .jd_mode = 3, | ||
3611 | .level_trigger_irq = true, | ||
3612 | }; | ||
3613 | |||
3614 | static const struct dmi_system_id dmi_platform_intel_broadwell[] = { | ||
3615 | { | ||
3616 | .ident = "Chrome Buddy", | ||
3617 | .matches = { | ||
3618 | DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), | ||
3619 | }, | ||
3620 | }, | ||
3621 | { } | ||
3622 | }; | ||
3623 | |||
3624 | static const struct rt5645_platform_data gpd_win_platform_data = { | ||
3625 | .jd_mode = 3, | ||
3626 | .inv_jd1_1 = true, | ||
3627 | }; | ||
3628 | |||
3629 | static const struct dmi_system_id dmi_platform_gpd_win[] = { | ||
3630 | { | 3696 | { |
3631 | /* | 3697 | /* |
3632 | * Match for the GPDwin which unfortunately uses somewhat | 3698 | * Match for the GPDwin which unfortunately uses somewhat |
@@ -3637,46 +3703,38 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = { | |||
3637 | * the same default product_name. Also the GPDwin is the | 3703 | * the same default product_name. Also the GPDwin is the |
3638 | * only device to have both board_ and product_name not set. | 3704 | * only device to have both board_ and product_name not set. |
3639 | */ | 3705 | */ |
3640 | .ident = "GPD Win", | 3706 | .ident = "GPD Win / Pocket", |
3641 | .matches = { | 3707 | .matches = { |
3642 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | 3708 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
3643 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | 3709 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), |
3644 | DMI_MATCH(DMI_BOARD_SERIAL, "Default string"), | 3710 | DMI_MATCH(DMI_BOARD_SERIAL, "Default string"), |
3645 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | 3711 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), |
3646 | }, | 3712 | }, |
3713 | .driver_data = (void *)&gpd_win_platform_data, | ||
3647 | }, | 3714 | }, |
3648 | {} | ||
3649 | }; | ||
3650 | |||
3651 | static const struct rt5645_platform_data general_platform_data2 = { | ||
3652 | .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, | ||
3653 | .dmic2_data_pin = RT5645_DMIC2_DISABLE, | ||
3654 | .jd_mode = 3, | ||
3655 | .inv_jd1_1 = true, | ||
3656 | }; | ||
3657 | |||
3658 | static const struct dmi_system_id dmi_platform_asus_t100ha[] = { | ||
3659 | { | 3715 | { |
3660 | .ident = "ASUS T100HAN", | 3716 | .ident = "ASUS T100HAN", |
3661 | .matches = { | 3717 | .matches = { |
3662 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 3718 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
3663 | DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), | 3719 | DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), |
3664 | }, | 3720 | }, |
3721 | .driver_data = (void *)&asus_t100ha_platform_data, | ||
3665 | }, | 3722 | }, |
3666 | { } | ||
3667 | }; | ||
3668 | |||
3669 | static const struct rt5645_platform_data minix_z83_4_platform_data = { | ||
3670 | .jd_mode = 3, | ||
3671 | }; | ||
3672 | |||
3673 | static const struct dmi_system_id dmi_platform_minix_z83_4[] = { | ||
3674 | { | 3723 | { |
3675 | .ident = "MINIX Z83-4", | 3724 | .ident = "MINIX Z83-4", |
3676 | .matches = { | 3725 | .matches = { |
3677 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), | 3726 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), |
3678 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), | 3727 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), |
3679 | }, | 3728 | }, |
3729 | .driver_data = (void *)&jd_mode3_platform_data, | ||
3730 | }, | ||
3731 | { | ||
3732 | .ident = "Teclast X80 Pro", | ||
3733 | .matches = { | ||
3734 | DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), | ||
3735 | DMI_MATCH(DMI_PRODUCT_NAME, "X80 Pro"), | ||
3736 | }, | ||
3737 | .driver_data = (void *)&jd_mode3_platform_data, | ||
3680 | }, | 3738 | }, |
3681 | { } | 3739 | { } |
3682 | }; | 3740 | }; |
@@ -3684,9 +3742,9 @@ static const struct dmi_system_id dmi_platform_minix_z83_4[] = { | |||
3684 | static bool rt5645_check_dp(struct device *dev) | 3742 | static bool rt5645_check_dp(struct device *dev) |
3685 | { | 3743 | { |
3686 | if (device_property_present(dev, "realtek,in2-differential") || | 3744 | if (device_property_present(dev, "realtek,in2-differential") || |
3687 | device_property_present(dev, "realtek,dmic1-data-pin") || | 3745 | device_property_present(dev, "realtek,dmic1-data-pin") || |
3688 | device_property_present(dev, "realtek,dmic2-data-pin") || | 3746 | device_property_present(dev, "realtek,dmic2-data-pin") || |
3689 | device_property_present(dev, "realtek,jd-mode")) | 3747 | device_property_present(dev, "realtek,jd-mode")) |
3690 | return true; | 3748 | return true; |
3691 | 3749 | ||
3692 | return false; | 3750 | return false; |
@@ -3710,6 +3768,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3710 | const struct i2c_device_id *id) | 3768 | const struct i2c_device_id *id) |
3711 | { | 3769 | { |
3712 | struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev); | 3770 | struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev); |
3771 | const struct dmi_system_id *dmi_data; | ||
3713 | struct rt5645_priv *rt5645; | 3772 | struct rt5645_priv *rt5645; |
3714 | int ret, i; | 3773 | int ret, i; |
3715 | unsigned int val; | 3774 | unsigned int val; |
@@ -3723,20 +3782,18 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3723 | rt5645->i2c = i2c; | 3782 | rt5645->i2c = i2c; |
3724 | i2c_set_clientdata(i2c, rt5645); | 3783 | i2c_set_clientdata(i2c, rt5645); |
3725 | 3784 | ||
3785 | dmi_data = dmi_first_match(dmi_platform_data); | ||
3786 | if (dmi_data) { | ||
3787 | dev_info(&i2c->dev, "Detected %s platform\n", dmi_data->ident); | ||
3788 | pdata = dmi_data->driver_data; | ||
3789 | } | ||
3790 | |||
3726 | if (pdata) | 3791 | if (pdata) |
3727 | rt5645->pdata = *pdata; | 3792 | rt5645->pdata = *pdata; |
3728 | else if (dmi_check_system(dmi_platform_intel_broadwell)) | ||
3729 | rt5645->pdata = buddy_platform_data; | ||
3730 | else if (rt5645_check_dp(&i2c->dev)) | 3793 | else if (rt5645_check_dp(&i2c->dev)) |
3731 | rt5645_parse_dt(rt5645, &i2c->dev); | 3794 | rt5645_parse_dt(rt5645, &i2c->dev); |
3732 | else if (dmi_check_system(dmi_platform_intel_braswell)) | 3795 | else |
3733 | rt5645->pdata = general_platform_data; | 3796 | rt5645->pdata = jd_mode3_platform_data; |
3734 | else if (dmi_check_system(dmi_platform_gpd_win)) | ||
3735 | rt5645->pdata = gpd_win_platform_data; | ||
3736 | else if (dmi_check_system(dmi_platform_asus_t100ha)) | ||
3737 | rt5645->pdata = general_platform_data2; | ||
3738 | else if (dmi_check_system(dmi_platform_minix_z83_4)) | ||
3739 | rt5645->pdata = minix_z83_4_platform_data; | ||
3740 | 3797 | ||
3741 | if (quirk != -1) { | 3798 | if (quirk != -1) { |
3742 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); | 3799 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); |