1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "aos/kernel.h"
10 #include "sensor_drv_api.h"
11 #include "sensor_hal.h"
12
13 #define TMD2725_REG_ENABLE 0x80
14 #define TMD2725_REG_ATIME 0x81
15 #define TMD2725_REG_PTIME 0x82
16 #define TMD2725_REG_WTIME 0x83
17 #define TMD2725_REG_AILT 0x84
18 #define TMD2725_REG_AILT_HI 0x85
19 #define TMD2725_REG_AIHT 0x86
20 #define TMD2725_REG_AIHT_HI 0x87
21 #define TMD2725_REG_PILT 0x88
22 #define TMD2725_REG_PIHT 0x8A
23 #define TMD2725_REG_PERS 0x8C
24 #define TMD2725_REG_CFG0 0x8D
25 #define TMD2725_REG_PGCFG0 0x8E
26 #define TMD2725_REG_PGCFG1 0x8F
27
28 #define TMD2725_REG_CFG1 0x90
29 #define TMD2725_REG_REVID 0x91
30 #define TMD2725_REG_CHIPID 0x92
31 #define TMD2725_REG_STATUS 0x93
32 #define TMD2725_REG_CH0DATA 0x94
33 #define TMD2725_REG_CH0DATA_HI 0x95
34 #define TMD2725_REG_CH1DATA 0x96
35 #define TMD2725_REG_CH1DATA_HI 0x97
36 #define TMD2725_REG_PDATA 0x9C
37
38 #define TMD2725_REG_ADCDATA_L 0x9D
39 #define TMD2725_REG_AUXID 0x9E
40 #define TMD2725_REG_CFG2 0x9F
41
42 #define TMD2725_REG_CFG3 0xAB
43 #define TMD2725_REG_CFG4 0xAC
44 #define TMD2725_REG_CFG5 0xAD
45
46 #define TMD2725_REG_POFFSET_L 0xC0
47 #define TMD2725_REG_POFFSET_H 0xC1
48
49 #define TMD2725_REG_AZ_CONFIG 0xD6
50 #define TMD2725_REG_CALIB 0xD7
51 #define TMD2725_REG_CALIBCFG 0xD9
52 #define TMD2725_REG_CALIBSTAT 0xDC
53 #define TMD2725_REG_INTENAB 0xDD
54
55 #define TMD2725_CHIPID_VALUE 0xE4
56 #define TMD2725_I2C_SLAVE_ADDR 0x39
57 #define TMD2725_ADDR_TRANS(n) ((n) << 1)
58 #define TMD2725_I2C_ADDR TMD2725_ADDR_TRANS(TMD2725_I2C_SLAVE_ADDR)
59
60
61 enum tmd2725_reg
62 {
63 TMD2725_MASK_BINSRCH_TARGET = 0x70,
64 TMD2725_SHIFT_BINSRCH_TARGET = 4,
65
66 TMD2725_MASK_START_OFFSET_CALIB = 0x01,
67
68 TMD2725_MASK_PROX_PERS = 0xf0,
69
70 TMD2725_MASK_PDRIVE = 0x1f,
71
72 TMD2725_MASK_PGAIN = 0xC0,
73 TMD2725_SHIFT_PGAIN = 6,
74
75 TMD2725_MASK_AGAIN = 0x03,
76 TMD2725_SHIFT_AGAIN = 0,
77
78 TMD2725_MASK_APERS = 0x0f,
79
80 TMD2725_MASK_POFFSET_H = 0x01,
81 TMD2725_SHIFT_POFFSET_H = 0,
82
83 TMD2725_MASK_PROX_DATA_AVG = 0x07, // AVG 8counts
84 TMD2725_SHIFT_PROX_DATA_AVG = 0,
85
86 TMD2725_MASK_PROX_AUTO_OFFSET_ADJUST = 0x08,
87 TMD2725_SHIFT_PROX_AUTO_OFFSET_ADJUST = 3,
88 };
89
90 enum tmd2725_en_reg
91 {
92 TMD2725_PON = (1 << 0),
93 TMD2725_AEN = (1 << 1),
94 TMD2725_PEN = (1 << 2),
95 TMD2725_WEN = (1 << 3),
96 TMD2725_EN_ALL = (TMD2725_AEN | TMD2725_PEN | TMD2725_WEN),
97 };
98
99 static uint8_t const regs[] = {
100 TMD2725_REG_PILT, TMD2725_REG_PIHT, TMD2725_REG_PERS, TMD2725_REG_PGCFG0,
101 TMD2725_REG_PGCFG1, TMD2725_REG_CFG1, TMD2725_REG_PTIME, TMD2725_REG_ATIME,
102 };
103
104 static uint8_t const als_regs[] = {
105 TMD2725_REG_ATIME, TMD2725_REG_WTIME, TMD2725_REG_PERS,
106 TMD2725_REG_CFG0, TMD2725_REG_CFG1,
107 };
108
109 enum tmd2725_status
110 {
111 TMD2725_ST_PGSAT_AMBIENT = (1 << 0),
112 TMD2725_ST_PGSAT_RELFLECT = (1 << 1),
113 TMD2725_ST_ZERODET = (1 << 2),
114 TMD2725_ST_CAL_IRQ = (1 << 3),
115 TMD2725_ST_ALS_IRQ = (1 << 4),
116 TMD2725_ST_PRX_IRQ = (1 << 5),
117 TMD2725_ST_PRX_SAT = (1 << 6),
118 TMD2725_ST_ALS_SAT = (1 << 7),
119 };
120
121 enum tmd2725_intenab_reg
122 {
123 TMD2725_CIEN = (1 << 3),
124 TMD2725_AIEN = (1 << 4),
125 TMD2725_PIEN = (1 << 5),
126 TMD2725_PSIEN = (1 << 6),
127 TMD2725_ASIEN = (1 << 7),
128 };
129
130 enum tmd2725_pwr_state
131 {
132 POWER_ON,
133 POWER_OFF,
134 POWER_STANDBY,
135 };
136
137 enum tmd2725_prox_state
138 {
139 PROX_STATE_NONE = 0,
140 PROX_STATE_INIT,
141 PROX_STATE_CALIB,
142 PROX_STATE_WAIT_AND_CALIB
143 };
144
145 enum tmd2725_ctrl_reg
146 {
147 AGAIN_1 = (0 << 0),
148 AGAIN_4 = (1 << 0),
149 AGAIN_16 = (2 << 0),
150 AGAIN_64 = (3 << 0),
151 PGAIN_1 = (0 << TMD2725_SHIFT_PGAIN),
152 PGAIN_2 = (1 << TMD2725_SHIFT_PGAIN),
153 PGAIN_4 = (2 << TMD2725_SHIFT_PGAIN),
154 PGAIN_8 = (3 << TMD2725_SHIFT_PGAIN),
155 PG_PULSE_4US = (0 << 6),
156 PG_PULSE_8US = (1 << 6),
157 PG_PULSE_16US = (2 << 6),
158 PG_PULSE_32US = (3 << 6),
159 };
160
161 static uint8_t const als_gains[] = { 1, 4, 16, 64 };
162 // pldriver
163 #define PDRIVE_MA(p) (((uint8_t)((p) / 6) - 1) & 0x1f)
164 #define P_TIME_US(p) ((((p) / 88) - 1.0) + 0.5)
165 #define PRX_PERSIST(p) (((p)&0xf) << 4)
166
167 #define INTEGRATION_CYCLE 2816
168 #define AW_TIME_MS(p) \
169 ((((p)*1000) + (INTEGRATION_CYCLE - 1)) / INTEGRATION_CYCLE)
170 #define ALS_PERSIST(p) (((p)&0xf) << 0)
171
172 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
173 // lux
174 #define INDOOR_LUX_TRIGGER 6000
175 #define OUTDOOR_LUX_TRIGGER 10000
176 #define TMD2725_MAX_LUX 0xffff
177 #define TMD2725_MAX_ALS_VALUE 0xffff
178 #define TMD2725_MIN_ALS_VALUE 10
179
180 /* Default LUX coefficients */
181 #define DFG 56
182 #define CoefA 1000
183 #define CoefB 82
184 #define CoefC 788
185 #define CoefD 41
186 #define MAX_REGS 256
187
188 #define max(a, b) (((a) > (b)) ? (a) : (b))
189 #define min(a, b) (((a) < (b)) ? (a) : (b))
190
191 struct tmd2725_lux_segment
192 {
193 uint32_t ch0_coef;
194 uint32_t ch1_coef;
195 };
196
197 struct tmd2725_als_inf
198 {
199 uint16_t als_ch0;
200 uint16_t als_ch1;
201 uint32_t CPL;
202 uint32_t lux1_ch0_coef;
203 uint32_t lux1_ch1_coef;
204 uint32_t lux2_ch0_coef;
205 uint32_t lux2_ch1_coef;
206 uint32_t sat;
207 uint16_t lux;
208 };
209
210 struct tmd2725_prox_inf
211 {
212 uint16_t raw;
213 int detected;
214 };
215
216 struct tmd2725_chips
217 {
218 bool als_enabled;
219 uint8_t atime;
220 uint8_t again;
221 uint8_t persist;
222
223 bool prox_enabled;
224 int16_t prox_th_min;
225 int16_t prox_th_max;
226 uint8_t prox_gain;
227 uint8_t prox_drive;
228 uint8_t prox_pulse_cnt;
229 uint8_t prox_pulse_len;
230 int16_t prox_offset;
231
232 uint8_t shadow[MAX_REGS];
233 struct tmd2725_lux_segment lux_segment[2];
234 struct tmd2725_prox_inf prx_inf;
235 struct tmd2725_als_inf als_inf;
236 };
237
238 i2c_dev_t tmd2725_ctx = {
239 .port = 3,
240 .config.address_width = 8,
241 .config.freq = 400000,
242 .config.dev_addr = TMD2725_I2C_ADDR,
243 };
244
245 static struct tmd2725_chips tmd2725_chip;
246 static uint8_t init_flag = 0;
247
drv_als_ps_ams_tmd2725_validate_id(i2c_dev_t * drv,uint8_t id_value)248 static int drv_als_ps_ams_tmd2725_validate_id(i2c_dev_t *drv, uint8_t id_value)
249 {
250 int ret = 0;
251 uint8_t chipid_value;
252 ret = sensor_i2c_read(drv, TMD2725_REG_CHIPID, &chipid_value, I2C_DATA_LEN,
253 I2C_OP_RETRIES);
254 if (unlikely(ret)) {
255 LOG("%s %s Sensor_i2c_read failure \n", SENSOR_STR, __func__);
256 return ret;
257 }
258 if (chipid_value != id_value)
259 return -1;
260
261 return 0;
262 }
263
tmd2725_reset_als_regs(i2c_dev_t * drv)264 static int tmd2725_reset_als_regs(i2c_dev_t *drv)
265 {
266 int i;
267 int ret = 0;
268 uint8_t reg;
269 for (i = 0; i < ARRAY_SIZE(als_regs); i++) {
270 reg = als_regs[i];
271 ret = sensor_i2c_write(drv, reg, &(tmd2725_chip.shadow[reg]),
272 I2C_DATA_LEN, I2C_OP_RETRIES);
273 if (unlikely(ret)) {
274 LOG("%s %s tmd2725 reset_als_regs failure \n", SENSOR_STR,
275 __func__);
276 return ret;
277 }
278 }
279 return 0;
280 }
281
sensor_i2c_modify(i2c_dev_t * drv,uint8_t * shadow,uint16_t reg,uint8_t mask,uint8_t value)282 static int32_t sensor_i2c_modify(i2c_dev_t *drv, uint8_t *shadow, uint16_t reg,
283 uint8_t mask, uint8_t value)
284 {
285 int ret;
286 uint8_t temp;
287 ret = sensor_i2c_read(drv, reg, &temp, I2C_DATA_LEN, I2C_OP_RETRIES);
288 if (unlikely(ret)) {
289 LOG("%s %s tmd2725 sensor_i2c_modify \n", SENSOR_STR, __func__);
290 return ret;
291 }
292 temp &= ~mask;
293 temp |= value;
294 sensor_i2c_write(drv, reg, &temp, I2C_DATA_LEN, I2C_OP_RETRIES);
295 shadow[reg] = temp;
296 return 0;
297 }
298
drv_als_ams_tmd2725_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)299 static int drv_als_ams_tmd2725_set_power_mode(i2c_dev_t * drv,
300 dev_power_mode_e mode)
301 {
302 switch (mode) {
303 case DEV_POWER_ON: {
304 if (!(tmd2725_chip.als_enabled)) {
305 tmd2725_chip.shadow[TMD2725_REG_ATIME] = tmd2725_chip.atime;
306 tmd2725_chip.shadow[TMD2725_REG_PERS] &= (~TMD2725_MASK_APERS);
307 tmd2725_chip.shadow[TMD2725_REG_PERS] |= 0x02;
308 tmd2725_reset_als_regs(drv);
309 sensor_i2c_modify(drv, tmd2725_chip.shadow, TMD2725_REG_INTENAB,
310 TMD2725_AIEN, TMD2725_AIEN);
311 sensor_i2c_modify(drv, tmd2725_chip.shadow, TMD2725_REG_ENABLE,
312 TMD2725_WEN | TMD2725_AEN | TMD2725_PON,
313 TMD2725_WEN | TMD2725_AEN | TMD2725_PON);
314 tmd2725_chip.als_enabled = true;
315 }
316 } break;
317 case DEV_POWER_OFF:
318 case DEV_SLEEP: {
319 sensor_i2c_modify(drv, tmd2725_chip.shadow, TMD2725_REG_INTENAB,
320 TMD2725_AIEN, 0);
321 sensor_i2c_modify(drv, tmd2725_chip.shadow, TMD2725_REG_ENABLE,
322 TMD2725_WEN | TMD2725_AEN, 0);
323 tmd2725_chip.als_enabled = false;
324 if (!(tmd2725_chip.shadow[TMD2725_REG_ENABLE] & TMD2725_EN_ALL))
325 sensor_i2c_modify(drv, tmd2725_chip.shadow, TMD2725_REG_ENABLE,
326 TMD2725_PON, 0);
327 } break;
328 default:
329 break;
330 }
331 return 0;
332 }
333
tmd2725_reset_regs(i2c_dev_t * drv)334 static int tmd2725_reset_regs(i2c_dev_t *drv)
335 {
336 int i;
337 int ret = 0;
338 uint8_t reg;
339 for (i = 0; i < ARRAY_SIZE(regs); i++) {
340 reg = regs[i];
341 ret = sensor_i2c_write(drv, reg, &(tmd2725_chip.shadow[reg]),
342 I2C_DATA_LEN, I2C_OP_RETRIES);
343 if (unlikely(ret)) {
344 LOG("%s %s tmd2725 reset_regs failure %d \n", SENSOR_STR,
345 __func__);
346 return ret;
347 }
348 }
349 return 0;
350 }
351
drv_als_ps_ams_tmd2725_set_default_config(i2c_dev_t * drv)352 static int drv_als_ps_ams_tmd2725_set_default_config(i2c_dev_t *drv)
353 {
354 int ret = 0;
355 if (!init_flag) {
356 tmd2725_chip.prox_th_min = 50;
357 tmd2725_chip.prox_th_max = 80;
358 tmd2725_chip.persist = PRX_PERSIST(0) | ALS_PERSIST(0);
359 tmd2725_chip.prox_pulse_cnt = 4;
360 tmd2725_chip.prox_gain = PGAIN_4;
361 tmd2725_chip.prox_drive = PDRIVE_MA(75);
362 tmd2725_chip.prox_offset = 0;
363 tmd2725_chip.prox_pulse_len = PG_PULSE_16US;
364 tmd2725_chip.again = AGAIN_16;
365 tmd2725_chip.atime = AW_TIME_MS(200);
366
367 tmd2725_chip.lux_segment[0].ch0_coef = CoefA;
368 tmd2725_chip.lux_segment[0].ch1_coef = CoefB;
369 tmd2725_chip.lux_segment[1].ch0_coef = CoefC;
370 tmd2725_chip.lux_segment[1].ch1_coef = CoefD;
371
372 tmd2725_chip.als_enabled = false;
373 tmd2725_chip.prox_enabled = false;
374
375 /* initial some config register */
376 tmd2725_chip.shadow[TMD2725_REG_PILT] = tmd2725_chip.prox_th_min & 0xff;
377 tmd2725_chip.shadow[TMD2725_REG_PIHT] = tmd2725_chip.prox_th_max & 0xff;
378 tmd2725_chip.shadow[TMD2725_REG_PERS] = tmd2725_chip.persist;
379 tmd2725_chip.shadow[TMD2725_REG_PGCFG0] =
380 tmd2725_chip.prox_pulse_cnt | tmd2725_chip.prox_pulse_len;
381 tmd2725_chip.shadow[TMD2725_REG_ATIME] = tmd2725_chip.atime;
382 tmd2725_chip.shadow[TMD2725_REG_CFG1] = tmd2725_chip.again;
383 tmd2725_chip.shadow[TMD2725_REG_PTIME] = P_TIME_US(2816);
384 tmd2725_chip.shadow[TMD2725_REG_PGCFG1] =
385 (tmd2725_chip.prox_gain & TMD2725_MASK_PGAIN) |
386 tmd2725_chip.prox_drive;
387
388 struct tmd2725_lux_segment *als = &(tmd2725_chip.lux_segment[0]);
389 tmd2725_chip.als_inf.lux1_ch0_coef = DFG * (als[0].ch0_coef);
390 tmd2725_chip.als_inf.lux1_ch1_coef = DFG * (als[0].ch1_coef);
391 tmd2725_chip.als_inf.lux2_ch0_coef = DFG * (als[1].ch0_coef);
392 tmd2725_chip.als_inf.lux2_ch1_coef = DFG * (als[1].ch1_coef);
393
394 ret = tmd2725_reset_regs(&tmd2725_ctx);
395 if (unlikely(ret)) {
396 LOG("%s %s , tmd2725 reset regs failure \n", SENSOR_STR, __func__);
397 return ret;
398 }
399 init_flag = 1;
400 }
401 return 0;
402 }
403
drv_als_ams_tmd2725_irq_handle(void)404 static void drv_als_ams_tmd2725_irq_handle(void)
405 {
406 /* no handle so far */
407 }
408
drv_als_ams_tmd2725_open(void)409 static int drv_als_ams_tmd2725_open(void)
410 {
411 int ret = 0;
412 ret = drv_als_ams_tmd2725_set_power_mode(&tmd2725_ctx, DEV_POWER_ON);
413 if (unlikely(ret)) {
414 return -1;
415 }
416 return 0;
417 }
418
drv_als_ams_tmd2725_close(void)419 static int drv_als_ams_tmd2725_close(void)
420 {
421 int ret = 0;
422 ret = drv_als_ams_tmd2725_set_power_mode(&tmd2725_ctx, DEV_POWER_OFF);
423 if (unlikely(ret)) {
424 return -1;
425 }
426 return 0;
427 }
428
tmd2725_read_als_data()429 static int tmd2725_read_als_data()
430 {
431 int ret;
432 uint8_t *buf;
433 ret = sensor_i2c_read(&tmd2725_ctx, TMD2725_REG_CH0DATA,
434 &(tmd2725_chip.shadow[TMD2725_REG_CH0DATA]), 4,
435 I2C_OP_RETRIES);
436 if (unlikely(ret)) {
437 LOG("%s %s tmd2725_read_als_data failure \n", SENSOR_STR, __func__);
438 return ret;
439 }
440 buf = &(tmd2725_chip.shadow[TMD2725_REG_CH0DATA]);
441 tmd2725_chip.als_inf.als_ch0 = (uint16_t)((buf[1] << 8) | buf[0]);
442 tmd2725_chip.als_inf.als_ch1 = (uint16_t)((buf[3] << 8) | buf[2]);
443
444 // LOG("%s %s als_ch0 is %d als_ch1 is %d \n",
445 // SENSOR_STR,__func__,tmd2725_chip.als_inf.als_ch0,tmd2725_chip.als_inf.als_ch1);
446
447 return 0;
448 }
449
tmd2725_als_cal_cpl()450 static int tmd2725_als_cal_cpl()
451 {
452 uint32_t cpl;
453 uint32_t sat;
454 uint8_t atime;
455 atime = tmd2725_chip.shadow[TMD2725_REG_ATIME];
456 cpl = atime;
457 cpl *= INTEGRATION_CYCLE;
458 cpl *=
459 als_gains[tmd2725_chip.shadow[TMD2725_REG_CFG1] & TMD2725_MASK_AGAIN];
460
461 sat = (int32_t)(atime << 10);
462 if (sat > TMD2725_MAX_ALS_VALUE)
463 sat = TMD2725_MAX_ALS_VALUE;
464
465 sat = sat * 8 / 10;
466 tmd2725_chip.als_inf.CPL = cpl;
467 tmd2725_chip.als_inf.sat = sat;
468
469 // LOG("CPL is %d sat is %d, atime is %d again is
470 // %d\n",tmd2725_chip.als_inf.CPL,tmd2725_chip.als_inf.sat,
471 // tmd2725_chip.atime, tmd2725_chip.again);
472 return 0;
473 }
474
tmd2725_set_als_gain(uint8_t gain)475 static int tmd2725_set_als_gain(uint8_t gain)
476 {
477 uint8_t ctrl_reg;
478 uint8_t temp, temp_zero = 0;
479 switch (gain) {
480 case 1:
481 ctrl_reg = AGAIN_1;
482 break;
483 case 4:
484 ctrl_reg = AGAIN_4;
485 break;
486 case 16:
487 ctrl_reg = AGAIN_16;
488 break;
489 case 64:
490 ctrl_reg = AGAIN_64;
491 break;
492 default:
493 LOG("set als_gain wrong Gain data \n");
494 return -1;
495 }
496 sensor_i2c_read(&tmd2725_ctx, TMD2725_REG_ENABLE, &temp, I2C_DATA_LEN,
497 I2C_OP_RETRIES);
498 sensor_i2c_write(&tmd2725_ctx, TMD2725_REG_ENABLE, &temp_zero, I2C_DATA_LEN,
499 I2C_OP_RETRIES);
500 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_CFG1,
501 TMD2725_MASK_AGAIN, ctrl_reg);
502 sensor_i2c_write(&tmd2725_ctx, TMD2725_REG_ENABLE, &temp, I2C_DATA_LEN,
503 I2C_OP_RETRIES);
504
505 tmd2725_chip.again = tmd2725_chip.shadow[TMD2725_REG_CFG1];
506 return 0;
507 }
508
509
tmd2725_als_inc_gain()510 static int tmd2725_als_inc_gain()
511 {
512 int ret;
513 uint8_t gain = (tmd2725_chip.shadow[TMD2725_REG_CFG1] & TMD2725_MASK_AGAIN);
514 if (gain > AGAIN_16)
515 return 1;
516 else if (gain < AGAIN_4)
517 gain = als_gains[AGAIN_4];
518 else if (gain < AGAIN_16)
519 gain = als_gains[AGAIN_16];
520 else
521 gain = als_gains[AGAIN_64];
522
523 ret = tmd2725_set_als_gain(gain);
524 if (unlikely(ret)) {
525 LOG("%s %s tmd2725_set_als_gain false\n", SENSOR_STR, __func__);
526 return ret;
527 }
528 tmd2725_als_cal_cpl();
529 return 0;
530 }
531
tmd2725_als_dec_gain()532 static int tmd2725_als_dec_gain()
533 {
534 int ret;
535 uint8_t gain = (tmd2725_chip.shadow[TMD2725_REG_CFG1] & TMD2725_MASK_AGAIN);
536 if (gain == AGAIN_1)
537 return 1;
538 else if (gain > AGAIN_16)
539 gain = als_gains[AGAIN_16];
540 else if (gain > AGAIN_4)
541 gain = als_gains[AGAIN_4];
542 else
543 gain = als_gains[AGAIN_1];
544
545 ret = tmd2725_set_als_gain(gain);
546 if (unlikely(ret)) {
547 LOG("%s %s tmd2725_set_als_gain false in dec_gain\n", SENSOR_STR,
548 __func__);
549 return ret;
550 }
551 tmd2725_als_cal_cpl();
552 return 0;
553 }
554
tmd2725_max_als_value()555 static int tmd2725_max_als_value()
556 {
557 int val;
558 val = tmd2725_chip.shadow[TMD2725_REG_ATIME];
559
560 if (val > 63)
561 val = 0xffff;
562 else
563 val = ((val * 1024) - 1);
564
565 return val;
566 }
tmd2725_get_lux()567 static int tmd2725_get_lux()
568 {
569 int ch0, ch1, lux1, lux2, lux;
570 ch0 = tmd2725_chip.als_inf.als_ch0;
571 ch1 = tmd2725_chip.als_inf.als_ch1;
572
573 tmd2725_als_cal_cpl();
574 lux1 = ((tmd2725_chip.als_inf.lux1_ch0_coef * ch0) -
575 (tmd2725_chip.als_inf.lux1_ch1_coef * ch1)) /
576 tmd2725_chip.als_inf.CPL;
577 lux2 = ((tmd2725_chip.als_inf.lux2_ch0_coef * ch0) -
578 (tmd2725_chip.als_inf.lux2_ch1_coef * ch1)) /
579 tmd2725_chip.als_inf.CPL;
580 lux = max(lux1, lux2);
581 lux = min(TMD2725_MAX_LUX, max(0, lux));
582
583 tmd2725_chip.als_inf.lux = lux;
584
585 if (ch0 < 100) {
586 tmd2725_als_inc_gain();
587 tmd2725_reset_als_regs(&tmd2725_ctx);
588 } else if (ch0 >= tmd2725_max_als_value()) {
589 tmd2725_als_dec_gain();
590 tmd2725_reset_als_regs(&tmd2725_ctx);
591 }
592 return 0;
593 }
594
drv_als_ams_tmd2725_read(void * buf,size_t len)595 static int drv_als_ams_tmd2725_read(void *buf, size_t len)
596 {
597 int ret;
598 size_t size;
599 uint8_t status = 0;
600 als_data_t *sensordata = (als_data_t *)buf;
601
602 if (buf == NULL) {
603 return -1;
604 }
605 size = sizeof(als_data_t);
606 if (len < size) {
607 return -1;
608 }
609
610 ret = sensor_i2c_read(&tmd2725_ctx, TMD2725_REG_STATUS,
611 &(tmd2725_chip.shadow[TMD2725_REG_STATUS]),
612 I2C_DATA_LEN, I2C_OP_RETRIES);
613 if (unlikely(ret)) {
614 LOG("%s %s TMD2725_READ_STATUS failure \n", SENSOR_STR, __func__);
615 return ret;
616 }
617 status = tmd2725_chip.shadow[TMD2725_REG_STATUS];
618 if (status & TMD2725_ST_ALS_IRQ) {
619 // clear AINT
620 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_STATUS,
621 TMD2725_ST_ALS_IRQ, 0);
622 tmd2725_read_als_data();
623 tmd2725_get_lux();
624 }
625
626 sensordata->lux = (uint32_t)(tmd2725_chip.als_inf.lux);
627 sensordata->timestamp = aos_now_ms();
628 return (int)size;
629 }
630
drv_als_ams_tmd2725_write(const void * buf,size_t len)631 static int drv_als_ams_tmd2725_write(const void *buf, size_t len)
632 {
633
634 // no handle so far
635 return 0;
636 }
637
drv_als_ams_tmd2725_ioctl(int cmd,unsigned long arg)638 static int drv_als_ams_tmd2725_ioctl(int cmd, unsigned long arg)
639 {
640 int ret = 0;
641 switch (cmd) {
642 case SENSOR_IOCTL_SET_POWER: {
643 ret = drv_als_ams_tmd2725_set_power_mode(&tmd2725_ctx, arg);
644 if (unlikely(ret)) {
645 return -1;
646 }
647 } break;
648 case SENSOR_IOCTL_GET_INFO: {
649 /* fill the dev info here */
650 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
651 info->model = "TMD2725_ALS";
652 info->unit = lux;
653 } break;
654 default:
655 break;
656 }
657 return 0;
658 }
659
drv_als_ams_tmd2725_init(void)660 int drv_als_ams_tmd2725_init(void)
661 {
662 int ret = 0;
663 sensor_obj_t sensor_als;
664 memset(&sensor_als, 0, sizeof(sensor_als));
665 /* fill the sensor obj parameters here */
666 sensor_als.tag = TAG_DEV_ALS;
667 sensor_als.path = dev_als_path;
668 sensor_als.io_port = I2C_PORT;
669 sensor_als.open = drv_als_ams_tmd2725_open;
670 sensor_als.close = drv_als_ams_tmd2725_close;
671 sensor_als.read = drv_als_ams_tmd2725_read;
672 sensor_als.write = drv_als_ams_tmd2725_write;
673 sensor_als.ioctl = drv_als_ams_tmd2725_ioctl;
674 sensor_als.irq_handle = drv_als_ams_tmd2725_irq_handle;
675
676 ret = sensor_create_obj(&sensor_als);
677 if (unlikely(ret)) {
678 return -1;
679 }
680 ret =
681 drv_als_ps_ams_tmd2725_validate_id(&tmd2725_ctx, TMD2725_CHIPID_VALUE);
682 if (unlikely(ret)) {
683 return -1;
684 }
685
686 ret = drv_als_ps_ams_tmd2725_set_default_config(&tmd2725_ctx);
687 if (unlikely(ret)) {
688 return -1;
689 }
690 return 0;
691 }
692
ams_sensor_i2c_write(i2c_dev_t * drv,uint8_t * shadow,uint16_t reg,uint8_t data)693 static uint32_t ams_sensor_i2c_write(i2c_dev_t *drv, uint8_t *shadow,
694 uint16_t reg, uint8_t data)
695 {
696 sensor_i2c_write(drv, reg, &data, I2C_DATA_LEN, I2C_OP_RETRIES);
697 tmd2725_chip.shadow[reg] = data;
698 return 0;
699 }
700
tmd2725_offset_calibration()701 int tmd2725_offset_calibration()
702 {
703 uint8_t temp;
704 sensor_i2c_read(&tmd2725_ctx, TMD2725_REG_ENABLE, &temp, I2C_DATA_LEN,
705 I2C_OP_RETRIES);
706 // enable prox enb bit
707 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_ENABLE,
708 TMD2725_PEN | TMD2725_PON, TMD2725_PON);
709 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_INTENAB,
710 TMD2725_PIEN | TMD2725_CIEN, TMD2725_CIEN);
711 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_CALIBCFG,
712 TMD2725_MASK_BINSRCH_TARGET | TMD2725_MASK_PROX_DATA_AVG |
713 TMD2725_MASK_PROX_AUTO_OFFSET_ADJUST,
714 (0x03 << TMD2725_SHIFT_BINSRCH_TARGET) |
715 (1 << TMD2725_SHIFT_PROX_DATA_AVG) |
716 (1 << TMD2725_SHIFT_PROX_AUTO_OFFSET_ADJUST));
717
718 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_CALIB,
719 TMD2725_MASK_START_OFFSET_CALIB, 0x01);
720 // set calibration default time 100ms
721 aos_msleep(100);
722
723 sensor_i2c_read(&tmd2725_ctx, TMD2725_REG_POFFSET_L,
724 &tmd2725_chip.shadow[TMD2725_REG_POFFSET_L], 2,
725 I2C_OP_RETRIES);
726 tmd2725_chip.prox_offset = tmd2725_chip.shadow[TMD2725_REG_POFFSET_L];
727 if (tmd2725_chip.shadow[TMD2725_REG_POFFSET_H] & TMD2725_MASK_POFFSET_H) {
728 tmd2725_chip.prox_offset *= -1;
729 }
730 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_ENABLE,
731 TMD2725_PEN, temp);
732 return 0;
733 }
734
drv_ps_ams_tmd2725_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)735 static int drv_ps_ams_tmd2725_set_power_mode(i2c_dev_t * drv,
736 dev_power_mode_e mode)
737 {
738 switch (mode) {
739 case DEV_POWER_ON: {
740 if (!(tmd2725_chip.prox_enabled)) {
741 tmd2725_chip.prox_th_min = 50;
742 tmd2725_chip.prox_th_max = 80;
743 ams_sensor_i2c_write(&tmd2725_ctx, tmd2725_chip.shadow,
744 TMD2725_REG_PILT,
745 tmd2725_chip.prox_th_min);
746 ams_sensor_i2c_write(&tmd2725_ctx, tmd2725_chip.shadow,
747 TMD2725_REG_PIHT,
748 tmd2725_chip.prox_th_max);
749 tmd2725_offset_calibration();
750
751 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow,
752 TMD2725_REG_PERS, TMD2725_MASK_PROX_PERS,
753 tmd2725_chip.persist &
754 TMD2725_MASK_PROX_PERS);
755
756 ams_sensor_i2c_write(
757 &tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_PGCFG0,
758 tmd2725_chip.prox_pulse_cnt | tmd2725_chip.prox_pulse_len);
759
760 sensor_i2c_modify(
761 &tmd2725_ctx, tmd2725_chip.shadow, TMD2725_REG_PGCFG1,
762 (tmd2725_chip.prox_gain & TMD2725_MASK_PGAIN) |
763 (tmd2725_chip.prox_drive & TMD2725_MASK_PDRIVE),
764 TMD2725_MASK_PGAIN | TMD2725_MASK_PDRIVE);
765 ams_sensor_i2c_write(&tmd2725_ctx, tmd2725_chip.shadow,
766 TMD2725_REG_PTIME, P_TIME_US(2816));
767
768 // enable proximity and interrupt
769 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow,
770 TMD2725_REG_ENABLE, TMD2725_PEN | TMD2725_PON,
771 TMD2725_PEN | TMD2725_PON);
772 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow,
773 TMD2725_REG_INTENAB, TMD2725_PIEN,
774 TMD2725_PIEN);
775 tmd2725_chip.prox_enabled = true;
776 tmd2725_chip.prx_inf.detected = false;
777 }
778 } break;
779
780 case DEV_POWER_OFF:
781
782 case DEV_SLEEP: {
783 if (tmd2725_chip.prox_enabled) {
784 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow,
785 TMD2725_REG_ENABLE, TMD2725_PEN, 0);
786 sensor_i2c_modify(&tmd2725_ctx, tmd2725_chip.shadow,
787 TMD2725_REG_INTENAB, TMD2725_PIEN, 0);
788 tmd2725_chip.prox_enabled = false;
789 if (!(tmd2725_chip.shadow[TMD2725_REG_ENABLE] & TMD2725_EN_ALL))
790 sensor_i2c_modify(drv, tmd2725_chip.shadow,
791 TMD2725_REG_ENABLE, TMD2725_PON, 0);
792 }
793 } break;
794
795 default:
796 break;
797 }
798 return 0;
799 }
800
drv_ps_ams_tmd2725_irq_handle(void)801 static void drv_ps_ams_tmd2725_irq_handle(void)
802 {
803 /* no handle so far */
804 }
805
drv_ps_ams_tmd2725_open(void)806 static int drv_ps_ams_tmd2725_open(void)
807 {
808 int ret = 0;
809 ret = drv_ps_ams_tmd2725_set_power_mode(&tmd2725_ctx, DEV_POWER_ON);
810 if (unlikely(ret)) {
811 return -1;
812 }
813 return 0;
814 }
815
drv_ps_ams_tmd2725_close(void)816 static int drv_ps_ams_tmd2725_close(void)
817 {
818 int ret = 0;
819 ret = drv_ps_ams_tmd2725_set_power_mode(&tmd2725_ctx, DEV_POWER_OFF);
820 if (unlikely(ret)) {
821 return -1;
822 }
823 return 0;
824 }
825
tmd2725_read_prox_data()826 static void tmd2725_read_prox_data()
827 {
828 sensor_i2c_read(&tmd2725_ctx, TMD2725_REG_PDATA,
829 &tmd2725_chip.shadow[TMD2725_REG_PDATA], I2C_DATA_LEN,
830 I2C_OP_RETRIES);
831 tmd2725_chip.prx_inf.raw = tmd2725_chip.shadow[TMD2725_REG_PDATA];
832 // LOG("%s %s read_prox_data raw data is
833 // %d\n",SENSOR_STR,__func__,tmd2725_chip.prx_inf.raw);
834 }
835
tmd2725_get_prox()836 static void tmd2725_get_prox()
837 {
838 if (tmd2725_chip.prx_inf.detected == false) {
839 if (tmd2725_chip.prx_inf.raw > tmd2725_chip.prox_th_max) {
840 tmd2725_chip.prx_inf.detected = true;
841 }
842 } else {
843 if (tmd2725_chip.prx_inf.raw < tmd2725_chip.prox_th_min) {
844 tmd2725_chip.prx_inf.detected = false;
845 }
846 }
847 }
848
drv_ps_ams_tmd2725_read(void * buf,size_t len)849 static int drv_ps_ams_tmd2725_read(void *buf, size_t len)
850 {
851 size_t size;
852
853 proximity_data_t *sensordata = (proximity_data_t *)buf;
854
855 if (buf == NULL) {
856 return -1;
857 }
858 size = sizeof(proximity_data_t);
859 if (len < size) {
860 return -1;
861 }
862
863 tmd2725_read_prox_data();
864 tmd2725_get_prox();
865 //prx_inf.detected describe the near or far, and prx_inf.raw is pdata
866 //sensordata->present = tmd2725_chip.prx_inf.detected;
867 sensordata->present = tmd2725_chip.prx_inf.raw;
868 sensordata->timestamp = aos_now_ms();
869 return (int)size;
870 }
871
drv_ps_ams_tmd2725_write(const void * buf,size_t len)872 static int drv_ps_ams_tmd2725_write(const void *buf, size_t len)
873 {
874 // no handle so far
875 return 0;
876 }
877
drv_ps_ams_tmd2725_ioctl(int cmd,unsigned long arg)878 static int drv_ps_ams_tmd2725_ioctl(int cmd, unsigned long arg)
879 {
880 int ret = 0;
881 switch (cmd) {
882 case SENSOR_IOCTL_SET_POWER: {
883 ret = drv_ps_ams_tmd2725_set_power_mode(&tmd2725_ctx, arg);
884 if (unlikely(ret)) {
885 return -1;
886 }
887 } break;
888 case SENSOR_IOCTL_GET_INFO: {
889 /* fill the dev info here */
890 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
891 info->model = "TMD2725_PS";
892 info->unit = cm;
893 } break;
894 default:
895 break;
896 }
897 return 0;
898 }
899
drv_ps_ams_tmd2725_init(void)900 int drv_ps_ams_tmd2725_init(void)
901 {
902 int ret = 0;
903 sensor_obj_t sensor_ps;
904 memset(&sensor_ps, 0, sizeof(sensor_ps));
905 /* fill the sensor obj parameters here */
906 sensor_ps.tag = TAG_DEV_PS;
907 sensor_ps.path = dev_ps_path;
908 sensor_ps.io_port = I2C_PORT;
909 sensor_ps.open = drv_ps_ams_tmd2725_open;
910 sensor_ps.close = drv_ps_ams_tmd2725_close;
911 sensor_ps.read = drv_ps_ams_tmd2725_read;
912 sensor_ps.write = drv_ps_ams_tmd2725_write;
913 sensor_ps.ioctl = drv_ps_ams_tmd2725_ioctl;
914 sensor_ps.irq_handle = drv_ps_ams_tmd2725_irq_handle;
915
916 ret = sensor_create_obj(&sensor_ps);
917 if (unlikely(ret)) {
918 return -1;
919 }
920 ret =
921 drv_als_ps_ams_tmd2725_validate_id(&tmd2725_ctx, TMD2725_CHIPID_VALUE);
922 if (unlikely(ret)) {
923 return -1;
924 }
925 ret = drv_als_ps_ams_tmd2725_set_default_config(&tmd2725_ctx);
926 if (unlikely(ret)) {
927 return -1;
928 }
929 return 0;
930 }
931
932
933 SENSOR_DRV_ADD(drv_als_ams_tmd2725_init);
934 SENSOR_DRV_ADD(drv_ps_ams_tmd2725_init);
935
936