aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5645.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r--sound/soc/codecs/rt5645.c97
1 files changed, 69 insertions, 28 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 87844a45886a..9ec58166f7c4 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -34,6 +34,17 @@
34#include "rl6231.h" 34#include "rl6231.h"
35#include "rt5645.h" 35#include "rt5645.h"
36 36
37#define QUIRK_INV_JD1_1(q) ((q) & 1)
38#define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1)
39#define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1)
40#define QUIRK_JD_MODE(q) (((q) >> 4) & 7)
41#define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3)
42#define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3)
43
44static unsigned int quirk = -1;
45module_param(quirk, uint, 0444);
46MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override");
47
37#define RT5645_DEVICE_ID 0x6308 48#define RT5645_DEVICE_ID 0x6308
38#define RT5650_DEVICE_ID 0x6419 49#define RT5650_DEVICE_ID 0x6419
39 50
@@ -59,7 +70,7 @@ static const struct regmap_range_cfg rt5645_ranges[] = {
59 70
60static const struct reg_sequence init_list[] = { 71static const struct reg_sequence init_list[] = {
61 {RT5645_PR_BASE + 0x3d, 0x3600}, 72 {RT5645_PR_BASE + 0x3d, 0x3600},
62 {RT5645_PR_BASE + 0x1c, 0xfd20}, 73 {RT5645_PR_BASE + 0x1c, 0xfd70},
63 {RT5645_PR_BASE + 0x20, 0x611f}, 74 {RT5645_PR_BASE + 0x20, 0x611f},
64 {RT5645_PR_BASE + 0x21, 0x4040}, 75 {RT5645_PR_BASE + 0x21, 0x4040},
65 {RT5645_PR_BASE + 0x23, 0x0004}, 76 {RT5645_PR_BASE + 0x23, 0x0004},
@@ -3151,7 +3162,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
3151 snd_soc_dapm_sync(dapm); 3162 snd_soc_dapm_sync(dapm);
3152 rt5645->jack_type = SND_JACK_HEADPHONE; 3163 rt5645->jack_type = SND_JACK_HEADPHONE;
3153 } 3164 }
3154 if (rt5645->pdata.jd_invert) 3165 if (rt5645->pdata.level_trigger_irq)
3155 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, 3166 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
3156 RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR); 3167 RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
3157 } else { /* jack out */ 3168 } else { /* jack out */
@@ -3172,7 +3183,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
3172 snd_soc_dapm_disable_pin(dapm, "LDO2"); 3183 snd_soc_dapm_disable_pin(dapm, "LDO2");
3173 snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); 3184 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
3174 snd_soc_dapm_sync(dapm); 3185 snd_soc_dapm_sync(dapm);
3175 if (rt5645->pdata.jd_invert) 3186 if (rt5645->pdata.level_trigger_irq)
3176 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, 3187 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
3177 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV); 3188 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
3178 } 3189 }
@@ -3238,24 +3249,16 @@ static void rt5645_jack_detect_work(struct work_struct *work)
3238 snd_soc_jack_report(rt5645->mic_jack, 3249 snd_soc_jack_report(rt5645->mic_jack,
3239 report, SND_JACK_MICROPHONE); 3250 report, SND_JACK_MICROPHONE);
3240 return; 3251 return;
3241 case 1: /* 2 port */ 3252 default: /* read rt5645 jd1_1 status */
3242 val = snd_soc_read(rt5645->codec, RT5645_A_JD_CTRL1) & 0x0070; 3253 val = snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x1000;
3243 break;
3244 default: /* 1 port */
3245 val = snd_soc_read(rt5645->codec, RT5645_A_JD_CTRL1) & 0x0020;
3246 break; 3254 break;
3247 3255
3248 } 3256 }
3249 3257
3250 switch (val) { 3258 if (!val && (rt5645->jack_type == 0)) { /* jack in */
3251 /* jack in */ 3259 report = rt5645_jack_detect(rt5645->codec, 1);
3252 case 0x30: /* 2 port */ 3260 } else if (!val && rt5645->jack_type != 0) {
3253 case 0x0: /* 1 port or 2 port */ 3261 /* for push button and jack out */
3254 if (rt5645->jack_type == 0) {
3255 report = rt5645_jack_detect(rt5645->codec, 1);
3256 /* for push button and jack out */
3257 break;
3258 }
3259 btn_type = 0; 3262 btn_type = 0;
3260 if (snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x4) { 3263 if (snd_soc_read(rt5645->codec, RT5645_INT_IRQ_ST) & 0x4) {
3261 /* button pressed */ 3264 /* button pressed */
@@ -3302,19 +3305,12 @@ static void rt5645_jack_detect_work(struct work_struct *work)
3302 mod_timer(&rt5645->btn_check_timer, 3305 mod_timer(&rt5645->btn_check_timer,
3303 msecs_to_jiffies(100)); 3306 msecs_to_jiffies(100));
3304 } 3307 }
3305 3308 } else {
3306 break; 3309 /* jack out */
3307 /* jack out */
3308 case 0x70: /* 2 port */
3309 case 0x10: /* 2 port */
3310 case 0x20: /* 1 port */
3311 report = 0; 3310 report = 0;
3312 snd_soc_update_bits(rt5645->codec, 3311 snd_soc_update_bits(rt5645->codec,
3313 RT5645_INT_IRQ_ST, 0x1, 0x0); 3312 RT5645_INT_IRQ_ST, 0x1, 0x0);
3314 rt5645_jack_detect(rt5645->codec, 0); 3313 rt5645_jack_detect(rt5645->codec, 0);
3315 break;
3316 default:
3317 break;
3318 } 3314 }
3319 3315
3320 snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE); 3316 snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE);
@@ -3601,7 +3597,7 @@ static struct rt5645_platform_data buddy_platform_data = {
3601 .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, 3597 .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
3602 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, 3598 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3603 .jd_mode = 3, 3599 .jd_mode = 3,
3604 .jd_invert = true, 3600 .level_trigger_irq = true,
3605}; 3601};
3606 3602
3607static struct dmi_system_id dmi_platform_intel_broadwell[] = { 3603static struct dmi_system_id dmi_platform_intel_broadwell[] = {
@@ -3614,6 +3610,33 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3614 { } 3610 { }
3615}; 3611};
3616 3612
3613static struct rt5645_platform_data gpd_win_platform_data = {
3614 .jd_mode = 3,
3615 .inv_jd1_1 = true,
3616};
3617
3618static const struct dmi_system_id dmi_platform_gpd_win[] = {
3619 {
3620 /*
3621 * Match for the GPDwin which unfortunately uses somewhat
3622 * generic dmi strings, which is why we test for 4 strings.
3623 * Comparing against 23 other byt/cht boards, board_vendor
3624 * and board_name are unique to the GPDwin, where as only one
3625 * other board has the same board_serial and 3 others have
3626 * the same default product_name. Also the GPDwin is the
3627 * only device to have both board_ and product_name not set.
3628 */
3629 .ident = "GPD Win",
3630 .matches = {
3631 DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
3632 DMI_MATCH(DMI_BOARD_NAME, "Default string"),
3633 DMI_MATCH(DMI_BOARD_SERIAL, "Default string"),
3634 DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
3635 },
3636 },
3637 {}
3638};
3639
3617static bool rt5645_check_dp(struct device *dev) 3640static bool rt5645_check_dp(struct device *dev)
3618{ 3641{
3619 if (device_property_present(dev, "realtek,in2-differential") || 3642 if (device_property_present(dev, "realtek,in2-differential") ||
@@ -3664,6 +3687,17 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3664 rt5645_parse_dt(rt5645, &i2c->dev); 3687 rt5645_parse_dt(rt5645, &i2c->dev);
3665 else if (dmi_check_system(dmi_platform_intel_braswell)) 3688 else if (dmi_check_system(dmi_platform_intel_braswell))
3666 rt5645->pdata = general_platform_data; 3689 rt5645->pdata = general_platform_data;
3690 else if (dmi_check_system(dmi_platform_gpd_win))
3691 rt5645->pdata = gpd_win_platform_data;
3692
3693 if (quirk != -1) {
3694 rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk);
3695 rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk);
3696 rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk);
3697 rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk);
3698 rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk);
3699 rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk);
3700 }
3667 3701
3668 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", 3702 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect",
3669 GPIOD_IN); 3703 GPIOD_IN);
@@ -3745,6 +3779,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3745 ret); 3779 ret);
3746 } 3780 }
3747 3781
3782 regmap_update_bits(rt5645->regmap, RT5645_CLSD_OUT_CTRL, 0xc0, 0xc0);
3783
3748 if (rt5645->pdata.in2_diff) 3784 if (rt5645->pdata.in2_diff)
3749 regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, 3785 regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL,
3750 RT5645_IN_DF2, RT5645_IN_DF2); 3786 RT5645_IN_DF2, RT5645_IN_DF2);
@@ -3848,12 +3884,16 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3848 default: 3884 default:
3849 break; 3885 break;
3850 } 3886 }
3887 if (rt5645->pdata.inv_jd1_1) {
3888 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
3889 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
3890 }
3851 } 3891 }
3852 3892
3853 regmap_update_bits(rt5645->regmap, RT5645_ADDA_CLK1, 3893 regmap_update_bits(rt5645->regmap, RT5645_ADDA_CLK1,
3854 RT5645_I2S_PD1_MASK, RT5645_I2S_PD1_2); 3894 RT5645_I2S_PD1_MASK, RT5645_I2S_PD1_2);
3855 3895
3856 if (rt5645->pdata.jd_invert) { 3896 if (rt5645->pdata.level_trigger_irq) {
3857 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2, 3897 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
3858 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV); 3898 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
3859 } 3899 }
@@ -3897,6 +3937,7 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
3897 3937
3898 cancel_delayed_work_sync(&rt5645->jack_detect_work); 3938 cancel_delayed_work_sync(&rt5645->jack_detect_work);
3899 cancel_delayed_work_sync(&rt5645->rcclock_work); 3939 cancel_delayed_work_sync(&rt5645->rcclock_work);
3940 del_timer_sync(&rt5645->btn_check_timer);
3900 3941
3901 snd_soc_unregister_codec(&i2c->dev); 3942 snd_soc_unregister_codec(&i2c->dev);
3902 regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); 3943 regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);