// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 */

/*!
 * @file mxc_keyb.c
 *
 * @brief Driver for the Freescale Semiconductor MXC keypad port.
 *
 * The keypad driver is designed as a standard Input driver which interacts
 * with low level keypad port hardware. Upon opening, the Keypad driver
 * initializes the keypad port. When the keypad interrupt happens the driver
 * calles keypad polling timer and scans the keypad matrix for key
 * press/release. If all key press/release happened it comes out of timer and
 * waits for key press interrupt. The scancode for key press and release events
 * are passed to Input subsytem.
 *
 * @ingroup keypad
 */

#include <asm/io.h>
#include <common.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/mach-imx/mxc_key_defs.h>
#include <malloc.h>

/*
 *  * Module header file
 *   */
#include <mxc_keyb.h>

/*!
 * Comment KPP_DEBUG to disable debug messages
 */

#undef	KPP_DEBUG

#ifdef	KPP_DEBUG
#define	KPP_PRINTF(fmt, args...)	printf(fmt , ##args)

static void mxc_kpp_dump_regs()
{
	unsigned short t1, t2, t3;

	t1 = __raw_readw(KPCR);
	t2 = __raw_readw(KPSR);
	t3 = __raw_readw(KDDR);
	/*
	KPP_PRINTF("KPCR=0x%04x, KPSR=0x%04x, KDDR=0x%04x\n",
		t1, t2, t3);
		*/
}
#else
#define KPP_PRINTF(fmt, args...)
#endif

static u16 mxc_key_mapping[] = CONFIG_MXC_KEYMAPPING;

/*!
 * This structure holds the keypad private data structure.
 */
static struct keypad_priv kpp_dev;

/*! Indicates if the key pad device is enabled. */

/*! This static variable indicates whether a key event is pressed/released. */
static unsigned short KPress;

/*! cur_rcmap and prev_rcmap array is used to detect key press and release. */
static unsigned short *cur_rcmap;	/* max 64 bits (8x8 matrix) */
static unsigned short *prev_rcmap;

/*!
 * Debounce polling period(10ms) in system ticks.
 */
/*static unsigned short KScanRate = (10 * CONFIG_SYS_HZ) / 1000;*/

/*!
 * These arrays are used to store press and release scancodes.
 */
static short **press_scancode;
static short **release_scancode;

static const unsigned short *mxckpd_keycodes;
static unsigned short mxckpd_keycodes_size;

/*!
 * This function is called to scan the keypad matrix to find out the key press
 * and key release events. Make scancode and break scancode are generated for
 * key press and key release events.
 *
 * The following scanning sequence are done for
 * keypad row and column scanning,
 * -# Write 1's to KPDR[15:8], setting column data to 1's
 * -# Configure columns as totem pole outputs(for quick discharging of keypad
 * capacitance)
 * -# Configure columns as open-drain
 * -# Write a single column to 0, others to 1.
 * -# Sample row inputs and save data. Multiple key presses can be detected on
 * a single column.
 * -# Repeat steps the above steps for remaining columns.
 * -# Return all columns to 0 in preparation for standby mode.
 * -# Clear KPKD and KPKR status bit(s) by writing to a 1,
 *    Set the KPKR synchronizer chain by writing "1" to KRSS register,
 *    Clear the KPKD synchronizer chain by writing "1" to KDSC register
 *
 * @result    Number of key pressed/released.
 */
