Onda's: add touchscreen boot menu for targets without/not much physical buttons ...
[kugel-rb.git] / firmware / target / mips / ingenic_jz47xx / onda_vx747 / sadc-onda_vx747.c
blob3218e9b5f7c8640df7747203a5d79fac618e0365
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)
39 #elif defined(ONDA_VX747P)
40 #define BTN_OFF (1 << 29)
41 #define BTN_VOL_DOWN (1 << 27)
42 #define BTN_HOLD (1 << 22) /* on REG_GPIO_PXPIN(2) */
43 #define BTN_MENU (1 << 20)
44 #define BTN_VOL_UP (1 << 19)
45 #elif defined(ONDA_VX777)
46 /* TODO */
47 #else
48 #error No buttons defined!
49 #endif
51 #define BTN_MASK (BTN_OFF | BTN_VOL_DOWN | \
52 BTN_MENU | BTN_VOL_UP)
55 #define TS_AD_COUNT 3
56 #define SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
58 #define SADC_CFG_INIT ( \
59 (2 << SADC_CFG_CLKOUT_NUM_BIT) | \
60 SADC_CFG_XYZ1Z2 | \
61 SADC_CFG_SNUM | \
62 (1 << SADC_CFG_CLKDIV_BIT) | \
63 SADC_CFG_PBAT_HIGH | \
64 SADC_CFG_CMD_INT_PEN \
67 static signed int x_pos, y_pos;
68 static int datacount = 0;
69 static volatile int cur_touch = 0;
70 static volatile bool pen_down = false;
71 static volatile unsigned short bat_val;
72 static struct mutex battery_mtx;
74 const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
76 /* TODO */
77 1000
80 const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
82 /* TODO */
83 900
86 /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
87 const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
89 /* TODO */
90 { 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000 },
93 /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
94 const unsigned short percent_to_volt_charge[11] =
96 /* TODO */
97 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000
100 /* VBAT = (BDATA/4096) * 7.5V */
101 #define BATTERY_SCALE_FACTOR 1875
103 /* Returns battery voltage from ADC [millivolts] */
104 unsigned int battery_adc_voltage(void)
106 unsigned int dummy, timeout=HZ/4;
108 mutex_lock(&battery_mtx);
110 dummy = REG_SADC_BATDAT;
111 dummy = REG_SADC_BATDAT;
113 REG_SADC_ENA |= SADC_ENA_PBATEN;
114 bat_val = 0;
116 /* primitive wakeup event */
117 while(bat_val == 0 && timeout--)
118 sleep(0);
120 logf("%d %d", bat_val, (bat_val*BATTERY_SCALE_FACTOR)>>10);
122 mutex_unlock(&battery_mtx);
124 return (bat_val*BATTERY_SCALE_FACTOR)>>10;
127 void button_init_device(void)
129 #ifdef ONDA_VX747
130 __gpio_as_input(32*3 + 29);
131 __gpio_as_input(32*3 + 27);
132 __gpio_as_input(32*3 + 16);
133 __gpio_as_input(32*3 + 1);
134 __gpio_as_input(32*3 + 0);
135 #elif defined(ONDA_VX747P)
136 __gpio_as_input(32*3 + 29);
137 __gpio_as_input(32*3 + 27);
138 __gpio_as_input(32*3 + 20);
139 __gpio_as_input(32*3 + 19);
140 __gpio_as_input(32*2 + 22);
141 #endif
144 bool button_hold(void)
146 return (
147 #ifdef ONDA_VX747
148 (~REG_GPIO_PXPIN(3)) & BTN_HOLD
149 #elif defined(ONDA_VX747P)
150 (~REG_GPIO_PXPIN(2)) & BTN_HOLD
151 #elif defined(ONDA_VX777)
152 false /* TODO */
153 #endif
154 ? true : false
158 int button_read_device(int *data)
160 int ret = 0;
161 static int old_data = 0;
163 *data = old_data;
165 /* Filter button events out if HOLD button is pressed at firmware/ level */
166 if(button_hold())
167 return 0;
169 #ifndef ONDA_VX777
170 int tmp = (~REG_GPIO_PXPIN(3)) & BTN_MASK;
172 if(tmp & BTN_VOL_DOWN)
173 ret |= BUTTON_VOL_DOWN;
174 if(tmp & BTN_VOL_UP)
175 ret |= BUTTON_VOL_UP;
176 if(tmp & BTN_MENU)
177 ret |= BUTTON_MENU;
178 if(tmp & BTN_OFF)
179 ret |= BUTTON_POWER;
180 #endif
182 if(cur_touch != 0 && pen_down)
184 ret |= touchscreen_to_pixels(cur_touch >> 16, cur_touch & 0xFFFF, data);
185 #if CONFIG_ORIENTATION == SCREEN_LANDSCAPE
186 *data = (*data & 0xFFFF) | ((LCD_HEIGHT - (*data >> 16)) << 16);
187 #endif
188 if( UNLIKELY(!is_backlight_on(true)) )
189 *data = 0;
191 old_data = *data;
194 return ret;
197 /* Interrupt handler */
198 void SADC(void)
200 unsigned char state;
201 unsigned char sadcstate;
203 sadcstate = REG_SADC_STATE;
204 state = REG_SADC_STATE & (~REG_SADC_CTRL);
205 REG_SADC_STATE &= sadcstate;
207 if(state & SADC_CTRL_PENDM)
209 /* Pen down IRQ */
210 REG_SADC_CTRL &= (~(SADC_CTRL_PENUM | SADC_CTRL_TSRDYM));
211 REG_SADC_CTRL |= (SADC_CTRL_PENDM);
212 pen_down = true;
215 if(state & SADC_CTRL_PENUM)
217 /* Pen up IRQ */
218 REG_SADC_CTRL &= (~SADC_CTRL_PENDM );
219 REG_SADC_CTRL |= SADC_CTRL_PENUM;
220 pen_down = false;
221 datacount = 0;
222 cur_touch = 0;
225 if(state & SADC_CTRL_TSRDYM)
227 unsigned int dat;
228 unsigned short xData, yData;
229 signed short tsz1Data, tsz2Data;
231 dat = REG_SADC_TSDAT;
232 xData = (dat >> 0) & 0xFFF;
233 yData = (dat >> 16) & 0xFFF;
235 dat = REG_SADC_TSDAT;
236 tsz1Data = (dat >> 0) & 0xFFF;
237 tsz2Data = (dat >> 16) & 0xFFF;
239 if(!pen_down)
240 return;
242 tsz1Data = tsz2Data - tsz1Data;
244 if((tsz1Data > 100) || (tsz1Data < -100))
246 if(datacount == 0)
248 x_pos = xData;
249 y_pos = yData;
251 else
253 x_pos += xData;
254 y_pos += yData;
257 datacount++;
259 if(datacount >= TS_AD_COUNT)
261 cur_touch = ((x_pos / datacount) << 16) |
262 ((y_pos / datacount) & 0xFFFF);
263 datacount = 0;
266 else
267 datacount = 0;
270 if(state & SADC_CTRL_PBATRDYM)
272 bat_val = REG_SADC_BATDAT;
273 /* Battery AD IRQ */
277 void adc_init(void)
279 __cpm_start_sadc();
280 REG_SADC_ENA = 0;
281 REG_SADC_STATE &= (~REG_SADC_STATE);
282 REG_SADC_CTRL = 0x1f;
284 REG_SADC_CFG = SADC_CFG_INIT;
286 system_enable_irq(IRQ_SADC);
288 REG_SADC_SAMETIME = 10;
289 REG_SADC_WAITTIME = 100;
290 REG_SADC_STATE &= ~REG_SADC_STATE;
291 REG_SADC_CTRL = ~(SADC_CTRL_PENDM | SADC_CTRL_PENUM | SADC_CTRL_TSRDYM | SADC_CTRL_PBATRDYM);
292 REG_SADC_ENA = SADC_ENA_TSEN;
294 mutex_init(&battery_mtx);
297 void adc_close(void)
299 REG_SADC_ENA = 0;
300 __intc_mask_irq(IRQ_SADC);
301 sleep(20);
302 __cpm_stop_sadc();