Add a BTN_MASK for the VX777 (aka fix red)
[kugel-rb.git] / firmware / target / mips / ingenic_jz47xx / onda_vx747 / sadc-onda_vx747.c
blob5695e2533ecd051ef43c88861356a5612b260b93
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Maurus Cuelenaere
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include "system.h"
24 #include "jz4740.h"
25 #include "button.h"
26 #include "button-target.h"
27 #include "powermgmt.h"
28 #include "kernel.h"
29 #include "backlight.h"
30 #include "logf.h"
31 #include "adc.h"
33 #ifdef ONDA_VX747
34 #define BTN_OFF (1 << 29)
35 #define BTN_VOL_DOWN (1 << 27)
36 #define BTN_HOLD (1 << 16)
37 #define BTN_MENU (1 << 1)
38 #define BTN_VOL_UP (1 << 0)
40 #define BTN_MASK (BTN_OFF | BTN_VOL_DOWN | \
41 BTN_MENU | BTN_VOL_UP)
42 #elif defined(ONDA_VX747P)
43 #define BTN_OFF (1 << 29)
44 #define BTN_VOL_DOWN (1 << 27)
45 #define BTN_HOLD (1 << 22) /* on REG_GPIO_PXPIN(2) */
46 #define BTN_MENU (1 << 20)
47 #define BTN_VOL_UP (1 << 19)
49 #define BTN_MASK (BTN_OFF | BTN_VOL_DOWN | \
50 BTN_MENU | BTN_VOL_UP)
51 #elif defined(ONDA_VX777)
52 #define BTN_OFF (1 << 29)
54 #define BTN_MASK (BTN_OFF)
55 #else
56 #error No buttons defined!
57 #endif
60 #define TS_AD_COUNT 3
61 #define SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
63 #define SADC_CFG_INIT ( \
64 (2 << SADC_CFG_CLKOUT_NUM_BIT) | \
65 SADC_CFG_XYZ1Z2 | \
66 SADC_CFG_SNUM | \
67 (1 << SADC_CFG_CLKDIV_BIT) | \
68 SADC_CFG_PBAT_HIGH | \
69 SADC_CFG_CMD_INT_PEN \
72 static signed int x_pos, y_pos;
73 static int datacount = 0;
74 static volatile int cur_touch = 0;
75 static volatile bool pen_down = false;
76 static struct mutex battery_mtx;
77 static struct wakeup battery_wkup;
79 const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
81 /* TODO */
82 1600
85 const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
87 /* TODO */
88 1500
91 /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
92 const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
94 /* TODO */
95 { 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400 },
98 /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
99 const unsigned short percent_to_volt_charge[11] =
101 /* TODO */
102 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400
105 /* VBAT = (BDATA/4096) * 7.5V */
106 #define BATTERY_SCALE_FACTOR 7500
108 /* Returns battery voltage from ADC [millivolts] */
109 unsigned int battery_adc_voltage(void)
111 unsigned int dummy, bat_val;
113 mutex_lock(&battery_mtx);
115 dummy = REG_SADC_BATDAT;
116 dummy = REG_SADC_BATDAT;
118 REG_SADC_ENA |= SADC_ENA_PBATEN;
120 wakeup_wait(&battery_wkup, HZ/4);
121 bat_val = REG_SADC_BATDAT;
123 logf("%d %d", bat_val, (bat_val * BATTERY_SCALE_FACTOR) / 4096);
125 mutex_unlock(&battery_mtx);
127 return (bat_val * BATTERY_SCALE_FACTOR) / 4096;
130 void button_init_device(void)
132 __gpio_as_input(32*3 + 29); /* VX777 and VX747(+) */
134 #ifdef ONDA_VX747
135 __gpio_as_input(32*3 + 27);
136 __gpio_as_input(32*3 + 16);
137 __gpio_as_input(32*3 + 1);
138 __gpio_as_input(32*3 + 0);
139 #elif defined(ONDA_VX747P)
140 __gpio_as_input(32*3 + 27);
141 __gpio_as_input(32*3 + 20);
142 __gpio_as_input(32*3 + 19);
143 __gpio_as_input(32*2 + 22);
144 #endif
147 bool button_hold(void)
149 return (
150 #ifdef ONDA_VX747
151 (~REG_GPIO_PXPIN(3)) & BTN_HOLD
152 #elif defined(ONDA_VX747P)
153 (~REG_GPIO_PXPIN(2)) & BTN_HOLD
154 #elif defined(ONDA_VX777)
155 false
156 #endif
157 ? true : false
161 int button_read_device(int *data)
163 int ret = 0;
164 static int old_data = 0;
166 *data = old_data;
168 /* Filter button events out if HOLD button is pressed at firmware/ level */
169 if(button_hold())
170 return 0;
172 int tmp = (~REG_GPIO_PXPIN(3)) & BTN_MASK;
174 if(tmp & BTN_OFF)
175 ret |= BUTTON_POWER;
176 #ifndef ONDA_VX777
177 if(tmp & BTN_VOL_DOWN)
178 ret |= BUTTON_VOL_DOWN;
179 if(tmp & BTN_VOL_UP)
180 ret |= BUTTON_VOL_UP;
181 if(tmp & BTN_MENU)
182 ret |= BUTTON_MENU;
183 #endif
185 if(cur_touch != 0 && pen_down)
187 ret |= touchscreen_to_pixels(cur_touch >> 16, cur_touch & 0xFFFF, data);
188 #if CONFIG_ORIENTATION == SCREEN_LANDSCAPE
189 *data = (*data & 0xFFFF) | ((LCD_HEIGHT - (*data >> 16)) << 16);
190 #endif
191 if( UNLIKELY(!is_backlight_on(true)) )
192 *data = 0;
194 old_data = *data;
197 return ret;
200 /* Interrupt handler */
201 void SADC(void)
203 unsigned char state, sadcstate;
205 sadcstate = REG_SADC_STATE;
206 state = sadcstate & (~REG_SADC_CTRL);
207 REG_SADC_STATE &= sadcstate;
209 if(state & SADC_CTRL_PENDM)
211 /* Pen down IRQ */
212 REG_SADC_CTRL &= (~(SADC_CTRL_PENUM | SADC_CTRL_TSRDYM));
213 REG_SADC_CTRL |= (SADC_CTRL_PENDM);
214 pen_down = true;
217 if(state & SADC_CTRL_PENUM)
219 /* Pen up IRQ */
220 REG_SADC_CTRL &= (~SADC_CTRL_PENDM );
221 REG_SADC_CTRL |= SADC_CTRL_PENUM;
222 pen_down = false;
223 datacount = 0;
224 cur_touch = 0;
227 if(state & SADC_CTRL_TSRDYM)
229 unsigned int dat;
230 unsigned short xData, yData;
231 signed short tsz1Data, tsz2Data;
233 dat = REG_SADC_TSDAT;
234 xData = (dat >> 0) & 0xFFF;
235 yData = (dat >> 16) & 0xFFF;
237 dat = REG_SADC_TSDAT;
238 tsz1Data = (dat >> 0) & 0xFFF;
239 tsz2Data = (dat >> 16) & 0xFFF;
241 if(!pen_down)
242 return;
244 tsz1Data = tsz2Data - tsz1Data;
246 if((tsz1Data > 100) || (tsz1Data < -100))
248 if(datacount == 0)
250 x_pos = xData;
251 y_pos = yData;
253 else
255 x_pos += xData;
256 y_pos += yData;
259 datacount++;
261 if(datacount >= TS_AD_COUNT)
263 cur_touch = ((x_pos / datacount) << 16) |
264 ((y_pos / datacount) & 0xFFFF);
265 datacount = 0;
268 else
269 datacount = 0;
272 if(state & SADC_CTRL_PBATRDYM)
274 /* Battery AD IRQ */
275 wakeup_signal(&battery_wkup);
279 void adc_init(void)
281 __cpm_start_sadc();
282 REG_SADC_ENA = 0;
283 REG_SADC_STATE &= (~REG_SADC_STATE);
284 REG_SADC_CTRL = 0x1f;
286 REG_SADC_CFG = SADC_CFG_INIT;
288 system_enable_irq(IRQ_SADC);
290 REG_SADC_SAMETIME = 10;
291 REG_SADC_WAITTIME = 100;
292 REG_SADC_STATE &= ~REG_SADC_STATE;
293 REG_SADC_CTRL = ~(SADC_CTRL_PENDM | SADC_CTRL_PENUM | SADC_CTRL_TSRDYM | SADC_CTRL_PBATRDYM);
294 REG_SADC_ENA = SADC_ENA_TSEN;
296 mutex_init(&battery_mtx);
297 wakeup_init(&battery_wkup);
300 void adc_close(void)
302 REG_SADC_ENA = 0;
303 __intc_mask_irq(IRQ_SADC);
304 sleep(20);
305 __cpm_stop_sadc();