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