Commit 2551b6e8 authored by Seven Lee's avatar Seven Lee Committed by Mark Brown

ASoC: nau8821: Add headset button detection

This patch adds the function of headphone button detection,
Button detection will be enabled if the device tree
has a key_enable property.
Signed-off-by: default avatarSeven Lee <wtli@nuvoton.com>
Link: https://lore.kernel.org/r/20220627032959.3442064-1-wtli@nuvoton.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8e26c518
...@@ -34,7 +34,7 @@ Optional properties: ...@@ -34,7 +34,7 @@ Optional properties:
- nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
- nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock. - nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock.
- nuvoton,key_enable: Headset button detection switch.
Example: Example:
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#define NAU_FVCO_MAX 100000000 #define NAU_FVCO_MAX 100000000
#define NAU_FVCO_MIN 90000000 #define NAU_FVCO_MIN 90000000
#define NAU8821_BUTTON SND_JACK_BTN_0
/* the maximum frequency of CLK_ADC and CLK_DAC */ /* the maximum frequency of CLK_ADC and CLK_DAC */
#define CLK_DA_AD_MAX 6144000 #define CLK_DA_AD_MAX 6144000
...@@ -911,6 +913,20 @@ static void nau8821_eject_jack(struct nau8821 *nau8821) ...@@ -911,6 +913,20 @@ static void nau8821_eject_jack(struct nau8821 *nau8821)
/* Recover to normal channel input */ /* Recover to normal channel input */
regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE, regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE,
NAU8821_ADC_R_SRC_EN, 0); NAU8821_ADC_R_SRC_EN, 0);
if (nau8821->key_enable) {
regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK,
NAU8821_IRQ_KEY_RELEASE_EN |
NAU8821_IRQ_KEY_PRESS_EN,
NAU8821_IRQ_KEY_RELEASE_EN |
NAU8821_IRQ_KEY_PRESS_EN);
regmap_update_bits(regmap,
NAU8821_R12_INTERRUPT_DIS_CTRL,
NAU8821_IRQ_KEY_RELEASE_DIS |
NAU8821_IRQ_KEY_PRESS_DIS,
NAU8821_IRQ_KEY_RELEASE_DIS |
NAU8821_IRQ_KEY_PRESS_DIS);
}
} }
static void nau8821_jdet_work(struct work_struct *work) static void nau8821_jdet_work(struct work_struct *work)
...@@ -940,6 +956,15 @@ static void nau8821_jdet_work(struct work_struct *work) ...@@ -940,6 +956,15 @@ static void nau8821_jdet_work(struct work_struct *work)
*/ */
regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE, regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE,
NAU8821_ADC_R_SRC_EN, NAU8821_ADC_R_SRC_EN); NAU8821_ADC_R_SRC_EN, NAU8821_ADC_R_SRC_EN);
if (nau8821->key_enable) {
regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK,
NAU8821_IRQ_KEY_RELEASE_EN |
NAU8821_IRQ_KEY_PRESS_EN, 0);
regmap_update_bits(regmap,
NAU8821_R12_INTERRUPT_DIS_CTRL,
NAU8821_IRQ_KEY_RELEASE_DIS |
NAU8821_IRQ_KEY_PRESS_DIS, 0);
}
} else { } else {
dev_dbg(nau8821->dev, "Headphone connected\n"); dev_dbg(nau8821->dev, "Headphone connected\n");
event |= SND_JACK_HEADPHONE; event |= SND_JACK_HEADPHONE;
...@@ -999,6 +1024,13 @@ static irqreturn_t nau8821_interrupt(int irq, void *data) ...@@ -999,6 +1024,13 @@ static irqreturn_t nau8821_interrupt(int irq, void *data)
nau8821_eject_jack(nau8821); nau8821_eject_jack(nau8821);
event_mask |= SND_JACK_HEADSET; event_mask |= SND_JACK_HEADSET;
clear_irq = NAU8821_JACK_EJECT_IRQ_MASK; clear_irq = NAU8821_JACK_EJECT_IRQ_MASK;
} else if (active_irq & NAU8821_KEY_SHORT_PRESS_IRQ) {
event |= NAU8821_BUTTON;
event_mask |= NAU8821_BUTTON;
clear_irq = NAU8821_KEY_SHORT_PRESS_IRQ;
} else if (active_irq & NAU8821_KEY_RELEASE_IRQ) {
event_mask = NAU8821_BUTTON;
clear_irq = NAU8821_KEY_RELEASE_IRQ;
} else if ((active_irq & NAU8821_JACK_INSERT_IRQ_MASK) == } else if ((active_irq & NAU8821_JACK_INSERT_IRQ_MASK) ==
NAU8821_JACK_INSERT_DETECTED) { NAU8821_JACK_INSERT_DETECTED) {
regmap_update_bits(regmap, NAU8821_R71_ANALOG_ADC_1, regmap_update_bits(regmap, NAU8821_R71_ANALOG_ADC_1,
...@@ -1489,6 +1521,7 @@ static void nau8821_print_device_properties(struct nau8821 *nau8821) ...@@ -1489,6 +1521,7 @@ static void nau8821_print_device_properties(struct nau8821 *nau8821)
nau8821->jack_eject_debounce); nau8821->jack_eject_debounce);
dev_dbg(dev, "dmic-clk-threshold: %d\n", dev_dbg(dev, "dmic-clk-threshold: %d\n",
nau8821->dmic_clk_threshold); nau8821->dmic_clk_threshold);
dev_dbg(dev, "key_enable: %d\n", nau8821->key_enable);
} }
static int nau8821_read_device_properties(struct device *dev, static int nau8821_read_device_properties(struct device *dev,
...@@ -1502,6 +1535,8 @@ static int nau8821_read_device_properties(struct device *dev, ...@@ -1502,6 +1535,8 @@ static int nau8821_read_device_properties(struct device *dev,
"nuvoton,jkdet-pull-enable"); "nuvoton,jkdet-pull-enable");
nau8821->jkdet_pull_up = device_property_read_bool(dev, nau8821->jkdet_pull_up = device_property_read_bool(dev,
"nuvoton,jkdet-pull-up"); "nuvoton,jkdet-pull-up");
nau8821->key_enable = device_property_read_bool(dev,
"nuvoton,key-enable");
ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity", ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity",
&nau8821->jkdet_polarity); &nau8821->jkdet_polarity);
if (ret) if (ret)
......
...@@ -525,6 +525,7 @@ struct nau8821 { ...@@ -525,6 +525,7 @@ struct nau8821 {
int jack_eject_debounce; int jack_eject_debounce;
int fs; int fs;
int dmic_clk_threshold; int dmic_clk_threshold;
int key_enable;
}; };
int nau8821_enable_jack_detect(struct snd_soc_component *component, int nau8821_enable_jack_detect(struct snd_soc_component *component,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment