/* include/linux/gpio_event.h
 *
 * Copyright (C) 2007 Google, 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 _LINUX_GPIO_EVENT_H
#define _LINUX_GPIO_EVENT_H

#include <linux/input.h>

enum {
	GPIO_EVENT_FUNC_UNINIT  = 0x0,
	GPIO_EVENT_FUNC_INIT    = 0x1,
	GPIO_EVENT_FUNC_SUSPEND = 0x2,
	GPIO_EVENT_FUNC_RESUME  = 0x3,
};
struct gpio_event_info {
	int (*func)(struct input_dev *input_dev,
		    struct gpio_event_info *info,
		    void **data, int func);
	int (*event)(struct input_dev *input_dev,
		     struct gpio_event_info *info,
		     void **data, unsigned int type,
		     unsigned int code, int value); /* out events */
};

struct gpio_event_platform_data {
	const char *name;
	struct gpio_event_info **info;
	size_t info_count;
	int (*power)(const struct gpio_event_platform_data *pdata, bool on);
};

#define GPIO_EVENT_DEV_NAME "gpio-event"

/* Key matrix */

enum gpio_event_matrix_flags {
	/* unset: drive active output low, set: drive active output high */
	GPIOKPF_ACTIVE_HIGH              = 1U << 0,
	GPIOKPF_DEBOUNCE                 = 1U << 1,
	GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
	GPIOKPF_REMOVE_PHANTOM_KEYS      = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
					   GPIOKPF_DEBOUNCE,
	GPIOKPF_DRIVE_INACTIVE           = 1U << 3,
	GPIOKPF_LEVEL_TRIGGERED_IRQ      = 1U << 4,
	GPIOKPF_PRINT_UNMAPPED_KEYS      = 1U << 16,
	GPIOKPF_PRINT_MAPPED_KEYS        = 1U << 17,
	GPIOKPF_PRINT_PHANTOM_KEYS       = 1U << 18,
};

extern int gpio_event_matrix_func(struct input_dev *input_dev,
			struct gpio_event_info *info, void **data, int func);
struct gpio_event_matrix_info {
	/* initialize to gpio_event_matrix_func */
	struct gpio_event_info info;
	/* size must be ninputs * noutputs */
	const unsigned short *keymap;
	unsigned int *input_gpios;
	unsigned int *output_gpios;
	unsigned int ninputs;
	unsigned int noutputs;
	/* time to wait before reading inputs after driving each output */
	ktime_t settle_time;
	/* time to wait before scanning the keypad a second time */
	ktime_t debounce_delay;
	ktime_t poll_time;
	unsigned flags;
};

/* Directly connected inputs and outputs */

enum gpio_event_direct_flags {
	GPIOEDF_ACTIVE_HIGH         = 1U << 0,
/*	GPIOEDF_USE_DOWN_IRQ        = 1U << 1, */
/*	GPIOEDF_USE_IRQ             = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
	GPIOEDF_PRINT_KEYS          = 1U << 8,
	GPIOEDF_PRINT_KEY_DEBOUNCE  = 1U << 9,
};

struct gpio_event_direct_entry {
	uint32_t gpio:23;
	uint32_t code:9;
};

/* inputs */
extern int gpio_event_input_func(struct input_dev *input_dev,
			struct gpio_event_info *info, void **data, int func);
struct gpio_event_input_info {
	/* initialize to gpio_event_input_func */
	struct gpio_event_info info;
	ktime_t debounce_time;
	ktime_t poll_time;
	uint16_t flags;
	uint16_t type;
	const struct gpio_event_direct_entry *keymap;
	size_t keymap_size;
};

/* outputs */
extern int gpio_event_output_func(struct input_dev *input_dev,
			struct gpio_event_info *info, void **data, int func);
extern int gpio_event_output_event(struct input_dev *input_dev,
			struct gpio_event_info *info, void **data,
			unsigned int type, unsigned int code, int value);
struct gpio_event_output_info {
	/* initialize to gpio_event_output_func and gpio_event_output_event */
	struct gpio_event_info info;
	uint16_t flags;
	uint16_t type;
	const struct gpio_event_direct_entry *keymap;
	size_t keymap_size;
};


/* axes */

enum gpio_event_axis_flags {
	GPIOEAF_PRINT_UNKNOWN_DIRECTION  = 1U << 16,
	GPIOEAF_PRINT_RAW                = 1U << 17,
	GPIOEAF_PRINT_EVENT              = 1U << 18,
};

extern int gpio_event_axis_func(struct input_dev *input_dev,
			struct gpio_event_info *info, void **data, int func);
struct gpio_event_axis_info {
	/* initialize to gpio_event_axis_func */
	struct gpio_event_info info;
	uint8_t  count;
	uint8_t  type; /* EV_REL or EV_ABS */
	uint16_t code;
	uint16_t decoded_size;
	uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
	uint32_t *gpio;
	uint32_t flags;
};
#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
uint16_t gpio_axis_4bit_gray_map(
			struct gpio_event_axis_info *info, uint16_t in);
uint16_t gpio_axis_5bit_singletrack_map(
			struct gpio_event_axis_info *info, uint16_t in);

#endif
