mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
sound: soc: Add docking station jack support
Add docking station jack interrupt support to msm8994 audio machine driver. Change-Id: I0af9a78cee92554fe75d2fd3c33fe0be98fc2576 Signed-off-by: Tanya Finkel <tfinkel@codeaurora.org>
This commit is contained in:
parent
2f0d7b70fe
commit
0dfb375b17
2 changed files with 150 additions and 0 deletions
20
sound/soc/msm/device_event.h
Normal file
20
sound/soc/msm/device_event.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __DEVICE_EVENT_H
|
||||
#define __DEVICE_EVENT_H
|
||||
|
||||
#define QC_AUDIO_EXTERNAL_SPK_1_EVENT "qc_ext_spk_1"
|
||||
#define QC_AUDIO_EXTERNAL_SPK_2_EVENT "qc_ext_spk_2"
|
||||
#define QC_AUDIO_EXTERNAL_MIC_EVENT "qc_ext_mic"
|
||||
|
||||
#endif /* __DEVICE_EVENT_H */
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/switch.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include <sound/jack.h>
|
||||
#include <sound/q6afe-v2.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <device_event.h>
|
||||
#include "qdsp6v2/msm-pcm-routing-v2.h"
|
||||
#include "qdsp6v2/q6core.h"
|
||||
#include "../codecs/wcd9xxx-common.h"
|
||||
|
@ -113,6 +115,16 @@ static int clk_users;
|
|||
static atomic_t prim_auxpcm_rsc_ref;
|
||||
static atomic_t sec_auxpcm_rsc_ref;
|
||||
|
||||
struct msm8994_liquid_dock_dev {
|
||||
int dock_plug_gpio;
|
||||
int dock_plug_irq;
|
||||
int dock_plug_det;
|
||||
struct work_struct irq_work;
|
||||
struct switch_dev audio_sdev;
|
||||
};
|
||||
|
||||
static struct msm8994_liquid_dock_dev *msm8994_liquid_dock_dev;
|
||||
|
||||
static const char *const pin_states[] = {"Disable", "active"};
|
||||
static const char *const spk_function[] = {"Off", "On"};
|
||||
static const char *const slim0_rx_ch_text[] = {"One", "Two"};
|
||||
|
@ -199,6 +211,103 @@ static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
|
|||
}
|
||||
}
|
||||
|
||||
static void msm8994_liquid_docking_irq_work(struct work_struct *work)
|
||||
{
|
||||
struct msm8994_liquid_dock_dev *dock_dev =
|
||||
container_of(work, struct msm8994_liquid_dock_dev, irq_work);
|
||||
|
||||
dock_dev->dock_plug_det =
|
||||
gpio_get_value(dock_dev->dock_plug_gpio);
|
||||
|
||||
switch_set_state(&dock_dev->audio_sdev, dock_dev->dock_plug_det);
|
||||
/*notify to audio deamon*/
|
||||
sysfs_notify(&dock_dev->audio_sdev.dev->kobj, NULL, "state");
|
||||
}
|
||||
|
||||
static irqreturn_t msm8994_liquid_docking_irq_handler(int irq, void *dev)
|
||||
{
|
||||
struct msm8994_liquid_dock_dev *dock_dev = dev;
|
||||
|
||||
/* switch speakers should not run in interrupt context */
|
||||
schedule_work(&dock_dev->irq_work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int msm8994_liquid_init_docking(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int dock_plug_gpio = 0;
|
||||
|
||||
/* plug in docking speaker+plug in device OR unplug one of them */
|
||||
u32 dock_plug_irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
|
||||
IRQF_SHARED;
|
||||
|
||||
dock_plug_gpio = of_get_named_gpio(spdev->dev.of_node,
|
||||
"qcom,dock-plug-det-irq", 0);
|
||||
|
||||
if (dock_plug_gpio >= 0) {
|
||||
msm8994_liquid_dock_dev =
|
||||
kzalloc(sizeof(*msm8994_liquid_dock_dev), GFP_KERNEL);
|
||||
if (!msm8994_liquid_dock_dev) {
|
||||
pr_err("msm8994_liquid_dock_dev alloc fail.\n");
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
msm8994_liquid_dock_dev->dock_plug_gpio = dock_plug_gpio;
|
||||
|
||||
ret = gpio_request(msm8994_liquid_dock_dev->dock_plug_gpio,
|
||||
"dock-plug-det-irq");
|
||||
if (ret) {
|
||||
pr_err("%s:failed request msm8994_liquid_dock_plug_gpio err = %d\n",
|
||||
__func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto fail_dock_gpio;
|
||||
}
|
||||
|
||||
msm8994_liquid_dock_dev->dock_plug_det =
|
||||
gpio_get_value(msm8994_liquid_dock_dev->dock_plug_gpio);
|
||||
msm8994_liquid_dock_dev->dock_plug_irq =
|
||||
gpio_to_irq(msm8994_liquid_dock_dev->dock_plug_gpio);
|
||||
|
||||
ret = request_irq(msm8994_liquid_dock_dev->dock_plug_irq,
|
||||
msm8994_liquid_docking_irq_handler,
|
||||
dock_plug_irq_flags,
|
||||
"liquid_dock_plug_irq",
|
||||
msm8994_liquid_dock_dev);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: Request Irq Failed err = %d\n",
|
||||
__func__, ret);
|
||||
goto fail_dock_gpio;
|
||||
}
|
||||
|
||||
msm8994_liquid_dock_dev->audio_sdev.name =
|
||||
QC_AUDIO_EXTERNAL_SPK_1_EVENT;
|
||||
|
||||
if (switch_dev_register(
|
||||
&msm8994_liquid_dock_dev->audio_sdev) < 0) {
|
||||
pr_err("%s: dock device register in switch diretory failed\n",
|
||||
__func__);
|
||||
goto fail_switch_dev;
|
||||
}
|
||||
|
||||
INIT_WORK(
|
||||
&msm8994_liquid_dock_dev->irq_work,
|
||||
msm8994_liquid_docking_irq_work);
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail_switch_dev:
|
||||
free_irq(msm8994_liquid_dock_dev->dock_plug_irq,
|
||||
msm8994_liquid_dock_dev);
|
||||
fail_dock_gpio:
|
||||
gpio_free(msm8994_liquid_dock_dev->dock_plug_gpio);
|
||||
exit:
|
||||
kfree(msm8994_liquid_dock_dev);
|
||||
msm8994_liquid_dock_dev = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void msm8994_ext_control(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
@ -1469,6 +1578,13 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return err;
|
||||
}
|
||||
|
||||
err = msm8994_liquid_init_docking();
|
||||
if (err) {
|
||||
pr_err("%s: 8994 init Docking stat IRQ failed (%d)\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = msm8994_ext_us_amp_init();
|
||||
if (err) {
|
||||
pr_err("%s: MTP 8994 US Emitter GPIO init failed (%d)\n",
|
||||
|
@ -2961,6 +3077,20 @@ static int msm8994_asoc_machine_remove(struct platform_device *pdev)
|
|||
|
||||
gpio_free(pdata->mclk_gpio);
|
||||
gpio_free(pdata->us_euro_gpio);
|
||||
|
||||
if (msm8994_liquid_dock_dev != NULL) {
|
||||
switch_dev_unregister(&msm8994_liquid_dock_dev->audio_sdev);
|
||||
|
||||
if (msm8994_liquid_dock_dev->dock_plug_irq)
|
||||
free_irq(msm8994_liquid_dock_dev->dock_plug_irq,
|
||||
msm8994_liquid_dock_dev);
|
||||
|
||||
if (msm8994_liquid_dock_dev->dock_plug_gpio)
|
||||
gpio_free(msm8994_liquid_dock_dev->dock_plug_gpio);
|
||||
|
||||
kfree(msm8994_liquid_dock_dev);
|
||||
msm8994_liquid_dock_dev = NULL;
|
||||
}
|
||||
msm_auxpcm_release_pinctrl(pdev, SEC_MI2S_PCM);
|
||||
msm_mi2s_release_pinctrl(pdev, PRI_MI2S_PCM);
|
||||
snd_soc_unregister_card(card);
|
||||
|
|
Loading…
Reference in a new issue