summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/button-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/button-imx31.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
new file mode 100644
index 0000000000..32d2a63c49
--- /dev/null
+++ b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c
@@ -0,0 +1,180 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include "cpu.h"
22#include "system.h"
23#include "button.h"
24#include "kernel.h"
25#include "backlight.h"
26#include "adc.h"
27#include "system.h"
28#include "backlight-target.h"
29#include "debug.h"
30#include "stdio.h"
31
32/* Most code in here is taken from the Linux BSP provided by Freescale
33 * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */
34
35void button_init_device(void)
36{
37 unsigned int reg_val;
38 /* Enable keypad clock */
39 //mxc_clks_enable(KPP_CLK);
40
41 /* Enable number of rows in keypad (KPCR[7:0])
42 * Configure keypad columns as open-drain (KPCR[15:8])
43 *
44 * Configure the rows/cols in KPP
45 * LSB nibble in KPP is for 8 rows
46 * MSB nibble in KPP is for 8 cols
47 */
48 reg_val = KPP_KPCR;
49 reg_val |= (1 << 8) - 1; /* LSB */
50 reg_val |= ((1 << 8) - 1) << 8; /* MSB */
51 KPP_KPCR = reg_val;
52
53 /* Write 0's to KPDR[15:8] */
54 reg_val = KPP_KPDR;
55 reg_val &= 0x00ff;
56 KPP_KPDR = reg_val;
57
58 /* Configure columns as output, rows as input (KDDR[15:0]) */
59 KPP_KDDR = 0xff00;
60
61 reg_val = 0xD;
62 reg_val |= (1 << 8);
63 KPP_KPSR = reg_val;
64}
65
66inline bool button_hold(void)
67{
68 return GPIO3_DR & 0x10;
69}
70
71int button_read_device(void)
72{
73 unsigned short reg_val;
74 int col, row;
75 int button = BUTTON_NONE;
76
77 if(!button_hold()) {
78 for (col = 0; col < 3; col++) { /* Col */
79 /* 1. Write 1s to KPDR[15:8] setting column data to 1s */
80 reg_val = KPP_KPDR;
81 reg_val |= 0xff00;
82 KPP_KPDR = reg_val;
83
84 /*
85 * 2. Configure columns as totem pole outputs(for quick
86 * discharging of keypad capacitance)
87 */
88 reg_val = KPP_KPCR;
89 reg_val &= 0x00ff;
90 KPP_KPCR = reg_val;
91
92 /* Give the columns time to discharge */
93 udelay(2);
94
95 /* 3. Configure columns as open-drain */
96 reg_val = KPP_KPCR;
97 reg_val |= ((1 << 8) - 1) << 8;
98 KPP_KPCR = reg_val;
99
100 /* 4. Write a single column to 0, others to 1.
101 * 5. Sample row inputs and save data. Multiple key presses
102 * can be detected on a single column.
103 * 6. Repeat steps 1 - 5 for remaining columns.
104 */
105
106 /* Col bit starts at 8th bit in KPDR */
107 reg_val = KPP_KPDR;
108 reg_val &= ~(1 << (8 + col));
109 KPP_KPDR = reg_val;
110
111 /* Delay added to avoid propagating the 0 from column to row
112 * when scanning. */
113 udelay(2);
114
115 /* Read row input */
116 reg_val = KPP_KPDR;
117 for (row = 0; row < 5; row++) { /* sample row */
118 if (!(reg_val & (1 << row))) {
119 if(row == 0) {
120 if(col == 0) {
121 button |= BUTTON_LEFT;
122 }
123 if(col == 1) {
124 button |= BUTTON_BACK;
125 }
126 if(col == 2) {
127 button |= BUTTON_VOL_UP;
128 }
129 } else if(row == 1) {
130 if(col == 0) {
131 button |= BUTTON_UP;
132 }
133 if(col == 1) {
134 button |= BUTTON_MENU;
135 }
136 if(col == 2) {
137 button |= BUTTON_VOL_DOWN;
138 }
139 } else if(row == 2) {
140 if(col == 0) {
141 button |= BUTTON_DOWN;
142 }
143 if(col == 2) {
144 button |= BUTTON_PREV;
145 }
146 } else if(row == 3) {
147 if(col == 0) {
148 button |= BUTTON_RIGHT;
149 }
150 if(col == 2) {
151 button |= BUTTON_PLAY;
152 }
153 } else if(row == 4) {
154 if(col == 0) {
155 button |= BUTTON_SELECT;
156 }
157 if(col == 2) {
158 button |= BUTTON_NEXT;
159 }
160 }
161 }
162 }
163 }
164
165 /*
166 * 7. Return all columns to 0 in preparation for standby mode.
167 * 8. Clear KPKD and KPKR status bit(s) by writing to a .1.,
168 * set the KPKR synchronizer chain by writing "1" to KRSS register,
169 * clear the KPKD synchronizer chain by writing "1" to KDSC register
170 */
171 reg_val = 0x00;
172 KPP_KPDR = reg_val;
173 reg_val = KPP_KPDR;
174 reg_val = KPP_KPSR;
175 reg_val |= 0xF;
176 KPP_KPSR = reg_val;
177 }
178
179 return button;
180}