174 lines
7.2 KiB
C
174 lines
7.2 KiB
C
|
/***************************************************************************
|
||
|
* __________ __ ___.
|
||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||
|
* \/ \/ \/ \/ \/
|
||
|
* $Id$
|
||
|
*
|
||
|
* Copyright (C) 2014 by Amaury Pouly
|
||
|
*
|
||
|
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||
|
* KIND, either express or implied.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#ifndef __button_imx233__
|
||
|
#define __button_imx233__
|
||
|
|
||
|
#include "button.h"
|
||
|
#include "button-target.h"
|
||
|
#include "lradc-imx233.h"
|
||
|
#include "pinctrl-imx233.h"
|
||
|
#include "power-imx233.h"
|
||
|
|
||
|
/* special values for .btn field */
|
||
|
#define IMX233_BUTTON_END -1 /* end of the list */
|
||
|
#define IMX233_BUTTON_HOLD -2 /* HOLD button */
|
||
|
#define IMX233_BUTTON_JACK -3 /* JACK detect */
|
||
|
#define IMX233_BUTTON_VDDIO -4 /* VDDIO value */
|
||
|
|
||
|
/* values for .periph field */
|
||
|
#define IMX233_BUTTON_GPIO 0 /* GPIO pin */
|
||
|
#define IMX233_BUTTON_LRADC 1 /* LRADC channel */
|
||
|
#define IMX233_BUTTON_PSWITCH 2 /* PSWITCH */
|
||
|
|
||
|
/* values for the .flags field */
|
||
|
#define IMX233_BUTTON_INVERTED (1 << 0) /* invert button detection */
|
||
|
#define IMX233_BUTTON_PULLUP (1 << 1) /* pin needs a pullup (GPIO) */
|
||
|
|
||
|
/** target-defined
|
||
|
* NOTE for proper operation:
|
||
|
* - the table must end which a dummy entry of type IMX233_BUTTON_END
|
||
|
* - default is active: high for GPIO, around value for LRADC, exact value for PSWITCH
|
||
|
* - inverted flags reverses the above behaviour
|
||
|
* - if lradc channel is relative, the .relative field specify a entry in the
|
||
|
* button table to which it is relative. This entry must have <0 .btn value
|
||
|
* and be of type LRADC. For example, if a channel is VDDIO relative, set
|
||
|
* .relative to IMX233_BUTTON_VDDIO and create an entry which .btn set to
|
||
|
* IMX233_BUTTON_VDDIO, channel set to VDDIO source and value set to the ideal values
|
||
|
* for which no correction is necessary. Note that the IMX233_BUTTON_VDDIO value is
|
||
|
* defined for convenience */
|
||
|
struct imx233_button_map_t
|
||
|
{
|
||
|
int btn; /* target button or magic value (END, HOLD, JACK) */
|
||
|
int periph; /* GPIO, LRADC, or PSWITCH, ... */
|
||
|
union
|
||
|
{
|
||
|
struct
|
||
|
{
|
||
|
int bank;
|
||
|
int pin;
|
||
|
}gpio;
|
||
|
struct
|
||
|
{
|
||
|
int src; /* source channel */
|
||
|
int value; /* expected value */
|
||
|
int relative; /* button to which it is relative or -1 if none */
|
||
|
}lradc;
|
||
|
struct
|
||
|
{
|
||
|
int level; /* value of the PSWITCH field: low, mid, high */
|
||
|
}pswitch;
|
||
|
}u;
|
||
|
int flags; /* flags */
|
||
|
const char *name; /* name of the button */
|
||
|
/** private fields */
|
||
|
bool last_val; /* last interpreted value */
|
||
|
int rounds; /* how many rounds it survived (debouncing) */
|
||
|
int threshold; /* round threshold for acceptance */
|
||
|
};
|
||
|
|
||
|
/* macros for the common cases */
|
||
|
#define IMX233_BUTTON_PATH_GPIO(bank_, pin_) .periph = IMX233_BUTTON_GPIO, \
|
||
|
.u = {.gpio = {.bank = bank_, .pin = pin_}}
|
||
|
#define IMX233_BUTTON_PATH_LRADC_REL(src_, val_, rel_) .periph = IMX233_BUTTON_LRADC, \
|
||
|
.u = {.lradc = {.src = src_, .value = val_, .relative = rel_}}
|
||
|
#define IMX233_BUTTON_PATH_LRADC(src_, val_) IMX233_BUTTON_PATH_LRADC_REL(src_, val_, -1)
|
||
|
#define IMX233_BUTTON_PATH_PSWITCH(lvl_) .periph = IMX233_BUTTON_PSWITCH, \
|
||
|
.u = {.pswitch = {.level = lvl_}}
|
||
|
#define IMX233_BUTTON_PATH_END() .periph = -1
|
||
|
/* special macro for VDDIO, for convenience */
|
||
|
#define IMX233_BUTTON_PATH_VDDIO(val_) IMX233_BUTTON_PATH_LRADC(LRADC_SRC_VDDIO, val_)
|
||
|
|
||
|
#define IMX233_BUTTON_NAMEFLAGS1(_,name_) .name = name_
|
||
|
#define IMX233_BUTTON_NAMEFLAGS2(_,name_,f1) .name = name_, .flags = IMX233_BUTTON_##f1
|
||
|
#define IMX233_BUTTON_NAMEFLAGS3(_,name_,f1,f2) .name = name_, \
|
||
|
.flags = IMX233_BUTTON_##f1 | IMX233_BUTTON_##f2
|
||
|
#define IMX233_BUTTON_NAMEFLAGS4(_,name_,f1,f2,f3) .name = name_, \
|
||
|
.flags =IMX233_BUTTON_##f1 | IMX233_BUTTON_##f2 | IMX233_BUTTON_##f3
|
||
|
|
||
|
#define IMX233_BUTTON__(btn_, path_, ...) \
|
||
|
{.btn = btn_, IMX233_BUTTON_PATH_##path_, \
|
||
|
REG_VARIADIC(IMX233_BUTTON_NAMEFLAGS, dummy, __VA_ARGS__)}
|
||
|
#define IMX233_BUTTON_(btn_, path_, ...) \
|
||
|
IMX233_BUTTON__(IMX233_BUTTON_##btn_, path_, __VA_ARGS__)
|
||
|
#define IMX233_BUTTON(btn_, path_, ...) \
|
||
|
IMX233_BUTTON__(BUTTON_##btn_, path_, __VA_ARGS__)
|
||
|
|
||
|
#define IMX233_BUTTON_END_() \
|
||
|
{.btn = IMX233_BUTTON_END}
|
||
|
|
||
|
/**
|
||
|
* This header provides macro to ease definition of buttons. There three types of
|
||
|
* buttons:
|
||
|
* - normal buttons: BUTTON_X -> defined using IMX233_BUTTON(X, ...)
|
||
|
* - special buttons IMX233_BUTTON_X -> defined using IMX233_BUTTON_(X, ...)
|
||
|
* - others: X -> defined using IMX233_BUTTON__(X, ...)
|
||
|
* A definition contains three mandatory parts and a fourth optional:
|
||
|
* IMX233_BUTTON(btn, path_spec, name [, flags])
|
||
|
* The path_spec can be of the form:
|
||
|
* - GPIO(bank, pin)
|
||
|
* - LRADC(src, value)
|
||
|
* - LRADC_REL(src, value, rel_idx)
|
||
|
* - PSWITCH(level)
|
||
|
* - END()
|
||
|
* The optional flags are specified as a list, without the IMX233_BUTTON_ prefix.
|
||
|
* Examples:
|
||
|
* - BUTTON_POWER named "power", mapped to PSWITCH mid level, no flags:
|
||
|
* IMX233_BUTTON(POWER, PSWICTH(1), "power")
|
||
|
* - IMX233_BUTTON_JACK named "jack", mapped to GPIO B2P17 inverted and pullup:
|
||
|
* IMX233_BUTTON_(JACK, GPIO(2, 17), "jack", INVERTED, PULLUP)
|
||
|
* - BIZARRE named "bizarre", mapped to LRADC channel 0, expected value 42:
|
||
|
* IMX233_BUTTON__(BIZARRE, LRADC(0, 42), "bizarre")
|
||
|
* - BUTTON_PLAY named "play", mapped to LRADc channel 2, expected value 300 related
|
||
|
* to button entry IDX
|
||
|
* IMX233_BUTTON(PLAY, LRADC_REL(2, 300, IDX), "play")
|
||
|
* - VDDIO entry, expected value 4000 (for relative entries):
|
||
|
* IMX233_BUTTON_(VDDIO, VDDIO(4000), "vddio")
|
||
|
* - last entry:
|
||
|
* IMX233_BUTTON_(END, END(), "")
|
||
|
*
|
||
|
* The driver also provides default implementations for headphones_inserted()
|
||
|
* and button_hold() which can be overriden since they have weak linkage.
|
||
|
*/
|
||
|
|
||
|
extern struct imx233_button_map_t imx233_button_map[];
|
||
|
|
||
|
/* initialise button driver */
|
||
|
void imx233_button_init(void);
|
||
|
/* others gives the bitmask of other buttons: the function will OR the result
|
||
|
* with them except if hold is detected in which case 0 is always returned */
|
||
|
int imx233_button_read(int others);
|
||
|
#ifdef HAS_BUTTON_HOLD
|
||
|
bool imx233_button_read_hold(void);
|
||
|
bool button_hold(void);
|
||
|
#endif
|
||
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||
|
bool imx233_button_read_jack(void);
|
||
|
bool headphones_inserted(void);
|
||
|
#endif
|
||
|
/* return interpreted button value, after processing.
|
||
|
* Argument is an index into the imx233_button_map table */
|
||
|
bool imx233_button_read_btn(int idx);
|
||
|
/* return raw value for a button, before any processing: GPIO state, LRADC
|
||
|
* channel value, PSWITCH value. Return -1 if there is no match.
|
||
|
* Argument is an index into the imx233_button_map table */
|
||
|
int imx233_button_read_raw(int idx);
|
||
|
|
||
|
#endif /* __button_imx233__ */
|