|
79 | 79 | #define BYT_RT5640_LINEOUT_AS_HP2 BIT(26)
|
80 | 80 | #define BYT_RT5640_HSMIC2_ON_IN1 BIT(27)
|
81 | 81 | #define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28)
|
| 82 | +#define BYT_RT5640_USE_AMCR0F28 BIT(29) |
82 | 83 |
|
83 | 84 | #define BYTCR_INPUT_DEFAULTS \
|
84 | 85 | (BYT_RT5640_IN3_MAP | \
|
|
93 | 94 | struct byt_rt5640_private {
|
94 | 95 | struct snd_soc_jack jack;
|
95 | 96 | struct snd_soc_jack jack2;
|
| 97 | + struct rt5640_set_jack_data jack_data; |
96 | 98 | struct gpio_desc *hsmic_detect;
|
97 | 99 | struct clk *mclk;
|
98 | 100 | struct device *codec_dev;
|
@@ -597,7 +599,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
597 | 599 | BYT_RT5640_OVCD_TH_2000UA |
|
598 | 600 | BYT_RT5640_OVCD_SF_0P75 |
|
599 | 601 | BYT_RT5640_SSP0_AIF1 |
|
600 |
| - BYT_RT5640_MCLK_EN), |
| 602 | + BYT_RT5640_MCLK_EN | |
| 603 | + BYT_RT5640_USE_AMCR0F28), |
601 | 604 | },
|
602 | 605 | {
|
603 | 606 | .matches = {
|
@@ -1109,6 +1112,32 @@ static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
|
1109 | 1112 | return ret;
|
1110 | 1113 | }
|
1111 | 1114 |
|
| 1115 | +/* Some Android devs specify IRQs/GPIOS in a special AMCR0F28 ACPI device */ |
| 1116 | +static int byt_rt5640_get_amcr0f28_settings(struct snd_soc_card *card) |
| 1117 | +{ |
| 1118 | + struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); |
| 1119 | + struct rt5640_set_jack_data *data = &priv->jack_data; |
| 1120 | + struct acpi_device *adev; |
| 1121 | + int ret = 0; |
| 1122 | + |
| 1123 | + adev = acpi_dev_get_first_match_dev("AMCR0F28", "1", -1); |
| 1124 | + if (!adev) { |
| 1125 | + dev_err(card->dev, "error cannot find AMCR0F28 adev\n"); |
| 1126 | + return -ENOENT; |
| 1127 | + } |
| 1128 | + |
| 1129 | + data->codec_irq_override = acpi_dev_gpio_irq_get(adev, 0); |
| 1130 | + if (data->codec_irq_override < 0) { |
| 1131 | + ret = data->codec_irq_override; |
| 1132 | + dev_err(card->dev, "error %d getting codec IRQ\n", ret); |
| 1133 | + goto put_adev; |
| 1134 | + } |
| 1135 | + |
| 1136 | +put_adev: |
| 1137 | + acpi_dev_put(adev); |
| 1138 | + return ret; |
| 1139 | +} |
| 1140 | + |
1112 | 1141 | static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
1113 | 1142 | {
|
1114 | 1143 | struct snd_soc_card *card = runtime->card;
|
@@ -1244,7 +1273,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
1244 | 1273 | }
|
1245 | 1274 | snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
|
1246 | 1275 | KEY_PLAYPAUSE);
|
1247 |
| - snd_soc_component_set_jack(component, &priv->jack, NULL); |
| 1276 | + |
| 1277 | + if (byt_rt5640_quirk & BYT_RT5640_USE_AMCR0F28) { |
| 1278 | + ret = byt_rt5640_get_amcr0f28_settings(card); |
| 1279 | + if (ret) |
| 1280 | + return ret; |
| 1281 | + } |
| 1282 | + |
| 1283 | + snd_soc_component_set_jack(component, &priv->jack, &priv->jack_data); |
1248 | 1284 | }
|
1249 | 1285 |
|
1250 | 1286 | if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
|
@@ -1448,7 +1484,8 @@ static int byt_rt5640_resume(struct snd_soc_card *card)
|
1448 | 1484 | for_each_card_components(card, component) {
|
1449 | 1485 | if (!strcmp(component->name, byt_rt5640_codec_name)) {
|
1450 | 1486 | dev_dbg(component->dev, "re-enabling jack detect after resume\n");
|
1451 |
| - snd_soc_component_set_jack(component, &priv->jack, NULL); |
| 1487 | + snd_soc_component_set_jack(component, &priv->jack, |
| 1488 | + &priv->jack_data); |
1452 | 1489 | break;
|
1453 | 1490 | }
|
1454 | 1491 | }
|
|
0 commit comments