static int mxc_kpp_scan_matrix(void)
{
	unsigned short reg_val;
	int col, row;
	short scancode = 0;
	int keycnt = 0;		/* How many keys are still pressed */

	/*
	 * wmb() linux kernel function which guarantees orderings in write
	 * operations
	 */
	/* wmb(); */

	/* save cur keypad matrix to prev */
	memcpy(prev_rcmap, cur_rcmap, kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));
	memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));

	/*1. Disable both (depress and release) keypad interrupts.*/

	/* KDIE has been disabled in mxc_kpp_getc before calling scan matrix.
	  * KRIE is always disabled in this driver.
	  */

	for (col = 0; col < kpp_dev.kpp_cols; col++) {	/* Col */
		/* 2. Write 1.s to KPDR[15:8] setting column data to 1.s */
		reg_val = __raw_readw(KPDR);
		reg_val |= 0xff00;
		__raw_writew(reg_val, KPDR);

		/*
		 * 3. Configure columns as totem pole outputs(for quick
		 * discharging of keypad capacitance)
		 */
		reg_val = __raw_readw(KPCR);
		reg_val &= 0x00ff;
		__raw_writew(reg_val, KPCR);

		udelay(2);

#ifdef KPP_DEBUG
		mxc_kpp_dump_regs();
#endif

		/*
		 * 4. Configure columns as open-drain
		 */
		reg_val = __raw_readw(KPCR);
		reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8;
		__raw_writew(reg_val, KPCR);

		/*
		 * 5. Write a single column to 0, others to 1.
		 * 6. Sample row inputs and save data. Multiple key presses
		 * can be detected on a single column.
		 * 7. Repeat steps 2 - 6 for remaining columns.
		 */

		/* Col bit starts at 8th bit in KPDR */
		reg_val = __raw_readw(KPDR);
		reg_val &= ~(1 << (8 + col));
		__raw_writew(reg_val, KPDR);

		/* Delay added to avoid propagating the 0 from column to row
		 * when scanning. */

		udelay(5);

#ifdef KPP_DEBUG
		mxc_kpp_dump_regs();
#endif

		/* Read row input */
		reg_val = __raw_readw(KPDR);
		for (row = 0; row < kpp_dev.kpp_rows; row++) {	/* sample row */
			if (TEST_BIT(reg_val, row) == 0) {
				cur_rcmap[row] = BITSET(cur_rcmap[row], col);
				keycnt++;
			}
		}
	}

	/*
	 * 8. Return all columns to 0 in preparation for standby mode.
	 * 9. Clear KPKD and KPKR status bit(s) by writing to a .1.,
	 * set the KPKR synchronizer chain by writing "1" to KRSS register,
	 * clear the KPKD synchronizer chain by writing "1" to KDSC register
	 */
	reg_val = 0x00;
	__raw_writew(reg_val, KPDR);
	reg_val = __raw_readw(KPDR);
	reg_val = __raw_readw(KPSR);
	reg_val |= KBD_STAT_KPKD | KBD_STAT_KPKR | KBD_STAT_KRSS |
	    KBD_STAT_KDSC;
	__raw_writew(reg_val, KPSR);

#ifdef KPP_DEBUG
	mxc_kpp_dump_regs();
#endif

	/* Check key press status change */

	/*
	 * prev_rcmap array will contain the previous status of the keypad
	 * matrix.  cur_rcmap array will contains the present status of the
	 * keypad matrix. If a bit is set in the array, that (row, col) bit is
	 * pressed, else it is not pressed.
	 *
	 * XORing these two variables will give us the change in bit for
	 * particular row and column.  If a bit is set in XOR output, then that
	 * (row, col) has a change of status from the previous state.  From
	 * the diff variable the key press and key release of row and column
	 * are found out.
	 *
	 * If the key press is determined then scancode for key pressed
	 * can be generated using the following statement:
	 *    scancode = ((row * 8) + col);
	 *
	 * If the key release is determined then scancode for key release
	 * can be generated using the following statement:
	 *    scancode = ((row * 8) + col) + MXC_KEYRELEASE;
	 */
	for (row = 0; row < kpp_dev.kpp_rows; row++) {
		unsigned char diff;

		/*
		 * Calculate the change in the keypad row status
		 */
		diff = prev_rcmap[row] ^ cur_rcmap[row];

		for (col = 0; col < kpp_dev.kpp_cols; col++) {
			if ((diff >> col) & 0x1) {
				/* There is a status change on col */
				if ((prev_rcmap[row] & BITSET(0, col)) == 0) {
					/*
					 * Previous state is 0, so now
					 * a key is pressed
					 */
					scancode =
					    ((row * kpp_dev.kpp_cols) +
					     col);
					KPress = 1;
					kpp_dev.iKeyState = KStateUp;

					KPP_PRINTF("Press   (%d, %d) scan=%d "
						 "Kpress=%d\n",
						 row, col, scancode, KPress);
					press_scancode[row][col] =
					    (short)scancode;
				} else {
					/*
					 * Previous state is not 0, so
					 * now a key is released
					 */
					scancode =
					    (row * kpp_dev.kpp_cols) +
					    col + MXC_KEYRELEASE;
					KPress = 0;
					kpp_dev.iKeyState = KStateDown;

					KPP_PRINTF
					    ("Release (%d, %d) scan=%d Kpress=%d\n",
					     row, col, scancode, KPress);
					release_scancode[row][col] =
					    (short)scancode;
					keycnt++;
				}
			}
		}
	}

	return keycnt;
}

