diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-05-30 16:24:38 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2016-06-01 23:09:27 +0200 |
commit | d42a4a4eb4bc20fda41543b8b831c1970723346f (patch) | |
tree | f6ba16e95c61e441c1f110131b17a710c785285c /firmware | |
parent | b2afd931e2d83ce346811a68a34ee56c48be6d35 (diff) | |
download | rockbox-d42a4a4eb4bc20fda41543b8b831c1970723346f.tar.gz rockbox-d42a4a4eb4bc20fda41543b8b831c1970723346f.zip |
zenxfi3: rewrite mpr121 driver
The new driver uses an asynchronous architecture for touch status reading.
Change-Id: Ic75a8b91bc47ee16c3af873afde178cd70186376
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/drivers/mpr121.c | 350 | ||||
-rw-r--r-- | firmware/export/mpr121.h | 314 | ||||
-rw-r--r-- | firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c | 95 | ||||
-rw-r--r-- | firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.c | 236 | ||||
-rw-r--r-- | firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.h | 176 |
7 files changed, 601 insertions, 574 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 34d2db39b2..db3f09ea8e 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -1231,10 +1231,10 @@ target/arm/imx233/creative-zenxfi2/powermgmt-zenxfi2.c | |||
1231 | #endif | 1231 | #endif |
1232 | 1232 | ||
1233 | #ifdef CREATIVE_ZENXFI3 | 1233 | #ifdef CREATIVE_ZENXFI3 |
1234 | drivers/mpr121.c | ||
1235 | #ifndef BOOTLOADER | 1234 | #ifndef BOOTLOADER |
1236 | target/arm/imx233/fmradio-imx233.c | 1235 | target/arm/imx233/fmradio-imx233.c |
1237 | #endif | 1236 | #endif |
1237 | target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.c | ||
1238 | target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c | 1238 | target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c |
1239 | target/arm/imx233/creative-zenxfi3/lcd-zenxfi3.c | 1239 | target/arm/imx233/creative-zenxfi3/lcd-zenxfi3.c |
1240 | target/arm/imx233/creative-zenxfi3/button-zenxfi3.c | 1240 | target/arm/imx233/creative-zenxfi3/button-zenxfi3.c |
diff --git a/firmware/drivers/mpr121.c b/firmware/drivers/mpr121.c deleted file mode 100644 index 7b41208a3a..0000000000 --- a/firmware/drivers/mpr121.c +++ /dev/null | |||
@@ -1,350 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2012 Amaury Pouly | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | /** Driver for the Freescale MPR121 Capacitive Proximity Sensor */ | ||
23 | #include "system.h" | ||
24 | #include "mpr121.h" | ||
25 | #include "i2c.h" | ||
26 | |||
27 | /* Touch status: EL{0,7} */ | ||
28 | #define REG_TOUCH_STATUS 0x00 | ||
29 | #define REG_TOUCH_STATUS__ELE(x) (1 << (x)) | ||
30 | /* Touch status: EL{8-11,prox}, overcurrent */ | ||
31 | #define REG_TOUCH_STATUS2 0x01 | ||
32 | #define REG_TOUCH_STATUS2__ELE(x) (1 << ((x) - 8)) | ||
33 | #define REG_TOUCH_STATUS2__ELEPROX (1 << 4) | ||
34 | #define REG_TOUCH_STATUS2__OVCF (1 << 7) | ||
35 | /* Out of range: EL{0,7} */ | ||
36 | #define REG_OOR_STATUS 0x02 | ||
37 | #define REG_OOR_STATUS__ELE(x) (1 << (x)) | ||
38 | /* Out of range: EL{8-11,prox}, autoconf err */ | ||
39 | #define REG_OOR_STATUS2 0x03 | ||
40 | #define REG_OOR_STATUS2__ELE(x) (1 << (x)) | ||
41 | #define REG_OOR_STATUS2__ELEPROX (1 << 4) | ||
42 | #define REG_OOR_STATUS2__ACFF (1 << 6) | ||
43 | #define REG_OOR_STATUS2__ARFF (1 << 7) | ||
44 | /* Electrode X filtered data LSB */ | ||
45 | #define REG_EFDxLB(x) (0x04 + 0x02 * (x)) | ||
46 | /* Electrode X filtered data MSB */ | ||
47 | #define REG_EFDxHB(x) (0x05 + 0x02 * (x)) | ||
48 | /* Proximity electrode X filtered data LSB */ | ||
49 | #define REG_EFDPROXLB 0x1c | ||
50 | /* Proximity electrode X filtered data MSB */ | ||
51 | #define REG_EFDPROXHB 0x1d | ||
52 | /* Electrode baseline value */ | ||
53 | #define REG_ExBV(x) (0x1e + (x)) | ||
54 | /* Proximity electrode baseline value */ | ||
55 | #define REG_EPROXBV 0x2a | ||
56 | /* Max Half Delta Rising */ | ||
57 | #define REG_MHDR 0x2b | ||
58 | /* Noise Half Delta Rising */ | ||
59 | #define REG_NHDR 0x2c | ||
60 | /* Noise Count Limit Rising */ | ||
61 | #define REG_NCLR 0x2d | ||
62 | /* Filter Delay Limit Rising */ | ||
63 | #define REG_FDLR 0x2e | ||
64 | /* Max Half Delta Falling */ | ||
65 | #define REG_MHDF 0x2f | ||
66 | /* Noise Half Delta Falling */ | ||
67 | #define REG_NHDF 0x30 | ||
68 | /* Noise Count Limit Falling */ | ||
69 | #define REG_NCLF 0x31 | ||
70 | /* Filter Delay Limit Falling */ | ||
71 | #define REG_FDLF 0x32 | ||
72 | /* Noise Half Delta Touched */ | ||
73 | #define REG_NHDT 0x33 | ||
74 | /* Noise Count Limit Touched */ | ||
75 | #define REG_NCLT 0x34 | ||
76 | /* Filter Delay Limit Touched */ | ||
77 | #define REG_FDLT 0x35 | ||
78 | /* Proximity Max Half Delta Rising */ | ||
79 | #define REG_MHDPROXR 0x36 | ||
80 | /* Proximity Noise Half Delta Rising */ | ||
81 | #define REG_NHDPROXR 0x37 | ||
82 | /* Proximity Noise Count Limit Rising */ | ||
83 | #define REG_NCLPROXR 0x38 | ||
84 | /* Proximity Filter Delay Limit Rising */ | ||
85 | #define REG_FDLPROXR 0x39 | ||
86 | /* Proximity Max Half Delta Falling */ | ||
87 | #define REG_MHDPROXF 0x3a | ||
88 | /* Proximity Noise Half Delta Falling */ | ||
89 | #define REG_NHDPROXF 0x3b | ||
90 | /* Proximity Noise Count Limit Falling */ | ||
91 | #define REG_NCLPROXF 0x3c | ||
92 | /* Proximity Filter Delay Limit Falling */ | ||
93 | #define REG_FDLPROXF 0x3d | ||
94 | /* Proximity Noise Half Delta Touched */ | ||
95 | #define REG_NHDPROXT 0x3e | ||
96 | /* Proximity Noise Count Limit Touched */ | ||
97 | #define REG_NCLPROXT 0x3f | ||
98 | /* Proximity Filter Delay Limit Touched */ | ||
99 | #define REG_FDLPROXT 0x40 | ||
100 | /* Eletrode Touch Threshold */ | ||
101 | #define REG_ExTTH(x) (0x41 + 2 * (x)) | ||
102 | /* Eletrode Release Threshold */ | ||
103 | #define REG_ExRTH(x) (0x42 + 2 * (x)) | ||
104 | /* Proximity Eletrode Touch Threshold */ | ||
105 | #define REG_EPROXTTH 0x59 | ||
106 | /* Proximity Eletrode Release Threshold */ | ||
107 | #define REG_EPROXRTH 0x5a | ||
108 | /* Debounce Control */ | ||
109 | #define REG_DEBOUNCE 0x5b | ||
110 | #define REG_DEBOUNCE__DR(dr) ((dr) << 4) | ||
111 | #define REG_DEBOUNCE__DT(dt) (dt) | ||
112 | /* Analog Front End Configuration */ | ||
113 | #define REG_AFE 0x5c | ||
114 | #define REG_AFE__CDC(cdc) (cdc) | ||
115 | #define REG_AFE__FFI(ffi) ((ffi) << 6) | ||
116 | /* Filter Configuration */ | ||
117 | #define REG_FILTER 0x5d | ||
118 | #define REG_FILTER__ESI(esi) (esi) | ||
119 | #define REG_FILTER__SFI(sfi) ((sfi) << 3) | ||
120 | #define REG_FILTER__CDT(cdt) ((cdt) << 5) | ||
121 | /* Electrode Configuration */ | ||
122 | #define REG_ELECTRODE 0x5e | ||
123 | #define REG_ELECTRODE__ELE_EN(en) (en) | ||
124 | #define REG_ELECTRODE__ELEPROX_EN(en) ((en) << 4) | ||
125 | #define REG_ELECTRODE__CL(cl) ((cl) << 6) | ||
126 | /* Electrode X Current */ | ||
127 | #define REG_CDCx(x) (0x5f + (x)) | ||
128 | /* Proximity Eletrode X Current */ | ||
129 | #define REG_CDCPROX 0x6b | ||
130 | /* Electrode X Charge Time */ | ||
131 | #define REG_CDTx(x) (0x6c + (x) / 2) | ||
132 | #define REG_CDTx__CDT0(x) (x) | ||
133 | #define REG_CDTx__CDT1(x) ((x) << 4) | ||
134 | /* Proximity Eletrode X Charge Time */ | ||
135 | #define REG_CDTPROX 0x72 | ||
136 | /* GPIO Control Register: CTL0{4-11} */ | ||
137 | #define REG_GPIO_CTL0 0x73 | ||
138 | #define REG_GPIO_CTL0__CTL0x(x) (1 << ((x) - 4)) | ||
139 | /* GPIO Control Register: CTL1{4-11} */ | ||
140 | #define REG_GPIO_CTL1 0x74 | ||
141 | #define REG_GPIO_CTL1__CTL1x(x) (1 << ((x) - 4)) | ||
142 | /* GPIO Data Register */ | ||
143 | #define REG_GPIO_DATA 0x75 | ||
144 | #define REG_GPIO_DATA__DATx(x) (1 << ((x) - 4)) | ||
145 | /* GPIO Direction Register */ | ||
146 | #define REG_GPIO_DIR 0x76 | ||
147 | #define REG_GPIO_DIR__DIRx(x) (1 << ((x) - 4)) | ||
148 | /* GPIO Enable Register */ | ||
149 | #define REG_GPIO_EN 0x77 | ||
150 | #define REG_GPIO_EN__ENx(x) (1 << ((x) - 4)) | ||
151 | /* GPIO Data Set Register */ | ||
152 | #define REG_GPIO_SET 0x78 | ||
153 | #define REG_GPIO_SET__SETx(x) (1 << ((x) - 4)) | ||
154 | /* GPIO Data Clear Register */ | ||
155 | #define REG_GPIO_CLR 0x79 | ||
156 | #define REG_GPIO_CLR__CLRx(x) (1 << ((x) - 4)) | ||
157 | /* GPIO Data Toggle Register */ | ||
158 | #define REG_GPIO_TOG 0x7a | ||
159 | #define REG_GPIO_TOG__TOGx(x) (1 << ((x) - 4)) | ||
160 | /* Auto-Configuration Control 0 */ | ||
161 | #define REG_AUTO_CONF 0x7b | ||
162 | #define REG_AUTO_CONF__ACE(ace) (ace) | ||
163 | #define REG_AUTO_CONF__ARE(are) ((are) << 1) | ||
164 | #define REG_AUTO_CONF__BVA(bva) ((bva) << 2) | ||
165 | #define REG_AUTO_CONF__RETRY(retry) ((retry) << 4) | ||
166 | #define REG_AUTO_CONF__FFI(ffi) ((ffi) << 6) | ||
167 | /* Auto-Configuration Control 1 */ | ||
168 | #define REG_AUTO_CONF2 0x7c | ||
169 | #define REG_AUTO_CONF2__ACFIE(acfie) (acfie) | ||
170 | #define REG_AUTO_CONF2__ARFIE(arfie) ((arfie) << 1) | ||
171 | #define REG_AUTO_CONF2__OORIE(oorie) ((oorie) << 2) | ||
172 | #define REG_AUTO_CONF2__SCTS(scts) ((scts) << 7) | ||
173 | /* Auto-Configuration Upper-Limit */ | ||
174 | #define REG_USL 0x7d | ||
175 | /* Auto-Configuration Lower-Limit */ | ||
176 | #define REG_LSL 0x7e | ||
177 | /* Auto-Configuration Target Level */ | ||
178 | #define REG_TL 0x7f | ||
179 | /* Soft-Reset */ | ||
180 | #define REG_SOFTRESET 0x80 | ||
181 | #define REG_SOFTRESET__MAGIC 0x63 | ||
182 | /* PWM Control */ | ||
183 | #define REG_PWMx(x) (0x81 + ((x) - 4) / 2) | ||
184 | #define REG_PWMx_IS_PWM0(x) (((x) % 2) == 0) | ||
185 | #define REG_PWMx__PWM0(x) (x) | ||
186 | #define REG_PWMx__PWM0_BM 0xf | ||
187 | #define REG_PWMx__PWM1(x) ((x) << 4) | ||
188 | #define REG_PWMx__PWM1_BM 0xf0 | ||
189 | |||
190 | static int i2c_addr; | ||
191 | |||
192 | static inline int mpr121_write_reg(uint8_t reg, uint8_t data) | ||
193 | { | ||
194 | return i2c_writemem(i2c_addr, reg, &data, 1); | ||
195 | } | ||
196 | |||
197 | static inline int mpr121_read_reg(uint8_t reg, uint8_t *data) | ||
198 | { | ||
199 | return i2c_readmem(i2c_addr, reg, data, 1); | ||
200 | } | ||
201 | |||
202 | int mpr121_init(int dev_i2c_addr) | ||
203 | { | ||
204 | i2c_addr = dev_i2c_addr; | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | int mpr121_soft_reset(void) | ||
209 | { | ||
210 | return mpr121_write_reg(REG_SOFTRESET, REG_SOFTRESET__MAGIC); | ||
211 | } | ||
212 | int mpr121_set_config(struct mpr121_config_t *conf) | ||
213 | { | ||
214 | int ret; | ||
215 | #define safe_write(reg, val) \ | ||
216 | do { ret = mpr121_write_reg(reg, val); \ | ||
217 | if(ret) return ret; } while(0) | ||
218 | /* stop mode */ | ||
219 | safe_write(REG_ELECTRODE, 0); | ||
220 | /* write baseline values */ | ||
221 | for(int i = 0; i < ELECTRODE_COUNT; i++) | ||
222 | safe_write(REG_ExBV(i), conf->ele[i].bv); | ||
223 | /* write eleprox bv */ | ||
224 | safe_write(REG_EPROXBV, conf->eleprox.bv); | ||
225 | /* write global fields */ | ||
226 | safe_write(REG_MHDR, conf->filters.ele.rising.mhd); | ||
227 | safe_write(REG_NHDR, conf->filters.ele.rising.nhd); | ||
228 | safe_write(REG_NCLR, conf->filters.ele.rising.ncl); | ||
229 | safe_write(REG_FDLR, conf->filters.ele.rising.fdl); | ||
230 | safe_write(REG_MHDF, conf->filters.ele.falling.mhd); | ||
231 | safe_write(REG_NHDF, conf->filters.ele.falling.nhd); | ||
232 | safe_write(REG_NCLF, conf->filters.ele.falling.ncl); | ||
233 | safe_write(REG_FDLF, conf->filters.ele.falling.fdl); | ||
234 | safe_write(REG_NHDT, conf->filters.ele.touched.nhd); | ||
235 | safe_write(REG_NCLT, conf->filters.ele.touched.ncl); | ||
236 | safe_write(REG_FDLT, conf->filters.ele.touched.fdl); | ||
237 | safe_write(REG_MHDPROXR, conf->filters.eleprox.rising.mhd); | ||
238 | safe_write(REG_NHDPROXR, conf->filters.eleprox.rising.nhd); | ||
239 | safe_write(REG_NCLPROXR, conf->filters.eleprox.rising.ncl); | ||
240 | safe_write(REG_FDLPROXR, conf->filters.eleprox.rising.fdl); | ||
241 | safe_write(REG_MHDPROXF, conf->filters.eleprox.falling.mhd); | ||
242 | safe_write(REG_NHDPROXF, conf->filters.eleprox.falling.nhd); | ||
243 | safe_write(REG_NCLPROXF, conf->filters.eleprox.falling.ncl); | ||
244 | safe_write(REG_FDLPROXF, conf->filters.eleprox.falling.fdl); | ||
245 | safe_write(REG_NHDPROXT, conf->filters.eleprox.touched.nhd); | ||
246 | safe_write(REG_NCLPROXT, conf->filters.eleprox.touched.ncl); | ||
247 | safe_write(REG_FDLPROXT, conf->filters.eleprox.touched.fdl); | ||
248 | /* touch & release thresholds */ | ||
249 | for(int i = 0; i < ELECTRODE_COUNT; i++) | ||
250 | { | ||
251 | safe_write(REG_ExTTH(i), conf->ele[i].tth); | ||
252 | safe_write(REG_ExRTH(i), conf->ele[i].rth); | ||
253 | } | ||
254 | safe_write(REG_EPROXTTH, conf->eleprox.tth); | ||
255 | safe_write(REG_EPROXRTH, conf->eleprox.rth); | ||
256 | /* debounce */ | ||
257 | safe_write(REG_DEBOUNCE, REG_DEBOUNCE__DR(conf->debounce.dr) | | ||
258 | REG_DEBOUNCE__DT(conf->debounce.dt)); | ||
259 | /* analog-front end and filters */ | ||
260 | safe_write(REG_AFE, REG_AFE__CDC(conf->global.cdc) | | ||
261 | REG_AFE__FFI(conf->global.ffi)); | ||
262 | safe_write(REG_FILTER, REG_FILTER__CDT(conf->global.cdt) | | ||
263 | REG_FILTER__ESI(conf->global.esi) | REG_FILTER__SFI(conf->global.sfi)); | ||
264 | /* electrode charge */ | ||
265 | for(int i = 0; i < ELECTRODE_COUNT; i++) | ||
266 | safe_write(REG_CDCx(i), conf->ele[i].cdc); | ||
267 | safe_write(REG_CDCPROX, conf->eleprox.cdc); | ||
268 | for(int i = 0; i < ELECTRODE_COUNT; i += 2) | ||
269 | { | ||
270 | safe_write(REG_CDTx(i), REG_CDTx__CDT0(conf->ele[i].cdt) | | ||
271 | REG_CDTx__CDT1(conf->ele[i+1].cdt)); | ||
272 | } | ||
273 | safe_write(REG_CDTPROX, conf->eleprox.cdt); | ||
274 | /* Auto-Configuration */ | ||
275 | safe_write(REG_AUTO_CONF, REG_AUTO_CONF__ACE(conf->autoconf.en) | | ||
276 | REG_AUTO_CONF__ARE(conf->autoconf.ren) | | ||
277 | REG_AUTO_CONF__BVA(conf->cal_lock) | | ||
278 | REG_AUTO_CONF__RETRY(conf->autoconf.retry) | | ||
279 | REG_AUTO_CONF__FFI(conf->global.ffi)); | ||
280 | safe_write(REG_AUTO_CONF2, REG_AUTO_CONF2__ACFIE(conf->autoconf.acfie) | | ||
281 | REG_AUTO_CONF2__ARFIE(conf->autoconf.arfie) | | ||
282 | REG_AUTO_CONF2__OORIE(conf->autoconf.oorie) | | ||
283 | REG_AUTO_CONF2__SCTS(conf->autoconf.scts)); | ||
284 | safe_write(REG_USL, conf->autoconf.usl); | ||
285 | safe_write(REG_LSL, conf->autoconf.lsl); | ||
286 | safe_write(REG_TL, conf->autoconf.tl); | ||
287 | /* electrode configuration */ | ||
288 | safe_write(REG_ELECTRODE, REG_ELECTRODE__ELE_EN(conf->ele_en) | | ||
289 | REG_ELECTRODE__ELEPROX_EN(conf->eleprox_en) | | ||
290 | REG_ELECTRODE__CL(conf->cal_lock)); | ||
291 | /* gpio config */ | ||
292 | uint8_t ctl = 0; | ||
293 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
294 | if(ELE_GPIO_CTL0(conf->ele[i].gpio)) | ||
295 | ctl |= REG_GPIO_CTL0__CTL0x(i); | ||
296 | safe_write(REG_GPIO_CTL0, ctl); | ||
297 | ctl = 0; | ||
298 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
299 | if(ELE_GPIO_CTL1(conf->ele[i].gpio)) | ||
300 | ctl |= REG_GPIO_CTL1__CTL1x(i); | ||
301 | safe_write(REG_GPIO_CTL1, ctl); | ||
302 | ctl = 0; | ||
303 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
304 | if(ELE_GPIO_DIR(conf->ele[i].gpio)) | ||
305 | ctl |= REG_GPIO_DIR__DIRx(i); | ||
306 | safe_write(REG_GPIO_DIR, ctl); | ||
307 | ctl = 0; | ||
308 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
309 | if(ELE_GPIO_EN(conf->ele[i].gpio)) | ||
310 | ctl |= REG_GPIO_EN__ENx(i); | ||
311 | safe_write(REG_GPIO_EN, ctl); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | int mpr121_set_gpio_output(int ele, int gpio_val) | ||
317 | { | ||
318 | switch(gpio_val) | ||
319 | { | ||
320 | case ELE_GPIO_SET: | ||
321 | return mpr121_write_reg(REG_GPIO_SET, REG_GPIO_SET__SETx(ele)); | ||
322 | case ELE_GPIO_CLR: | ||
323 | return mpr121_write_reg(REG_GPIO_CLR, REG_GPIO_CLR__CLRx(ele)); | ||
324 | case ELE_GPIO_TOG: | ||
325 | return mpr121_write_reg(REG_GPIO_TOG, REG_GPIO_TOG__TOGx(ele)); | ||
326 | default: | ||
327 | return -1; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | int mpr121_set_gpio_pwm(int ele, int pwm) | ||
332 | { | ||
333 | uint8_t reg_val; | ||
334 | int ret = mpr121_read_reg(REG_PWMx(ele), ®_val); | ||
335 | if(ret) return ret; | ||
336 | if(REG_PWMx_IS_PWM0(ele)) | ||
337 | reg_val = (reg_val & ~REG_PWMx__PWM0_BM) | REG_PWMx__PWM0(pwm); | ||
338 | else | ||
339 | reg_val = (reg_val & ~REG_PWMx__PWM1_BM) | REG_PWMx__PWM1(pwm); | ||
340 | return mpr121_write_reg(REG_PWMx(ele), reg_val); | ||
341 | } | ||
342 | |||
343 | int mpr121_get_touch_status(unsigned *status) | ||
344 | { | ||
345 | uint8_t buf[2]; | ||
346 | int ret = i2c_readmem(i2c_addr, REG_TOUCH_STATUS, buf, 2); | ||
347 | if(!ret && status) | ||
348 | *status = buf[0] | buf[1]; | ||
349 | return ret; | ||
350 | } | ||
diff --git a/firmware/export/mpr121.h b/firmware/export/mpr121.h index 96b83ecc90..50c13a1c7b 100644 --- a/firmware/export/mpr121.h +++ b/firmware/export/mpr121.h | |||
@@ -18,153 +18,173 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #ifndef __MPR121_H__ | ||
22 | #define __MPR121_H__ | ||
21 | 23 | ||
22 | /** Driver for the Freescale MPR121 Capacitive Proximity Sensor */ | 24 | /** Registers for the Freescale MPR121 Capacitive Proximity Sensor */ |
23 | #include "system.h" | 25 | #include "system.h" |
24 | 26 | ||
25 | #define ELECTRODE_COUNT 12 | 27 | /* Touch status: EL{0,7} */ |
26 | #define ELE_GPIO_FIRST 4 | 28 | #define REG_TOUCH_STATUS 0x00 |
27 | #define ELE_GPIO_LAST 11 | 29 | #define REG_TOUCH_STATUS__ELE(x) (1 << (x)) |
28 | 30 | /* Touch status: EL{8-11,prox}, overcurrent */ | |
29 | /* gpio config (encoding: [0]=en,[1]=dir,[2]=ctl[1],[3]=ctl[0]) */ | 31 | #define REG_TOUCH_STATUS2 0x01 |
30 | #define ELE_GPIO_DISABLE 0 | 32 | #define REG_TOUCH_STATUS2__ELE(x) (1 << ((x) - 8)) |
31 | #define ELE_GPIO_INPUT 1 | 33 | #define REG_TOUCH_STATUS2__ELEPROX (1 << 4) |
32 | #define ELE_GPIO_INPUT_PULLDOWN 9 /* input with pull-down */ | 34 | #define REG_TOUCH_STATUS2__OVCF (1 << 7) |
33 | #define ELE_GPIO_INPUT_PULLUP 13 /* input with pull-up */ | 35 | /* Out of range: EL{0,7} */ |
34 | #define ELE_GPIO_OUTPUT 3 | 36 | #define REG_OOR_STATUS 0x02 |
35 | #define ELE_GPIO_OUTPUT_OPEN 11 /* open drain low-side */ | 37 | #define REG_OOR_STATUS__ELE(x) (1 << (x)) |
36 | #define ELE_GPIO_OUTPUT_OPEN_LED 15 /* open drain high-side (led driver) */ | 38 | /* Out of range: EL{8-11,prox}, autoconf err */ |
37 | 39 | #define REG_OOR_STATUS2 0x03 | |
38 | /* internal use */ | 40 | #define REG_OOR_STATUS2__ELE(x) (1 << (x)) |
39 | #define ELE_GPIO_EN(val) ((val) & 1) | 41 | #define REG_OOR_STATUS2__ELEPROX (1 << 4) |
40 | #define ELE_GPIO_DIR(val) (((val) >> 1) & 1) | 42 | #define REG_OOR_STATUS2__ACFF (1 << 6) |
41 | #define ELE_GPIO_CTL0(val) (((val) >> 3) & 1) | 43 | #define REG_OOR_STATUS2__ARFF (1 << 7) |
42 | #define ELE_GPIO_CTL1(val) (((val) >> 1) & 1) | 44 | /* Electrode X filtered data LSB */ |
43 | 45 | #define REG_EFDxLB(x) (0x04 + 0x02 * (x)) | |
44 | struct mpr121_electrode_config_t | 46 | /* Electrode X filtered data MSB */ |
45 | { | 47 | #define REG_EFDxHB(x) (0x05 + 0x02 * (x)) |
46 | uint8_t bv; /* baseline value */ | 48 | /* Proximity electrode X filtered data LSB */ |
47 | uint8_t tth; /* touch threshold */ | 49 | #define REG_EFDPROXLB 0x1c |
48 | uint8_t rth; /* release threshold */ | 50 | /* Proximity electrode X filtered data MSB */ |
49 | uint8_t cdc; /* charge current (optional if auto-conf) */ | 51 | #define REG_EFDPROXHB 0x1d |
50 | uint8_t cdt; /* charge time (optional if auto-conf) */ | 52 | /* Electrode baseline value */ |
51 | int gpio; /* gpio config */ | 53 | #define REG_ExBV(x) (0x1e + (x)) |
52 | }; | 54 | /* Proximity electrode baseline value */ |
53 | 55 | #define REG_EPROXBV 0x2a | |
54 | struct mpr121_baseline_filter_config_t | 56 | /* Max Half Delta Rising */ |
55 | { | 57 | #define REG_MHDR 0x2b |
56 | uint8_t mhd; /* max half delta (except for touched) */ | 58 | /* Noise Half Delta Rising */ |
57 | uint8_t nhd; /* noise half delta */ | 59 | #define REG_NHDR 0x2c |
58 | uint8_t ncl; /* noise count limit */ | 60 | /* Noise Count Limit Rising */ |
59 | uint8_t fdl; /* filter delay count limit */ | 61 | #define REG_NCLR 0x2d |
60 | }; | 62 | /* Filter Delay Limit Rising */ |
61 | 63 | #define REG_FDLR 0x2e | |
62 | struct mpr121_baseline_filters_config_t | 64 | /* Max Half Delta Falling */ |
63 | { | 65 | #define REG_MHDF 0x2f |
64 | struct mpr121_baseline_filter_config_t rising; | 66 | /* Noise Half Delta Falling */ |
65 | struct mpr121_baseline_filter_config_t falling; | 67 | #define REG_NHDF 0x30 |
66 | struct mpr121_baseline_filter_config_t touched; | 68 | /* Noise Count Limit Falling */ |
67 | }; | 69 | #define REG_NCLF 0x31 |
68 | 70 | /* Filter Delay Limit Falling */ | |
69 | struct mpr121_debounce_config_t | 71 | #define REG_FDLF 0x32 |
70 | { | 72 | /* Noise Half Delta Touched */ |
71 | uint8_t dt; /* debounce count for touch */ | 73 | #define REG_NHDT 0x33 |
72 | uint8_t dr; /* debounce count for release */ | 74 | /* Noise Count Limit Touched */ |
73 | }; | 75 | #define REG_NCLT 0x34 |
74 | 76 | /* Filter Delay Limit Touched */ | |
75 | /* first filter iterations */ | 77 | #define REG_FDLT 0x35 |
76 | #define FFI_6_SAMPLES 0 | 78 | /* Proximity Max Half Delta Rising */ |
77 | #define FFI_10_SAMPLES 1 | 79 | #define REG_MHDPROXR 0x36 |
78 | #define FFI_18_SAMPLES 2 | 80 | /* Proximity Noise Half Delta Rising */ |
79 | #define FFI_34_SAMPLES 3 | 81 | #define REG_NHDPROXR 0x37 |
80 | /* charge discharge current */ | 82 | /* Proximity Noise Count Limit Rising */ |
81 | #define CDC_DISABLE 0 | 83 | #define REG_NCLPROXR 0x38 |
82 | #define CDC_uA(ua) (ua) | 84 | /* Proximity Filter Delay Limit Rising */ |
83 | /* charge discharge time */ | 85 | #define REG_FDLPROXR 0x39 |
84 | #define CDT_DISABLE 0 | 86 | /* Proximity Max Half Delta Falling */ |
85 | #define CDT_log_us(lus) (lus) /* actual value = 2^{us-2} µs */ | 87 | #define REG_MHDPROXF 0x3a |
86 | /* second filter iterations */ | 88 | /* Proximity Noise Half Delta Falling */ |
87 | #define SFI_4_SAMPLES 0 | 89 | #define REG_NHDPROXF 0x3b |
88 | #define SFI_6_SAMPLES 1 | 90 | /* Proximity Noise Count Limit Falling */ |
89 | #define SFI_10_SAMPLES 2 | 91 | #define REG_NCLPROXF 0x3c |
90 | #define SFI_18_SAMPLES 3 | 92 | /* Proximity Filter Delay Limit Falling */ |
91 | /* Eletrode sample interval */ | 93 | #define REG_FDLPROXF 0x3d |
92 | #define ESI_log_ms(lms) (lms) /* actual value = 2^{lms} ms */ | 94 | /* Proximity Noise Half Delta Touched */ |
93 | 95 | #define REG_NHDPROXT 0x3e | |
94 | struct mpr121_global_config_t | 96 | /* Proximity Noise Count Limit Touched */ |
95 | { | 97 | #define REG_NCLPROXT 0x3f |
96 | uint8_t ffi; /* first filter iterations */ | 98 | /* Proximity Filter Delay Limit Touched */ |
97 | uint8_t cdc; /* global charge discharge current */ | 99 | #define REG_FDLPROXT 0x40 |
98 | uint8_t cdt; /* global charge discharge time */ | 100 | /* Eletrode Touch Threshold */ |
99 | uint8_t sfi; /* second first iterations */ | 101 | #define REG_ExTTH(x) (0x41 + 2 * (x)) |
100 | uint8_t esi; /* electrode sample interval */ | 102 | /* Eletrode Release Threshold */ |
101 | }; | 103 | #define REG_ExRTH(x) (0x42 + 2 * (x)) |
102 | 104 | /* Proximity Eletrode Touch Threshold */ | |
103 | #define RETRY_NEVER 0 | 105 | #define REG_EPROXTTH 0x59 |
104 | #define RETRY_2_TIMES 1 | 106 | /* Proximity Eletrode Release Threshold */ |
105 | #define RETRY_4_TIMES 2 | 107 | #define REG_EPROXRTH 0x5a |
106 | #define RETRY_8_TIMES 3 | 108 | /* Debounce Control */ |
107 | 109 | #define REG_DEBOUNCE 0x5b | |
108 | struct mpr121_auto_config_t | 110 | #define REG_DEBOUNCE__DR(dr) ((dr) << 4) |
109 | { | 111 | #define REG_DEBOUNCE__DT(dt) (dt) |
110 | bool en; /* auto-conf enable */ | 112 | /* Analog Front End Configuration */ |
111 | bool ren; /* auto-reconf enable */ | 113 | #define REG_AFE 0x5c |
112 | uint8_t retry; /* retry count */ | 114 | #define REG_AFE__CDC(cdc) (cdc) |
113 | bool scts; /* skip charge time search */ | 115 | #define REG_AFE__FFI(ffi) ((ffi) << 6) |
114 | uint8_t usl; /* upper-side limit */ | 116 | /* Filter Configuration */ |
115 | uint8_t lsl; /* lower-side limit */ | 117 | #define REG_FILTER 0x5d |
116 | uint8_t tl; /* target level */ | 118 | #define REG_FILTER__ESI(esi) (esi) |
117 | bool acfie; /* auto-conf fail interrupt en */ | 119 | #define REG_FILTER__SFI(sfi) ((sfi) << 3) |
118 | bool arfie; /* auto-reconf fail interrupt en */ | 120 | #define REG_FILTER__CDT(cdt) ((cdt) << 5) |
119 | bool oorie; /* out of range interrupt en */ | 121 | /* Electrode Configuration */ |
120 | }; | 122 | #define REG_ELECTRODE 0x5e |
121 | 123 | #define REG_ELECTRODE__ELE_EN(en) (en) | |
122 | /* electrode mode */ | 124 | #define REG_ELECTRODE__ELEPROX_EN(en) ((en) << 4) |
123 | #define ELE_DISABLE 0 | 125 | #define REG_ELECTRODE__CL(cl) ((cl) << 6) |
124 | #define ELE_EN0_x(x) ((x) + 1) | 126 | /* Electrode X Current */ |
125 | /* eleprox mode */ | 127 | #define REG_CDCx(x) (0x5f + (x)) |
126 | #define ELEPROX_DISABLE 0 | 128 | /* Proximity Eletrode X Current */ |
127 | #define ELEPROX_EN0_1 1 | 129 | #define REG_CDCPROX 0x6b |
128 | #define ELEPROX_EN0_3 2 | 130 | /* Electrode X Charge Time */ |
129 | #define ELEPROX_EN0_11 3 | 131 | #define REG_CDTx(x) (0x6c + (x) / 2) |
130 | /* calibration lock */ | 132 | #define REG_CDTx__CDT0(x) (x) |
131 | #define CL_SLOW_TRACK 0 | 133 | #define REG_CDTx__CDT1(x) ((x) << 4) |
132 | #define CL_DISABLE 1 | 134 | /* Proximity Eletrode X Charge Time */ |
133 | #define CL_TRACK 2 | 135 | #define REG_CDTPROX 0x72 |
134 | #define CL_FAST_TRACK 3 | 136 | /* GPIO Control Register: CTL0{4-11} */ |
135 | 137 | #define REG_GPIO_CTL0 0x73 | |
136 | struct mpr121_config_t | 138 | #define REG_GPIO_CTL0__CTL0x(x) (1 << ((x) - 4)) |
137 | { | 139 | /* GPIO Control Register: CTL1{4-11} */ |
138 | struct mpr121_electrode_config_t ele[ELECTRODE_COUNT]; | 140 | #define REG_GPIO_CTL1 0x74 |
139 | struct mpr121_electrode_config_t eleprox; | 141 | #define REG_GPIO_CTL1__CTL1x(x) (1 << ((x) - 4)) |
140 | struct | 142 | /* GPIO Data Register */ |
141 | { | 143 | #define REG_GPIO_DATA 0x75 |
142 | struct mpr121_baseline_filters_config_t ele; | 144 | #define REG_GPIO_DATA__DATx(x) (1 << ((x) - 4)) |
143 | struct mpr121_baseline_filters_config_t eleprox; | 145 | /* GPIO Direction Register */ |
144 | }filters; | 146 | #define REG_GPIO_DIR 0x76 |
145 | struct mpr121_debounce_config_t debounce; | 147 | #define REG_GPIO_DIR__DIRx(x) (1 << ((x) - 4)) |
146 | struct mpr121_global_config_t global; | 148 | /* GPIO Enable Register */ |
147 | struct mpr121_auto_config_t autoconf; | 149 | #define REG_GPIO_EN 0x77 |
148 | uint8_t ele_en; /* eletroce mode */ | 150 | #define REG_GPIO_EN__ENx(x) (1 << ((x) - 4)) |
149 | uint8_t eleprox_en; /* proximity mode */ | 151 | /* GPIO Data Set Register */ |
150 | uint8_t cal_lock; /* calibration lock */ | 152 | #define REG_GPIO_SET 0x78 |
151 | }; | 153 | #define REG_GPIO_SET__SETx(x) (1 << ((x) - 4)) |
152 | 154 | /* GPIO Data Clear Register */ | |
153 | /* gpio value */ | 155 | #define REG_GPIO_CLR 0x79 |
154 | #define ELE_GPIO_CLR 0 | 156 | #define REG_GPIO_CLR__CLRx(x) (1 << ((x) - 4)) |
155 | #define ELE_GPIO_SET 1 | 157 | /* GPIO Data Toggle Register */ |
156 | #define ELE_GPIO_TOG 2 | 158 | #define REG_GPIO_TOG 0x7a |
157 | /* pwm value */ | 159 | #define REG_GPIO_TOG__TOGx(x) (1 << ((x) - 4)) |
158 | #define ELE_PWM_DISABLE 0 | 160 | /* Auto-Configuration Control 0 */ |
159 | #define ELE_PWM_DUTY(x) (x) | 161 | #define REG_AUTO_CONF 0x7b |
160 | #define ELE_PWM_MIN_DUTY 1 | 162 | #define REG_AUTO_CONF__ACE(ace) (ace) |
161 | #define ELE_PWM_MAX_DUTY 15 | 163 | #define REG_AUTO_CONF__ARE(are) ((are) << 1) |
162 | 164 | #define REG_AUTO_CONF__BVA(bva) ((bva) << 2) | |
163 | int mpr121_init(int dev_i2c_addr); | 165 | #define REG_AUTO_CONF__RETRY(retry) ((retry) << 4) |
164 | int mpr121_soft_reset(void); | 166 | #define REG_AUTO_CONF__FFI(ffi) ((ffi) << 6) |
165 | int mpr121_set_config(struct mpr121_config_t *conf); | 167 | /* Auto-Configuration Control 1 */ |
166 | /* gpios are only implemented for electrode>=4 */ | 168 | #define REG_AUTO_CONF2 0x7c |
167 | int mpr121_set_gpio_output(int ele, int gpio_val); | 169 | #define REG_AUTO_CONF2__ACFIE(acfie) (acfie) |
168 | int mpr121_set_gpio_pwm(int ele, int pwm); | 170 | #define REG_AUTO_CONF2__ARFIE(arfie) ((arfie) << 1) |
169 | /* get electrode status (bitmap) */ | 171 | #define REG_AUTO_CONF2__OORIE(oorie) ((oorie) << 2) |
170 | int mpr121_get_touch_status(unsigned *status); | 172 | #define REG_AUTO_CONF2__SCTS(scts) ((scts) << 7) |
173 | /* Auto-Configuration Upper-Limit */ | ||
174 | #define REG_USL 0x7d | ||
175 | /* Auto-Configuration Lower-Limit */ | ||
176 | #define REG_LSL 0x7e | ||
177 | /* Auto-Configuration Target Level */ | ||
178 | #define REG_TL 0x7f | ||
179 | /* Soft-Reset */ | ||
180 | #define REG_SOFTRESET 0x80 | ||
181 | #define REG_SOFTRESET__MAGIC 0x63 | ||
182 | /* PWM Control */ | ||
183 | #define REG_PWMx(x) (0x81 + ((x) - 4) / 2) | ||
184 | #define REG_PWMx_IS_PWM0(x) (((x) % 2) == 0) | ||
185 | #define REG_PWMx__PWM0(x) (x) | ||
186 | #define REG_PWMx__PWM0_BM 0xf | ||
187 | #define REG_PWMx__PWM1(x) ((x) << 4) | ||
188 | #define REG_PWMx__PWM1_BM 0xf0 | ||
189 | |||
190 | #endif /* __MPR121_H__ */ | ||
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c index 2b77a4d7ac..e3baddea1e 100644 --- a/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c +++ b/firmware/target/arm/imx233/creative-zenxfi3/backlight-zenxfi3.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "backlight.h" | 25 | #include "backlight.h" |
26 | #include "backlight-target.h" | 26 | #include "backlight-target.h" |
27 | #include "pwm-imx233.h" | 27 | #include "pwm-imx233.h" |
28 | #include "mpr121.h" | 28 | #include "mpr121-zenxfi3.h" |
29 | 29 | ||
30 | void backlight_hw_brightness(int brightness) | 30 | void backlight_hw_brightness(int brightness) |
31 | { | 31 | { |
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c index 756231a042..ed8e769e2d 100644 --- a/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c +++ b/firmware/target/arm/imx233/creative-zenxfi3/button-zenxfi3.c | |||
@@ -18,16 +18,10 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "button-target.h" | ||
22 | #include "system.h" | 21 | #include "system.h" |
23 | #include "system-target.h" | 22 | #include "tick.h" |
24 | #include "pinctrl-imx233.h" | ||
25 | #include "power-imx233.h" | ||
26 | #include "button-imx233.h" | 23 | #include "button-imx233.h" |
27 | #include "string.h" | 24 | #include "mpr121-zenxfi3.h" |
28 | #include "usb.h" | ||
29 | #include "backlight.h" | ||
30 | #include "mpr121.h" | ||
31 | 25 | ||
32 | #define I_VDDIO 0 /* index in the table */ | 26 | #define I_VDDIO 0 /* index in the table */ |
33 | 27 | ||
@@ -42,7 +36,8 @@ struct imx233_button_map_t imx233_button_map[] = | |||
42 | IMX233_BUTTON_(END, END(), "") | 36 | IMX233_BUTTON_(END, END(), "") |
43 | }; | 37 | }; |
44 | 38 | ||
45 | static struct mpr121_config_t config = | 39 | /* MPR121 configuration, mostly extracted from OF */ |
40 | static struct mpr121_config_t mpr121_config = | ||
46 | { | 41 | { |
47 | .ele = | 42 | .ele = |
48 | { | 43 | { |
@@ -73,74 +68,11 @@ static struct mpr121_config_t config = | |||
73 | .cal_lock = CL_TRACK | 68 | .cal_lock = CL_TRACK |
74 | }; | 69 | }; |
75 | 70 | ||
76 | #define MPR121_INTERRUPT 1 | ||
77 | |||
78 | static int touchpad_btns = 0; | ||
79 | static long mpr121_stack[DEFAULT_STACK_SIZE/sizeof(long)]; | ||
80 | static const char mpr121_thread_name[] = "mpr121"; | ||
81 | static struct event_queue mpr121_queue; | ||
82 | |||
83 | static void mpr121_irq_cb(int bank, int pin, intptr_t user) | ||
84 | { | ||
85 | (void) bank; | ||
86 | (void) pin; | ||
87 | (void) user; | ||
88 | /* the callback will not be fired until interrupt is enabled back so | ||
89 | * the queue will not overflow or contain multiple MPR121_INTERRUPT events */ | ||
90 | queue_post(&mpr121_queue, MPR121_INTERRUPT, 0); | ||
91 | } | ||
92 | |||
93 | static void mpr121_thread(void) | ||
94 | { | ||
95 | struct queue_event ev; | ||
96 | |||
97 | while(1) | ||
98 | { | ||
99 | queue_wait(&mpr121_queue, &ev); | ||
100 | /* handle usb connect and ignore all messages except rmi interrupts */ | ||
101 | if(ev.id == SYS_USB_CONNECTED) | ||
102 | { | ||
103 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
104 | continue; | ||
105 | } | ||
106 | else if(ev.id != MPR121_INTERRUPT) | ||
107 | continue; | ||
108 | /* clear interrupt and get status */ | ||
109 | unsigned status; | ||
110 | touchpad_btns = 0; | ||
111 | if(!mpr121_get_touch_status(&status)) | ||
112 | { | ||
113 | /* ELE3: up | ||
114 | * ELE4: back | ||
115 | * ELE5: menu | ||
116 | * ELE6: down | ||
117 | * ELE7: play */ | ||
118 | if(status & 0x8) touchpad_btns |= BUTTON_UP; | ||
119 | if(status & 0x10) touchpad_btns |= BUTTON_BACK; | ||
120 | if(status & 0x20) touchpad_btns |= BUTTON_MENU; | ||
121 | if(status & 0x40) touchpad_btns |= BUTTON_DOWN; | ||
122 | if(status & 0x80) touchpad_btns |= BUTTON_PLAY; | ||
123 | } | ||
124 | /* enable interrupt */ | ||
125 | imx233_pinctrl_setup_irq(0, 18, true, true, false, &mpr121_irq_cb, 0); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | /* B0P18 is #IRQ line of the touchpad */ | 71 | /* B0P18 is #IRQ line of the touchpad */ |
130 | void button_init_device(void) | 72 | void button_init_device(void) |
131 | { | 73 | { |
132 | mpr121_init(0xb4); | 74 | mpr121_init(); |
133 | mpr121_soft_reset(); | 75 | mpr121_set_config(&mpr121_config); |
134 | mpr121_set_config(&config); | ||
135 | |||
136 | queue_init(&mpr121_queue, true); | ||
137 | create_thread(mpr121_thread, mpr121_stack, sizeof(mpr121_stack), 0, | ||
138 | mpr121_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); | ||
139 | /* enable interrupt */ | ||
140 | imx233_pinctrl_acquire(0, 18, "mpr121_int"); | ||
141 | imx233_pinctrl_set_function(0, 18, PINCTRL_FUNCTION_GPIO); | ||
142 | imx233_pinctrl_enable_gpio(0, 18, false); | ||
143 | imx233_pinctrl_setup_irq(0, 18, true, true, false, &mpr121_irq_cb, 0); | ||
144 | /* generic part */ | 76 | /* generic part */ |
145 | imx233_button_init(); | 77 | imx233_button_init(); |
146 | } | 78 | } |
@@ -151,7 +83,6 @@ int button_read_device(void) | |||
151 | * for one second after hold is released */ | 83 | * for one second after hold is released */ |
152 | static int power_ignore_counter = 0; | 84 | static int power_ignore_counter = 0; |
153 | static bool old_hold; | 85 | static bool old_hold; |
154 | /* light handling */ | ||
155 | bool hold = button_hold(); | 86 | bool hold = button_hold(); |
156 | if(hold != old_hold) | 87 | if(hold != old_hold) |
157 | { | 88 | { |
@@ -159,6 +90,20 @@ int button_read_device(void) | |||
159 | if(!hold) | 90 | if(!hold) |
160 | power_ignore_counter = HZ; | 91 | power_ignore_counter = HZ; |
161 | } | 92 | } |
93 | /* interpret touchpad status */ | ||
94 | unsigned status = mpr121_get_touch_status(); | ||
95 | unsigned touchpad_btns = 0; | ||
96 | /* ELE3: up | ||
97 | * ELE4: back | ||
98 | * ELE5: menu | ||
99 | * ELE6: down | ||
100 | * ELE7: play */ | ||
101 | if(status & 0x8) touchpad_btns |= BUTTON_UP; | ||
102 | if(status & 0x10) touchpad_btns |= BUTTON_BACK; | ||
103 | if(status & 0x20) touchpad_btns |= BUTTON_MENU; | ||
104 | if(status & 0x40) touchpad_btns |= BUTTON_DOWN; | ||
105 | if(status & 0x80) touchpad_btns |= BUTTON_PLAY; | ||
106 | /* feed it to generic code */ | ||
162 | int res = imx233_button_read(touchpad_btns); | 107 | int res = imx233_button_read(touchpad_btns); |
163 | if(power_ignore_counter > 0) | 108 | if(power_ignore_counter > 0) |
164 | { | 109 | { |
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.c b/firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.c new file mode 100644 index 0000000000..23fcc7f0e4 --- /dev/null +++ b/firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2012 Amaury Pouly | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | /** Driver for the Freescale MPR121 Capacitive Proximity Sensor */ | ||
23 | #include "system.h" | ||
24 | #include "kernel.h" | ||
25 | #include "usb.h" | ||
26 | #include "mpr121.h" | ||
27 | #include "mpr121-zenxfi3.h" | ||
28 | #include "i2c-imx233.h" | ||
29 | #include "pinctrl-imx233.h" | ||
30 | |||
31 | #define MPR121_I2C_ADDR 0xb4 | ||
32 | |||
33 | /* NOTE on the architecture of the driver | ||
34 | * | ||
35 | * All non-time-critical operations (setup, gpio/pwm changes) are done with | ||
36 | * blocking i2c transfers to make the code simpler. Since reading the touch | ||
37 | * status is time critical, it is done asynchronously: when the IRQ pin is | ||
38 | * asserted, it will disable IRQ pin sensing and trigger an asynchronous i2c | ||
39 | * transfer to read touch status. When the transfer finishes, the driver will | ||
40 | * renable IRQ pin sensing. */ | ||
41 | |||
42 | static unsigned touch_status = 0; /* touch bitmask as reported by mpr121 */ | ||
43 | static struct imx233_i2c_xfer_t read_status_xfer; /* async transfer to read touch status */ | ||
44 | static uint8_t read_status_sel_reg; /* buffer for async transfer operation */ | ||
45 | static uint8_t read_status_buf[2]; /* buffer for async transfer operation */ | ||
46 | |||
47 | static void mpr121_irq_cb(int bank, int pin, intptr_t user); | ||
48 | |||
49 | static void touch_status_i2c_cb(struct imx233_i2c_xfer_t *xfer, enum imx233_i2c_error_t status) | ||
50 | { | ||
51 | (void) xfer; | ||
52 | (void) status; | ||
53 | /* put status in the global variable */ | ||
54 | touch_status = read_status_buf[0] | read_status_buf[1] << 8; | ||
55 | /* start sensing IRQ pin again */ | ||
56 | imx233_pinctrl_setup_irq(0, 18, true, true, false, &mpr121_irq_cb, 0); | ||
57 | } | ||
58 | |||
59 | void mpr121_irq_cb(int bank, int pin, intptr_t user) | ||
60 | { | ||
61 | (void) bank; | ||
62 | (void) pin; | ||
63 | (void) user; | ||
64 | /* NOTE the callback will not be fired until interrupt is enabled back. | ||
65 | * | ||
66 | * now setup an asynchronous i2c transfer to read touch status register, | ||
67 | * this is a readmem operation with a first stage to select register | ||
68 | * and a second stage to read status (2 bytes) */ | ||
69 | read_status_sel_reg = REG_TOUCH_STATUS; | ||
70 | |||
71 | read_status_xfer.next = NULL; | ||
72 | read_status_xfer.fast_mode = true; | ||
73 | read_status_xfer.dev_addr = MPR121_I2C_ADDR; | ||
74 | read_status_xfer.mode = I2C_READ; | ||
75 | read_status_xfer.count[0] = 1; /* set touch status register address */ | ||
76 | read_status_xfer.data[0] = &read_status_sel_reg; | ||
77 | read_status_xfer.count[1] = 2; | ||
78 | read_status_xfer.data[1] = &read_status_buf; | ||
79 | read_status_xfer.tmo_ms = 1000; | ||
80 | read_status_xfer.callback = &touch_status_i2c_cb; | ||
81 | |||
82 | imx233_i2c_transfer(&read_status_xfer); | ||
83 | } | ||
84 | |||
85 | static inline int mpr121_write_reg(uint8_t reg, uint8_t data) | ||
86 | { | ||
87 | return i2c_writemem(MPR121_I2C_ADDR, reg, &data, 1); | ||
88 | } | ||
89 | |||
90 | static inline int mpr121_read_reg(uint8_t reg, uint8_t *data) | ||
91 | { | ||
92 | return i2c_readmem(MPR121_I2C_ADDR, reg, data, 1); | ||
93 | } | ||
94 | |||
95 | void mpr121_init(void) | ||
96 | { | ||
97 | /* soft reset */ | ||
98 | mpr121_write_reg(REG_SOFTRESET, REG_SOFTRESET__MAGIC); | ||
99 | /* enable interrupt */ | ||
100 | imx233_pinctrl_acquire(0, 18, "mpr121_int"); | ||
101 | imx233_pinctrl_set_function(0, 18, PINCTRL_FUNCTION_GPIO); | ||
102 | imx233_pinctrl_enable_gpio(0, 18, false); | ||
103 | imx233_pinctrl_setup_irq(0, 18, true, true, false, &mpr121_irq_cb, 0); | ||
104 | } | ||
105 | |||
106 | void mpr121_set_config(struct mpr121_config_t *conf) | ||
107 | { | ||
108 | /* stop mode */ | ||
109 | mpr121_write_reg(REG_ELECTRODE, 0); | ||
110 | /* write baseline values */ | ||
111 | for(int i = 0; i < ELECTRODE_COUNT; i++) | ||
112 | mpr121_write_reg(REG_ExBV(i), conf->ele[i].bv); | ||
113 | /* write eleprox bv */ | ||
114 | mpr121_write_reg(REG_EPROXBV, conf->eleprox.bv); | ||
115 | /* write global fields */ | ||
116 | mpr121_write_reg(REG_MHDR, conf->filters.ele.rising.mhd); | ||
117 | mpr121_write_reg(REG_NHDR, conf->filters.ele.rising.nhd); | ||
118 | mpr121_write_reg(REG_NCLR, conf->filters.ele.rising.ncl); | ||
119 | mpr121_write_reg(REG_FDLR, conf->filters.ele.rising.fdl); | ||
120 | mpr121_write_reg(REG_MHDF, conf->filters.ele.falling.mhd); | ||
121 | mpr121_write_reg(REG_NHDF, conf->filters.ele.falling.nhd); | ||
122 | mpr121_write_reg(REG_NCLF, conf->filters.ele.falling.ncl); | ||
123 | mpr121_write_reg(REG_FDLF, conf->filters.ele.falling.fdl); | ||
124 | mpr121_write_reg(REG_NHDT, conf->filters.ele.touched.nhd); | ||
125 | mpr121_write_reg(REG_NCLT, conf->filters.ele.touched.ncl); | ||
126 | mpr121_write_reg(REG_FDLT, conf->filters.ele.touched.fdl); | ||
127 | mpr121_write_reg(REG_MHDPROXR, conf->filters.eleprox.rising.mhd); | ||
128 | mpr121_write_reg(REG_NHDPROXR, conf->filters.eleprox.rising.nhd); | ||
129 | mpr121_write_reg(REG_NCLPROXR, conf->filters.eleprox.rising.ncl); | ||
130 | mpr121_write_reg(REG_FDLPROXR, conf->filters.eleprox.rising.fdl); | ||
131 | mpr121_write_reg(REG_MHDPROXF, conf->filters.eleprox.falling.mhd); | ||
132 | mpr121_write_reg(REG_NHDPROXF, conf->filters.eleprox.falling.nhd); | ||
133 | mpr121_write_reg(REG_NCLPROXF, conf->filters.eleprox.falling.ncl); | ||
134 | mpr121_write_reg(REG_FDLPROXF, conf->filters.eleprox.falling.fdl); | ||
135 | mpr121_write_reg(REG_NHDPROXT, conf->filters.eleprox.touched.nhd); | ||
136 | mpr121_write_reg(REG_NCLPROXT, conf->filters.eleprox.touched.ncl); | ||
137 | mpr121_write_reg(REG_FDLPROXT, conf->filters.eleprox.touched.fdl); | ||
138 | /* touch & release thresholds */ | ||
139 | for(int i = 0; i < ELECTRODE_COUNT; i++) | ||
140 | { | ||
141 | mpr121_write_reg(REG_ExTTH(i), conf->ele[i].tth); | ||
142 | mpr121_write_reg(REG_ExRTH(i), conf->ele[i].rth); | ||
143 | } | ||
144 | mpr121_write_reg(REG_EPROXTTH, conf->eleprox.tth); | ||
145 | mpr121_write_reg(REG_EPROXRTH, conf->eleprox.rth); | ||
146 | /* debounce */ | ||
147 | mpr121_write_reg(REG_DEBOUNCE, REG_DEBOUNCE__DR(conf->debounce.dr) | | ||
148 | REG_DEBOUNCE__DT(conf->debounce.dt)); | ||
149 | /* analog-front end and filters */ | ||
150 | mpr121_write_reg(REG_AFE, REG_AFE__CDC(conf->global.cdc) | | ||
151 | REG_AFE__FFI(conf->global.ffi)); | ||
152 | mpr121_write_reg(REG_FILTER, REG_FILTER__CDT(conf->global.cdt) | | ||
153 | REG_FILTER__ESI(conf->global.esi) | REG_FILTER__SFI(conf->global.sfi)); | ||
154 | /* electrode charge */ | ||
155 | for(int i = 0; i < ELECTRODE_COUNT; i++) | ||
156 | mpr121_write_reg(REG_CDCx(i), conf->ele[i].cdc); | ||
157 | mpr121_write_reg(REG_CDCPROX, conf->eleprox.cdc); | ||
158 | for(int i = 0; i < ELECTRODE_COUNT; i += 2) | ||
159 | { | ||
160 | mpr121_write_reg(REG_CDTx(i), REG_CDTx__CDT0(conf->ele[i].cdt) | | ||
161 | REG_CDTx__CDT1(conf->ele[i+1].cdt)); | ||
162 | } | ||
163 | mpr121_write_reg(REG_CDTPROX, conf->eleprox.cdt); | ||
164 | /* Auto-Configuration */ | ||
165 | mpr121_write_reg(REG_AUTO_CONF, REG_AUTO_CONF__ACE(conf->autoconf.en) | | ||
166 | REG_AUTO_CONF__ARE(conf->autoconf.ren) | | ||
167 | REG_AUTO_CONF__BVA(conf->cal_lock) | | ||
168 | REG_AUTO_CONF__RETRY(conf->autoconf.retry) | | ||
169 | REG_AUTO_CONF__FFI(conf->global.ffi)); | ||
170 | mpr121_write_reg(REG_AUTO_CONF2, REG_AUTO_CONF2__ACFIE(conf->autoconf.acfie) | | ||
171 | REG_AUTO_CONF2__ARFIE(conf->autoconf.arfie) | | ||
172 | REG_AUTO_CONF2__OORIE(conf->autoconf.oorie) | | ||
173 | REG_AUTO_CONF2__SCTS(conf->autoconf.scts)); | ||
174 | mpr121_write_reg(REG_USL, conf->autoconf.usl); | ||
175 | mpr121_write_reg(REG_LSL, conf->autoconf.lsl); | ||
176 | mpr121_write_reg(REG_TL, conf->autoconf.tl); | ||
177 | /* electrode configuration */ | ||
178 | mpr121_write_reg(REG_ELECTRODE, REG_ELECTRODE__ELE_EN(conf->ele_en) | | ||
179 | REG_ELECTRODE__ELEPROX_EN(conf->eleprox_en) | | ||
180 | REG_ELECTRODE__CL(conf->cal_lock)); | ||
181 | /* gpio config */ | ||
182 | uint8_t ctl = 0; | ||
183 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
184 | if(ELE_GPIO_CTL0(conf->ele[i].gpio)) | ||
185 | ctl |= REG_GPIO_CTL0__CTL0x(i); | ||
186 | mpr121_write_reg(REG_GPIO_CTL0, ctl); | ||
187 | ctl = 0; | ||
188 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
189 | if(ELE_GPIO_CTL1(conf->ele[i].gpio)) | ||
190 | ctl |= REG_GPIO_CTL1__CTL1x(i); | ||
191 | mpr121_write_reg(REG_GPIO_CTL1, ctl); | ||
192 | ctl = 0; | ||
193 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
194 | if(ELE_GPIO_DIR(conf->ele[i].gpio)) | ||
195 | ctl |= REG_GPIO_DIR__DIRx(i); | ||
196 | mpr121_write_reg(REG_GPIO_DIR, ctl); | ||
197 | ctl = 0; | ||
198 | for(int i = ELE_GPIO_FIRST; i <= ELE_GPIO_LAST; i++) | ||
199 | if(ELE_GPIO_EN(conf->ele[i].gpio)) | ||
200 | ctl |= REG_GPIO_EN__ENx(i); | ||
201 | mpr121_write_reg(REG_GPIO_EN, ctl); | ||
202 | } | ||
203 | |||
204 | void mpr121_set_gpio_output(int ele, int gpio_val) | ||
205 | { | ||
206 | switch(gpio_val) | ||
207 | { | ||
208 | case ELE_GPIO_SET: | ||
209 | mpr121_write_reg(REG_GPIO_SET, REG_GPIO_SET__SETx(ele)); | ||
210 | break; | ||
211 | case ELE_GPIO_CLR: | ||
212 | mpr121_write_reg(REG_GPIO_CLR, REG_GPIO_CLR__CLRx(ele)); | ||
213 | break; | ||
214 | case ELE_GPIO_TOG: | ||
215 | mpr121_write_reg(REG_GPIO_TOG, REG_GPIO_TOG__TOGx(ele)); | ||
216 | break; | ||
217 | default: | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | void mpr121_set_gpio_pwm(int ele, int pwm) | ||
223 | { | ||
224 | uint8_t reg_val; | ||
225 | mpr121_read_reg(REG_PWMx(ele), ®_val); | ||
226 | if(REG_PWMx_IS_PWM0(ele)) | ||
227 | reg_val = (reg_val & ~REG_PWMx__PWM0_BM) | REG_PWMx__PWM0(pwm); | ||
228 | else | ||
229 | reg_val = (reg_val & ~REG_PWMx__PWM1_BM) | REG_PWMx__PWM1(pwm); | ||
230 | mpr121_write_reg(REG_PWMx(ele), reg_val); | ||
231 | } | ||
232 | |||
233 | unsigned mpr121_get_touch_status(void) | ||
234 | { | ||
235 | return touch_status; | ||
236 | } | ||
diff --git a/firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.h b/firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.h new file mode 100644 index 0000000000..eb8b00eeee --- /dev/null +++ b/firmware/target/arm/imx233/creative-zenxfi3/mpr121-zenxfi3.h | |||
@@ -0,0 +1,176 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2016 Amaury Pouly | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __MPR121_ZENXFI3_H__ | ||
22 | #define __MPR121_ZENXFI3_H__ | ||
23 | |||
24 | /** Driver for the Freescale MPR121 Capacitive Proximity Sensor */ | ||
25 | #include "system.h" | ||
26 | |||
27 | #define ELECTRODE_COUNT 12 | ||
28 | #define ELE_GPIO_FIRST 4 | ||
29 | #define ELE_GPIO_LAST 11 | ||
30 | |||
31 | /* gpio config (encoding: [0]=en,[1]=dir,[2]=ctl[1],[3]=ctl[0]) */ | ||
32 | #define ELE_GPIO_DISABLE 0 | ||
33 | #define ELE_GPIO_INPUT 1 | ||
34 | #define ELE_GPIO_INPUT_PULLDOWN 9 /* input with pull-down */ | ||
35 | #define ELE_GPIO_INPUT_PULLUP 13 /* input with pull-up */ | ||
36 | #define ELE_GPIO_OUTPUT 3 | ||
37 | #define ELE_GPIO_OUTPUT_OPEN 11 /* open drain low-side */ | ||
38 | #define ELE_GPIO_OUTPUT_OPEN_LED 15 /* open drain high-side (led driver) */ | ||
39 | |||
40 | /* internal use */ | ||
41 | #define ELE_GPIO_EN(val) ((val) & 1) | ||
42 | #define ELE_GPIO_DIR(val) (((val) >> 1) & 1) | ||
43 | #define ELE_GPIO_CTL0(val) (((val) >> 3) & 1) | ||
44 | #define ELE_GPIO_CTL1(val) (((val) >> 1) & 1) | ||
45 | |||
46 | struct mpr121_electrode_config_t | ||
47 | { | ||
48 | uint8_t bv; /* baseline value */ | ||
49 | uint8_t tth; /* touch threshold */ | ||
50 | uint8_t rth; /* release threshold */ | ||
51 | uint8_t cdc; /* charge current (optional if auto-conf) */ | ||
52 | uint8_t cdt; /* charge time (optional if auto-conf) */ | ||
53 | int gpio; /* gpio config */ | ||
54 | }; | ||
55 | |||
56 | struct mpr121_baseline_filter_config_t | ||
57 | { | ||
58 | uint8_t mhd; /* max half delta (except for touched) */ | ||
59 | uint8_t nhd; /* noise half delta */ | ||
60 | uint8_t ncl; /* noise count limit */ | ||
61 | uint8_t fdl; /* filter delay count limit */ | ||
62 | }; | ||
63 | |||
64 | struct mpr121_baseline_filters_config_t | ||
65 | { | ||
66 | struct mpr121_baseline_filter_config_t rising; | ||
67 | struct mpr121_baseline_filter_config_t falling; | ||
68 | struct mpr121_baseline_filter_config_t touched; | ||
69 | }; | ||
70 | |||
71 | struct mpr121_debounce_config_t | ||
72 | { | ||
73 | uint8_t dt; /* debounce count for touch */ | ||
74 | uint8_t dr; /* debounce count for release */ | ||
75 | }; | ||
76 | |||
77 | /* first filter iterations */ | ||
78 | #define FFI_6_SAMPLES 0 | ||
79 | #define FFI_10_SAMPLES 1 | ||
80 | #define FFI_18_SAMPLES 2 | ||
81 | #define FFI_34_SAMPLES 3 | ||
82 | /* charge discharge current */ | ||
83 | #define CDC_DISABLE 0 | ||
84 | #define CDC_uA(ua) (ua) | ||
85 | /* charge discharge time */ | ||
86 | #define CDT_DISABLE 0 | ||
87 | #define CDT_log_us(lus) (lus) /* actual value = 2^{us-2} µs */ | ||
88 | /* second filter iterations */ | ||
89 | #define SFI_4_SAMPLES 0 | ||
90 | #define SFI_6_SAMPLES 1 | ||
91 | #define SFI_10_SAMPLES 2 | ||
92 | #define SFI_18_SAMPLES 3 | ||
93 | /* Eletrode sample interval */ | ||
94 | #define ESI_log_ms(lms) (lms) /* actual value = 2^{lms} ms */ | ||
95 | |||
96 | struct mpr121_global_config_t | ||
97 | { | ||
98 | uint8_t ffi; /* first filter iterations */ | ||
99 | uint8_t cdc; /* global charge discharge current */ | ||
100 | uint8_t cdt; /* global charge discharge time */ | ||
101 | uint8_t sfi; /* second first iterations */ | ||
102 | uint8_t esi; /* electrode sample interval */ | ||
103 | }; | ||
104 | |||
105 | #define RETRY_NEVER 0 | ||
106 | #define RETRY_2_TIMES 1 | ||
107 | #define RETRY_4_TIMES 2 | ||
108 | #define RETRY_8_TIMES 3 | ||
109 | |||
110 | struct mpr121_auto_config_t | ||
111 | { | ||
112 | bool en; /* auto-conf enable */ | ||
113 | bool ren; /* auto-reconf enable */ | ||
114 | uint8_t retry; /* retry count */ | ||
115 | bool scts; /* skip charge time search */ | ||
116 | uint8_t usl; /* upper-side limit */ | ||
117 | uint8_t lsl; /* lower-side limit */ | ||
118 | uint8_t tl; /* target level */ | ||
119 | bool acfie; /* auto-conf fail interrupt en */ | ||
120 | bool arfie; /* auto-reconf fail interrupt en */ | ||
121 | bool oorie; /* out of range interrupt en */ | ||
122 | }; | ||
123 | |||
124 | /* electrode mode */ | ||
125 | #define ELE_DISABLE 0 | ||
126 | #define ELE_EN0_x(x) ((x) + 1) | ||
127 | /* eleprox mode */ | ||
128 | #define ELEPROX_DISABLE 0 | ||
129 | #define ELEPROX_EN0_1 1 | ||
130 | #define ELEPROX_EN0_3 2 | ||
131 | #define ELEPROX_EN0_11 3 | ||
132 | /* calibration lock */ | ||
133 | #define CL_SLOW_TRACK 0 | ||
134 | #define CL_DISABLE 1 | ||
135 | #define CL_TRACK 2 | ||
136 | #define CL_FAST_TRACK 3 | ||
137 | |||
138 | struct mpr121_config_t | ||
139 | { | ||
140 | struct mpr121_electrode_config_t ele[ELECTRODE_COUNT]; | ||
141 | struct mpr121_electrode_config_t eleprox; | ||
142 | struct | ||
143 | { | ||
144 | struct mpr121_baseline_filters_config_t ele; | ||
145 | struct mpr121_baseline_filters_config_t eleprox; | ||
146 | }filters; | ||
147 | struct mpr121_debounce_config_t debounce; | ||
148 | struct mpr121_global_config_t global; | ||
149 | struct mpr121_auto_config_t autoconf; | ||
150 | uint8_t ele_en; /* eletroce mode */ | ||
151 | uint8_t eleprox_en; /* proximity mode */ | ||
152 | uint8_t cal_lock; /* calibration lock */ | ||
153 | }; | ||
154 | |||
155 | /* gpio value */ | ||
156 | #define ELE_GPIO_CLR 0 | ||
157 | #define ELE_GPIO_SET 1 | ||
158 | #define ELE_GPIO_TOG 2 | ||
159 | /* pwm value */ | ||
160 | #define ELE_PWM_DISABLE 0 | ||
161 | #define ELE_PWM_DUTY(x) (x) | ||
162 | #define ELE_PWM_MIN_DUTY 1 | ||
163 | #define ELE_PWM_MAX_DUTY 15 | ||
164 | |||
165 | void mpr121_init(void); | ||
166 | void mpr121_set_config(struct mpr121_config_t *conf); | ||
167 | /* gpios are only implemented for electrode>=4, use ELE_GPIO_* for value */ | ||
168 | void mpr121_set_gpio_output(int ele, int gpio_val); | ||
169 | /* pwm value is between 0 and 15, use ELE_PWM_DISABLE or ELE_PWM_DUTY */ | ||
170 | void mpr121_set_gpio_pwm(int ele, int pwm); | ||
171 | /* get electrode status (bitmap) | ||
172 | * NOTE this function merely returns the last electrode status read from the | ||
173 | * device and does not actively ask the device for touch status. */ | ||
174 | unsigned mpr121_get_touch_status(void); | ||
175 | |||
176 | #endif /* __MPR121_ZENXFI3_H__ */ | ||