From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Andrew F. Davis" Subject: [PATCH 14/17] ASoC: tlv320aic31xx: Add headphone/headset detection Date: Wed, 8 Nov 2017 18:27:38 -0600 Message-ID: <20171109002741.10897-15-afd@ti.com> References: <20171109002741.10897-1-afd@ti.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <20171109002741.10897-1-afd@ti.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org To: Liam Girdwood , Mark Brown , Rob Herring , Mark Rutland , =?UTF-8?q?Beno=C3=AEt=20Cousson?= , Tony Lindgren Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, "Andrew F . Davis" List-Id: devicetree@vger.kernel.org This device can detect the insertion/removal of headphones and headsets. Enable reporting this status by enabling this interrupt and forwarding this to upper-layers if a jack has been defined. This jack definition and the resulting operation from a jack detection event must currently be defined by sound card platform code until CODEC outputs to jack mappings can be defined generically. Signed-off-by: Andrew F. Davis --- sound/soc/codecs/tlv320aic31xx.c | 33 +++++++++++++++++++++++++++++++++ sound/soc/codecs/tlv320aic31xx.h | 11 +++++++++++ 2 files changed, 44 insertions(+) diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index f208362017c6..7a27361d9d27 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,7 @@ static bool aic31xx_volatile(struct device *dev, unsigned int reg) case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */ case AIC31XX_INTRDACFLAG2: case AIC31XX_INTRADCFLAG2: + case AIC31XX_HSDETECT: return true; } return false; @@ -170,6 +172,7 @@ struct aic31xx_priv { int micbias_vg; struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; + struct snd_soc_jack *jack; unsigned int sysclk; u8 p_div; int rate_div_line; @@ -1339,6 +1342,32 @@ static irqreturn_t aic31xx_irq(int irq, void *data) if (value & AIC31XX_HPRSCDETECT) dev_err(dev, "Short circuit on Right output is detected\n"); + if (value & AIC31XX_HSPLUG) { + int status = 0; + + ret = regmap_read(aic31xx->regmap, AIC31XX_HSDETECT, &value); + if (ret) { + dev_err(dev, "Failed to read headset type: %d\n", ret); + return IRQ_NONE; + } + + switch ((value & AIC31XX_HSD_TYPE_MASK) >> + AIC31XX_HSD_TYPE_SHIFT) { + case AIC31XX_HSD_HP: + status |= SND_JACK_HEADPHONE; + break; + case AIC31XX_HSD_HS: + status |= SND_JACK_HEADSET; + break; + default: + break; + } + + if (aic31xx->jack) + snd_soc_jack_report(aic31xx->jack, status, + AIC31XX_JACK_MASK); + } + ret = regmap_read(aic31xx->regmap, AIC31XX_OFFLAG, &value); if (ret) { dev_err(dev, "Failed to read overflow flag: %d\n", ret); @@ -1430,9 +1459,13 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, AIC31XX_GPIO1_FUNC_SHIFT); regmap_write(aic31xx->regmap, AIC31XX_INT1CTRL, + AIC31XX_HSPLUGDET | AIC31XX_SC | AIC31XX_ENGINE); + regmap_write(aic31xx->regmap, AIC31XX_HSDETECT, + AIC31XX_HSD_ENABLE); + ret = devm_request_threaded_irq(aic31xx->dev, aic31xx->irq, NULL, aic31xx_irq, IRQF_ONESHOT, "aic31xx-irq", diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h index 944a19539324..eca0a99209d8 100644 --- a/sound/soc/codecs/tlv320aic31xx.h +++ b/sound/soc/codecs/tlv320aic31xx.h @@ -27,6 +27,9 @@ #define AIC31XX_MINIDSP_BIT BIT(2) #define DAC31XX_BIT BIT(3) +#define AIC31XX_JACK_MASK (SND_JACK_HEADPHONE | \ + SND_JACK_HEADSET) + enum aic31xx_type { AIC3100 = 0, AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, @@ -221,6 +224,14 @@ enum aic31xx_type { /* AIC31XX_DACMUTE */ #define AIC31XX_DACMUTE_MASK GENMASK(3, 2) +/* AIC31XX_HSDETECT */ +#define AIC31XX_HSD_ENABLE BIT(7) +#define AIC31XX_HSD_TYPE_MASK GENMASK(6, 5) +#define AIC31XX_HSD_TYPE_SHIFT 5 +#define AIC31XX_HSD_NONE 0 +#define AIC31XX_HSD_HP 1 +#define AIC31XX_HSD_HS 3 + /* AIC31XX_MICBIAS */ #define AIC31XX_MICBIAS_MASK GENMASK(1, 0) #define AIC31XX_MICBIAS_SHIFT 0 -- 2.15.0