static int mxc_kpp_reset(void)
{
	unsigned short reg_val;
	int i;

	/*
	* Stop scanning and wait for interrupt.
	* Enable press interrupt and disable release interrupt.
	*/
	__raw_writew(0x00FF, KPDR);
	reg_val = __raw_readw(KPSR);
	reg_val |= (KBD_STAT_KPKR | KBD_STAT_KPKD);
	reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC;
	__raw_writew(reg_val, KPSR);
	reg_val |= KBD_STAT_KDIE;
	reg_val &= ~KBD_STAT_KRIE;
	__raw_writew(reg_val, KPSR);

#ifdef KPP_DEBUG
	mxc_kpp_dump_regs();
#endif

	/*
	* No more keys pressed... make sure unwanted key codes are
	* not given upstairs
	*/
	for (i = 0; i < kpp_dev.kpp_rows; i++) {
		memset(press_scancode[i], -1,
			sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols);
		memset(release_scancode[i], -1,
			sizeof(release_scancode[0][0]) *
			kpp_dev.kpp_cols);
	}

	return 0;
}

int mxc_kpp_getc(struct kpp_key_info **key_info)
{
	int col, row;
	int key_cnt;
	unsigned short reg_val;
	short scancode = 0;
	int index = 0;
	struct kpp_key_info *keyi;

	reg_val = __raw_readw(KPSR);

	if (reg_val & KBD_STAT_KPKD) {
		/*
		* Disable key press(KDIE status bit) interrupt
		*/
		reg_val &= ~KBD_STAT_KDIE;
		__raw_writew(reg_val, KPSR);

#ifdef KPP_DEBUG
		mxc_kpp_dump_regs();
#endif

		key_cnt = mxc_kpp_scan_matrix();
	} else {
		return 0;
	}

	if (key_cnt <= 0)
		return 0;

	*key_info = keyi =
		(struct kpp_key_info *)malloc
		(sizeof(struct kpp_key_info) * key_cnt);

	/*
	* This switch case statement is the
	* implementation of state machine of debounc
	* logic for key press/release.
	* The explaination of state machine is as
	* follows:
	*
	* KStateUp State:
	* This is in intial state of the state machine
	* this state it checks for any key presses.
	* The key press can be checked using the
	* variable KPress. If KPress is set, then key
	* press is identified and switches the to
	* KStateFirstDown state for key press to
	* debounce.
	*
	* KStateFirstDown:
	* After debounce delay(10ms), if the KPress is
	* still set then pass scancode generated to
	* input device and change the state to
	* KStateDown, else key press debounce is not
	* satisfied so change the state to KStateUp.
	*
	* KStateDown:
	* In this state it checks for any key release.
	* If KPress variable is cleared, then key
	* release is indicated and so, switch the
	* state to KStateFirstUp else to state
	* KStateDown.
	*
	* KStateFirstUp:
	* After debounce delay(10ms), if the KPress is
	* still reset then pass the key release
	* scancode to input device and change
	* the state to KStateUp else key release is
	* not satisfied so change the state to
	* KStateDown.
	*/

	for (row = 0; row < kpp_dev.kpp_rows; row++) {
		for (col = 0; col < kpp_dev.kpp_cols; col++) {
			if ((press_scancode[row][col] != -1)) {
				/* Still Down, so add scancode */
				scancode =
				    press_scancode[row][col];

				keyi[index].val = mxckpd_keycodes[scancode];
				keyi[index++].evt = KDepress;

				KPP_PRINTF("KStateFirstDown: scan=%d val=%d\n",
					scancode, mxckpd_keycodes[scancode]);
				if (index >= key_cnt)
					goto key_detect;

				kpp_dev.iKeyState = KStateDown;
				press_scancode[row][col] = -1;
			}
		}
	}

	for (row = 0; row < kpp_dev.kpp_rows; row++) {
		for (col = 0; col < kpp_dev.kpp_cols; col++) {
			if ((release_scancode[row][col] != -1)) {
				scancode =
				    release_scancode[row][col];
				scancode =
					scancode - MXC_KEYRELEASE;

				keyi[index].val = mxckpd_keycodes[scancode];
				keyi[index++].evt = KRelease;

				KPP_PRINTF("KStateFirstUp: scan=%d val=%d\n",
					scancode, mxckpd_keycodes[scancode]);
				if (index >= key_cnt)
					goto key_detect;

				kpp_dev.iKeyState = KStateUp;
				release_scancode[row][col] = -1;
			}
		}
	}

key_detect:
	mxc_kpp_reset();
	return key_cnt;
}

/*!
 * This function is called to free the allocated memory for local arrays
 */
