blob: d3dc6ac643c47e82ee58e43250a1e264add66894 [file] [log] [blame] [edit]
/* Board support file for Samsung Tuna Board.
*
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2010 Texas Instruments
*
* Based on mach-omap2/board-omap4panda.c
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/i2c/twl6030-madc.h>
#include <linux/sec_jack.h>
#include "mux.h"
#include "board-tuna.h"
#define GPIO_EAR_MICBIAS_EN 49
#define GPIO_DET_35 0
#define GPIO_EAR_SEND_END 1
#define ADC_CHANNEL_JACK 2
static void sec_jack_set_micbias_state(bool on)
{
gpio_set_value(GPIO_EAR_MICBIAS_EN, on);
}
static struct sec_jack_zone sec_jack_zones[] = {
{
/* adc < 50, unstable zone, default to 3pole if it stays
* in this range for a half second (20ms delays, 25 samples)
*/
.adc_high = 50,
.delay_ms = 20,
.check_count = 25,
.jack_type = SEC_HEADSET_3POLE,
},
{
/* 50 < adc <= 490, unstable zone, default to 3pole if it stays
* in this range for a second (10ms delays, 100 samples)
*/
.adc_high = 490,
.delay_ms = 10,
.check_count = 100,
.jack_type = SEC_HEADSET_3POLE,
},
{
/* 490 < adc <= 900, unstable zone, default to 4pole if it
* stays in this range for a second (10ms delays, 100 samples)
*/
.adc_high = 900,
.delay_ms = 10,
.check_count = 100,
.jack_type = SEC_HEADSET_4POLE,
},
{
/* 900 < adc <= 1500, 4 pole zone, default to 4pole if it
* stays in this range for 200ms (20ms delays, 10 samples)
*/
.adc_high = 1500,
.delay_ms = 20,
.check_count = 10,
.jack_type = SEC_HEADSET_4POLE,
},
{
/* adc > 1500, unstable zone, default to 3pole if it stays
* in this range for a second (10ms delays, 100 samples)
*/
.adc_high = 0x7fffffff,
.delay_ms = 10,
.check_count = 100,
.jack_type = SEC_HEADSET_3POLE,
},
};
/* To support 3-buttons earjack */
static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = {
{
/* 0 <= adc <= 93, stable zone */
.code = KEY_MEDIA,
.adc_low = 0,
.adc_high = 93,
},
{
/* 94 <= adc <= 167, stable zone */
.code = KEY_PREVIOUSSONG,
.adc_low = 94,
.adc_high = 167,
},
{
/* 168 <= adc <= 370, stable zone */
.code = KEY_NEXTSONG,
.adc_low = 168,
.adc_high = 370,
},
};
static int sec_jack_get_adc_value(void)
{
int value;
value = twl6030_get_madc_conversion(ADC_CHANNEL_JACK);
return (int)(1800*value) / 1024;
}
struct sec_jack_platform_data sec_jack_pdata = {
.set_micbias_state = sec_jack_set_micbias_state,
.get_adc_value = sec_jack_get_adc_value,
.zones = sec_jack_zones,
.num_zones = ARRAY_SIZE(sec_jack_zones),
.buttons_zones = sec_jack_buttons_zones,
.num_buttons_zones = ARRAY_SIZE(sec_jack_buttons_zones),
.det_gpio = GPIO_DET_35,
.send_end_gpio = GPIO_EAR_SEND_END,
};
static struct platform_device sec_device_jack = {
.name = "sec_jack",
.id = 1, /* will be used also for gpio_event id */
.dev.platform_data = &sec_jack_pdata,
};
void __init omap4_tuna_jack_init(void)
{
omap_mux_init_signal("sim_io.gpio_wk0", OMAP_PIN_INPUT);
gpio_request(GPIO_DET_35, "det_35_en");
gpio_direction_input(GPIO_DET_35);
omap_mux_init_signal("sim_clk.gpio_wk1", OMAP_PIN_INPUT);
gpio_request(GPIO_EAR_SEND_END, "ear_send_end");
gpio_direction_input(GPIO_EAR_SEND_END);
omap_mux_init_signal("gpmc_a25.gpio_49", OMAP_PIN_OUTPUT | OMAP_MUX_MODE3);
gpio_request(GPIO_EAR_MICBIAS_EN, "ear_micbias_en");
gpio_direction_output(GPIO_EAR_MICBIAS_EN, 0);
gpio_free(GPIO_DET_35);
gpio_free(GPIO_EAR_SEND_END);
platform_device_register(&sec_device_jack);
}