Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
mako: add the earjack debugger trigger
Only enable the uart console when detected earjack debugger.
Uart signal interferes audio signal. you might listen to noise via
headset. So this patch fixes this issue.

Change-Id: I9174f0f243043138304aced16b49c70ce317a2de
  • Loading branch information
dojipkim committed Sep 22, 2012
1 parent a8c7f6b commit 910a603
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 11 deletions.
5 changes: 3 additions & 2 deletions arch/arm/mach-msm/lge/mako/Makefile
Expand Up @@ -9,6 +9,7 @@ obj-$(CONFIG_MACH_APQ8064_MAKO) += board-mako.o \
board-mako-misc.o \
board-mako-sound.o \
board-mako-storage.o \
board-mako-nfc.o
board-mako-nfc.o \
board-mako-earjack-debugger.o

CFLAGS_board-mako-display.o += -Idrivers/video
CFLAGS_board-mako-display.o += -Idrivers/video
240 changes: 240 additions & 0 deletions arch/arm/mach-msm/lge/mako/board-mako-earjack-debugger.c
@@ -0,0 +1,240 @@
/*
* earjack debugger trigger
*
* Copyright (C) 2012 LGE, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/pm.h>

#include <mach/gpiomux.h>

#include "board-mako.h"
#include "board-mako-earjack-debugger.h"

#define MAKO_UART_TX_GPIO 10
#define MAKO_UART_RX_GPIO 11

static struct gpiomux_setting gsbi4_uart = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_NONE,
};

static struct gpiomux_setting gsbi4_gpio = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_NONE,
};

static bool mako_uart_initialized = false;

struct earjack_debugger_device {
int gpio;
int irq;
int saved_detect;
void (*set_uart_console)(int enable);
};

static void earjack_debugger_set_gpiomux_uart(int enable)
{
if (enable) {
msm_gpiomux_write(MAKO_UART_TX_GPIO, GPIOMUX_ACTIVE,
&gsbi4_uart, NULL);
msm_gpiomux_write(MAKO_UART_TX_GPIO, GPIOMUX_SUSPENDED,
&gsbi4_uart, NULL);
msm_gpiomux_write(MAKO_UART_RX_GPIO, GPIOMUX_ACTIVE,
&gsbi4_uart, NULL);
msm_gpiomux_write(MAKO_UART_RX_GPIO, GPIOMUX_SUSPENDED,
&gsbi4_uart, NULL);
} else {
msm_gpiomux_write(MAKO_UART_TX_GPIO, GPIOMUX_ACTIVE,
&gsbi4_gpio, NULL);
msm_gpiomux_write(MAKO_UART_TX_GPIO, GPIOMUX_SUSPENDED,
&gsbi4_gpio, NULL);
msm_gpiomux_write(MAKO_UART_RX_GPIO, GPIOMUX_ACTIVE,
&gsbi4_gpio, NULL);
msm_gpiomux_write(MAKO_UART_RX_GPIO, GPIOMUX_SUSPENDED,
&gsbi4_gpio, NULL);
}
}

static int earjack_debugger_detected(void *dev)
{
struct earjack_debugger_device *adev = dev;

return !!gpio_get_value(adev->gpio);
}

static void earjack_debugger_set_console(void *dev)
{
struct earjack_debugger_device *adev = dev;

if (earjack_debugger_detected(adev)) {
if (!mako_uart_initialized) {
mako_uart_initialized = true;
earjack_debugger_set_gpiomux_uart(1);
mdelay(1);
}
adev->set_uart_console(1);
} else {
adev->set_uart_console(0);
}
}

static irqreturn_t earjack_debugger_irq_handler(int irq, void *_dev)
{
struct earjack_debugger_device *adev = _dev;

earjack_debugger_set_console(adev);

return IRQ_HANDLED;
}

static int earjack_debugger_probe(struct platform_device *pdev)
{
int ret = 0;
struct earjack_debugger_device *adev;
struct earjack_debugger_platform_data *pdata =
pdev->dev.platform_data;

if (!pdata) {
pr_err("%s: no pdata\n", __func__);
return -ENODEV;
}

adev = kzalloc(sizeof(struct earjack_debugger_device), GFP_KERNEL);
if (!adev) {
pr_err("%s: no memory\n", __func__);
return -ENOMEM;
}

adev->gpio = pdata->gpio_trigger;
adev->irq = gpio_to_irq(pdata->gpio_trigger);
adev->set_uart_console = pdata->set_uart_console;

platform_set_drvdata(pdev, adev);

ret = gpio_request_one(adev->gpio, GPIOF_IN,
"gpio_earjack_debugger");
if (ret < 0) {
pr_err("%s: failed to request gpio %d\n", __func__,
adev->gpio);
goto err_gpio_request;
}

ret = request_threaded_irq(adev->irq, NULL, earjack_debugger_irq_handler,
IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,
"earjack_debugger_trigger", adev);
if (ret < 0) {
pr_err("%s: failed to request irq\n", __func__);
goto err_request_irq;
}

if (earjack_debugger_detected(adev)) {
if (adev->set_uart_console) {
mako_uart_initialized = true;
earjack_debugger_set_gpiomux_uart(1);
adev->set_uart_console(1);
}
} else {
earjack_debugger_set_gpiomux_uart(0);
}

pr_info("earjack debugger probed\n");

return ret;

err_request_irq:
gpio_free(adev->gpio);
err_gpio_request:
kfree(adev);

return ret;
}

static int earjack_debugger_remove(struct platform_device *pdev)
{
struct earjack_debugger_device *adev = platform_get_drvdata(pdev);

free_irq(adev->irq, adev);
gpio_free(adev->gpio);
kfree(adev);

return 0;
}

static void earjack_debugger_shutdown(struct platform_device *pdev)
{
struct earjack_debugger_device *adev = platform_get_drvdata(pdev);

disable_irq(adev->irq);
}

static int earjack_debugger_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct earjack_debugger_device *adev = platform_get_drvdata(pdev);

disable_irq(adev->irq);
adev->saved_detect = earjack_debugger_detected(adev);

return 0;
}

static int earjack_debugger_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct earjack_debugger_device *adev = platform_get_drvdata(pdev);
int detect = 0;

detect = earjack_debugger_detected(adev);
if (detect != adev->saved_detect)
earjack_debugger_set_console(adev);
enable_irq(adev->irq);

return 0;
}

static const struct dev_pm_ops earjack_debugger_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(earjack_debugger_suspend,
earjack_debugger_resume)
};

static struct platform_driver earjack_debugger_driver = {
.probe = earjack_debugger_probe,
.remove = earjack_debugger_remove,
.shutdown = earjack_debugger_shutdown,
.driver = {
.name = "earjack-debugger-trigger",
.pm = &earjack_debugger_pm_ops,
},
};

static int __init earjack_debugger_init(void)
{
return platform_driver_register(&earjack_debugger_driver);
}

subsys_initcall_sync(earjack_debugger_init);
23 changes: 23 additions & 0 deletions arch/arm/mach-msm/lge/mako/board-mako-earjack-debugger.h
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2012 LGE, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 __EARJACK_DEBUGGER_H
#define __EARJACK_DEBUGGER_H

struct earjack_debugger_platform_data {
int gpio_trigger;
void (*set_uart_console)(int enable);
};

#endif
1 change: 1 addition & 0 deletions arch/arm/mach-msm/lge/mako/board-mako-pmic.c
Expand Up @@ -119,6 +119,7 @@ struct pm8xxx_mpp_init {

/* Initial PM8921 GPIO configurations */
static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
PM8921_GPIO_INPUT(13, PM_GPIO_PULL_DN), /* EARJACK_DEBUGGER */
PM8921_GPIO_INPUT(14, PM_GPIO_PULL_DN), /* SLIMPORT_CBL_DET */
PM8921_GPIO_OUTPUT(15, 0, HIGH), /* ANX_P_DWN_CTL */
PM8921_GPIO_OUTPUT(16, 0, HIGH), /* ANX_AVDD33_EN */
Expand Down
33 changes: 24 additions & 9 deletions arch/arm/mach-msm/lge/mako/board-mako-sound.c
Expand Up @@ -26,6 +26,7 @@
#endif