static void mxc_kpp_free_allocated(void)
{
	int i;

	if (press_scancode) {
		for (i = 0; i < kpp_dev.kpp_rows; i++) {
			if (press_scancode[i])
				free(press_scancode[i]);
		}
		free(press_scancode);
	}

	if (release_scancode) {
		for (i = 0; i < kpp_dev.kpp_rows; i++) {
			if (release_scancode[i])
				free(release_scancode[i]);
		}
		free(release_scancode);
	}

	if (cur_rcmap)
		free(cur_rcmap);

	if (prev_rcmap)
		free(prev_rcmap);
}

/*!
 * This function is called during the driver binding process.
 *
 * @param   pdev  the device structure used to store device specific
 *                information that is used by the suspend, resume and remove
 *                functions.
 *
 * @return  The function returns 0 on successful registration. Otherwise returns
 *          specific error code.
 */
int mxc_kpp_init(void)
{
	int i;
	int retval;
	unsigned int reg_val;

	kpp_dev.kpp_cols = CONFIG_MXC_KPD_COLMAX;
	kpp_dev.kpp_rows = CONFIG_MXC_KPD_ROWMAX;

	/* clock and IOMUX configuration for keypad */
	setup_mxc_kpd();

	/* Configure keypad */

	/* Enable number of rows in keypad (KPCR[7:0])
	 * Configure keypad columns as open-drain (KPCR[15:8])
	 *
	 * Configure the rows/cols in KPP
	 * LSB nibble in KPP is for 8 rows
	 * MSB nibble in KPP is for 8 cols
	 */
	reg_val = __raw_readw(KPCR);
	reg_val |= (1  << kpp_dev.kpp_rows) - 1;	/* LSB */
	reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8;	/* MSB */
	__raw_writew(reg_val, KPCR);

	/* Write 0's to KPDR[15:8] */
	reg_val = __raw_readw(KPDR);
	reg_val &= 0x00ff;
	__raw_writew(reg_val, KPDR);

	/* Configure columns as output,
	 * rows as input (KDDR[15:0]) */
	reg_val = __raw_readw(KDDR);
	reg_val |= 0xff00;
	reg_val &= 0xff00;
	__raw_writew(reg_val, KDDR);

	/* Clear the KPKD Status Flag
	 * and Synchronizer chain. */
	reg_val = __raw_readw(KPSR);
	reg_val &= ~(KBD_STAT_KPKR | KBD_STAT_KPKD);
	reg_val |= KBD_STAT_KPKD;
	reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC;
	__raw_writew(reg_val, KPSR);
	/* Set the KDIE control bit, and clear the KRIE
	 * control bit (avoid false release events). */
	reg_val |= KBD_STAT_KDIE;
	reg_val &= ~KBD_STAT_KRIE;
	__raw_writew(reg_val, KPSR);

#ifdef KPP_DEBUG
	mxc_kpp_dump_regs();
#endif

	mxckpd_keycodes = mxc_key_mapping;
	mxckpd_keycodes_size = kpp_dev.kpp_cols * kpp_dev.kpp_rows;

	if ((mxckpd_keycodes == (void *)0)
	    || (mxckpd_keycodes_size == 0)) {
		retval = -ENODEV;
		goto err;
	}

	/* allocate required memory */
	press_scancode   = (short **)malloc(kpp_dev.kpp_rows * sizeof(press_scancode[0]));
	release_scancode = (short **)malloc(kpp_dev.kpp_rows * sizeof(release_scancode[0]));

	if (!press_scancode || !release_scancode) {
		retval = -ENOMEM;
		goto err;
	}

	for (i = 0; i < kpp_dev.kpp_rows; i++) {
		press_scancode[i] = (short *)malloc(kpp_dev.kpp_cols
					    * sizeof(press_scancode[0][0]));
		release_scancode[i] =
		    (short *)malloc(kpp_dev.kpp_cols * sizeof(release_scancode[0][0]));

		if (!press_scancode[i] || !release_scancode[i]) {
			retval = -ENOMEM;
			goto err;
		}
	}

	cur_rcmap =
	    (unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
	prev_rcmap =
	    (unsigned short *)malloc(kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));

	if (!cur_rcmap || !prev_rcmap) {
		retval = -ENOMEM;
		goto err;
	}

	for (i = 0; i < kpp_dev.kpp_rows; i++) {
		memset(press_scancode[i], -1,
		       sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols);
		memset(release_scancode[i], -1,
		       sizeof(release_scancode[0][0]) * kpp_dev.kpp_cols);
	}
	memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0]));
	memset(prev_rcmap, 0, kpp_dev.kpp_rows * sizeof(prev_rcmap[0]));

	return 0;

err:
	mxc_kpp_free_allocated();
	return retval;
}