#include "board-mako.h"
#include "board-mako-earjack-debugger.h"


#define TPA2028D_ADDRESS (0xB0>>1)
Expand Down Expand Up @@ -170,10 +171,12 @@ int mako_console_stopped(void)
return !console_enabled;
}

static void fsa8008_set_uart_console(int enable)
static void set_uart_console(int enable)
{
static struct console *uart_con = NULL;

console_enabled = enable;

if (!uart_con) {
struct console *con;
for_each_console(con) {
Expand All @@ -189,7 +192,6 @@ static void fsa8008_set_uart_console(int enable)
return;
}

console_enabled = enable;
if (enable)
console_start(uart_con);
else
Expand All @@ -210,7 +212,7 @@ static struct fsa8008_platform_data lge_hs_pdata = {

.latency_for_detection = 75,
.set_headset_mic_bias = enable_external_mic_bias,
.set_uart_console = fsa8008_set_uart_console,
.set_uart_console = set_uart_console,
};

static struct platform_device lge_hsd_device = {
Expand All @@ -221,14 +223,27 @@ static struct platform_device lge_hsd_device = {
},
};

static int __init lge_hsd_fsa8008_init(void)
{
printk(KERN_INFO "lge_hsd_fsa8008_init\n");
return platform_device_register(&lge_hsd_device);
}
#define GPIO_EARJACK_DEBUGGER_TRIGGER PM8921_GPIO_PM_TO_SYS(13)
static struct earjack_debugger_platform_data earjack_debugger_pdata = {
.gpio_trigger = GPIO_EARJACK_DEBUGGER_TRIGGER,
.set_uart_console = set_uart_console,
};

static struct platform_device earjack_debugger_device = {
.name = "earjack-debugger-trigger",
.id = -1,
.dev = {
.platform_data = &earjack_debugger_pdata,
},
};

static struct platform_device *sound_devices[] __initdata = {
&lge_hsd_device,
&earjack_debugger_device,
};

void __init lge_add_sound_devices(void)
{
lge_add_i2c_tpa2028d_devices();
lge_hsd_fsa8008_init();
platform_add_devices(sound_devices, ARRAY_SIZE(sound_devices));
}

0 comments on commit 910a603

Please sign in to comment.