1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "aos/kernel.h"
5 #include "sensor_drv_api.h"
6 #include "sensor_hal.h"
7 
8 #define LTR659_I2C_SLAVE_ADDR                           0x23
9 
10 #define LTR659_SW_RESET                                 0x80
11 #define LTR659_PS_CONTR                                 0x81 /* PS operation mode */
12 #define LTR659_PS_LED                                   0x82 /* LED pulse freq, current duty, peak current */
13 #define LTR659_PS_N_PULSES                              0x83 /* PS number of pulses */
14 #define LTR659_PS_MEAS_RATE                             0x84 /* measurement rate*/
15 #define LTR659_PART_ID                                  0x86
16 #define LTR659_MANUFAC_ID                               0x87
17 #define LTR659_PS_STATUS                                0x8C
18 #define LTR659_PS_DATA_0                                0x8D
19 #define LTR659_PS_DATA_1                                0x8E
20 #define LTR659_INTERRUPT                                0x8F
21 #define LTR659_PS_THRES_UP_0                            0x90 /* PS interrupt upper threshold, lower byte */
22 #define LTR659_PS_THRES_UP_1                            0x91 /* PS interrupt upper threshold, upper byte */
23 #define LTR659_PS_THRES_LOW_0                           0x92 /* PS interrupt lower threshold, lower byte */
24 #define LTR659_PS_THRES_LOW_1                           0x93 /* PS interrupt lower threshold, upper byte */
25 #define LTR659_PS_OFFSET_1                              0x94 /* PS offset, upper byte */
26 #define LTR659_PS_OFFSET_0                              0x95 /* PS offset, lower byte */
27 #define LTR659_INTR_PRST                                0x9E /* PS interrupt persist setting */
28 
29 #define LTR659_ADDR_TRANS(n)                            ((n) << 1)
30 #define LTR659_I2C_ADDR                                 LTR659_ADDR_TRANS(LTR659_I2C_SLAVE_ADDR)
31 #define LTR659_PART_ID_VAL                              0x92
32 #define LTR659_MANUFAC_ID_VAL                           0x05
33 
34 #define LTR659_SW_RESET_REG_SW_RESET__POS               (1)
35 #define LTR659_SW_RESET_REG_SW_RESET__MSK               (0x02)
36 #define LTR659_SW_RESET_REG_SW_RESET__REG               (LTR659_SW_RESET)
37 
38 #define LTR659_PS_CONTR_REG_PS_MODE__POS                (0)
39 #define LTR659_PS_CONTR_REG_PS_MODE__MSK                (0x03)
40 #define LTR659_PS_CONTR_REG_PS_MODE__REG                (LTR659_PS_CONTR)
41 
42 #define LTR659_PS_CONTR_REG_PS_GAIN__POS                (2)
43 #define LTR659_PS_CONTR_REG_PS_GAIN__MSK                (0x0C)
44 #define LTR659_PS_CONTR_REG_PS_GAIN__REG                (LTR659_PS_CONTR)
45 
46 #define LTR659_PS_CONTR_REG_PS_SAT_IND_EN__POS          (5)
47 #define LTR659_PS_CONTR_REG_PS_SAT_IND_EN__MSK          (0x20)
48 #define LTR659_PS_CONTR_REG_PS_SAT_IND_EN__REG          (LTR659_PS_CONTR)
49 
50 #define LTR659_PS_LED_REG_LED_CURR__POS                 (0)
51 #define LTR659_PS_LED_REG_LED_CURR__MSK                 (0x07)
52 #define LTR659_PS_LED_REG_LED_CURR__REG                 (LTR659_PS_LED)
53 
54 #define LTR659_PS_LED_REG_LED_DUTY__POS                 (3)
55 #define LTR659_PS_LED_REG_LED_DUTY__MSK                 (0x18)
56 #define LTR659_PS_LED_REG_LED_DUTY__REG                 (LTR659_PS_LED)
57 
58 #define LTR659_PS_LED_REG_LED_PULSE__POS                (5)
59 #define LTR659_PS_LED_REG_LED_PULSE__MSK                (0xE0)
60 #define LTR659_PS_LED_REG_LED_PULSE__REG                (LTR659_PS_LED)
61 
62 #define LTR659_PS_N_PULSES_REG_PULSES__POS              (0)
63 #define LTR659_PS_N_PULSES_REG_PULSES__MSK              (0x0F)
64 #define LTR659_PS_N_PULSES_REG_PULSES__REG              (LTR659_PS_N_PULSES)
65 
66 #define LTR659_PS_MEAS_RATE_REG_MEAS_RPT_RATE__POS      (0)
67 #define LTR659_PS_MEAS_RATE_REG_MEAS_RPT_RATE__MSK      (0x0F)
68 #define LTR659_PS_MEAS_RATE_REG_MEAS_RPT_RATE__REG      (LTR659_PS_MEAS_RATE)
69 
70 #define LTR659_PS_STATUS_REG_PS_DATA_STATUS__POS        (0)
71 #define LTR659_PS_STATUS_REG_PS_DATA_STATUS__MSK        (0x01)
72 #define LTR659_PS_STATUS_REG_PS_DATA_STATUS__REG        (LTR659_PS_STATUS)
73 
74 #define LTR659_PS_STATUS_REG_PS_INT_STATUS__POS         (1)
75 #define LTR659_PS_STATUS_REG_PS_INT_STATUS__MSK         (0x02)
76 #define LTR659_PS_STATUS_REG_PS_INT_STATUS__REG         (LTR659_PS_STATUS)
77 
78 #define LTR659_INTERRUPT_REG_INT_MODE__POS              (0)
79 #define LTR659_INTERRUPT_REG_INT_MODE__MSK              (0x01)
80 #define LTR659_INTERRUPT_REG_INT_MODE__REG              (LTR659_INTERRUPT)
81 
82 #define LTR659_INTERRUPT_REG_INT_POLARITY__POS          (2)
83 #define LTR659_INTERRUPT_REG_INT_POLARITY__MSK          (0x04)
84 #define LTR659_INTERRUPT_REG_INT_POLARITY__REG          (LTR659_INTERRUPT)
85 
86 #define LTR659_INTR_PRST_REG_PS_PERSIST__POS            (4)
87 #define LTR659_INTR_PRST_REG_PS_PERSIST__MSK            (0xF0)
88 #define LTR659_INTR_PRST_REG_PS_PERSIST__REG            (LTR659_INTR_PRST)
89 
90 #define LTR659_GET_BITSLICE(regvar, bitname)            ((regvar & LTR659_##bitname##__MSK) >> LTR659_##bitname##__POS)
91 #define LTR659_SET_BITSLICE(regvar, bitname, val)       ((regvar & ~LTR659_##bitname##__MSK) | ((val<<LTR659_##bitname##__POS)&LTR659_##bitname##__MSK))
92 
93 #define LTR659_WAIT_TIME_PER_CHECK                      (10)
94 #define LTR659_WAIT_TIME_TOTAL                          (100)
95 
96 typedef enum {
97     LTR659_SW_RESET_FALSE = 0x00,
98     LTR659_SW_RESET_TRUE = 0x01,
99 } LTR659_CFG_SW_RESET;
100 
101 typedef enum {
102     LTR659_PS_STANDBY = 0x00,
103     LTR659_PS_ACTIVE = 0x02,
104 } LTR659_CFG_PS_MODE;
105 
106 typedef enum {
107     LTR659_PS_GAIN_16X = 0x00,
108     LTR659_PS_GAIN_32X = 0x02,
109     LTR659_PS_GAIN_64X = 0x03,
110 } LTR659_CFG_PS_GAIN;
111 
112 typedef enum {
113     LTR659_PS_SAT_IND_FALSE = 0x00,
114     LTR659_PS_SAT_IND_TRUE = 0x01,
115 } LTR659_CFG_PS_SAT_IND_EN;
116 
117 typedef enum {
118     LTR659_LED_PEAK_CURRENT_5 = 0x00,                   /* LED pulse current level = 5mA */
119     LTR659_LED_PEAK_CURRENT_10 = 0x01,                  /* LED pulse current level = 10mA */
120     LTR659_LED_PEAK_CURRENT_20 = 0x02,                  /* LED pulse current level = 20mA */
121     LTR659_LED_PEAK_CURRENT_50 = 0x03,                  /* LED pulse current level = 50mA */
122     LTR659_LED_PEAK_CURRENT_100 = 0x04,                 /* LED pulse current level = 100mA (default) */
123 } LTR659_CFG_LED_PEAK_CURRENT;
124 
125 typedef enum {
126     LTR659_LED_DUTY_CYCLE_25PCT = 0x00,                 /* Duty = 25% */
127     LTR659_LED_DUTY_CYCLE_50PCT = 0x01,                 /* Duty = 50% */
128     LTR659_LED_DUTY_CYCLE_75PCT = 0x02,                 /* Duty = 75% */
129     LTR659_LED_DUTY_CYCLE_100PCT = 0x03,                /* Duty = 100% (default) */
130 } LTR659_CFG_LED_DUTY_CYCLE;
131 
132 typedef enum {
133     LTR659_LED_PULSE_30kHZ = 0x00,                      /* LED pulse period = 30kHz */
134     LTR659_LED_PULSE_40kHZ = 0x01,                      /* LED pulse period = 40kHz */
135     LTR659_LED_PULSE_50kHZ = 0x02,                      /* LED pulse period = 50kHz */
136     LTR659_LED_PULSE_60kHZ = 0x03,                      /* LED pulse period = 60kHz */
137     LTR659_LED_PULSE_70kHZ = 0x04,                      /* LED pulse period = 70kHz */
138     LTR659_LED_PULSE_80kHZ = 0x05,                      /* LED pulse period = 80kHz */
139     LTR659_LED_PULSE_90kHZ = 0x06,                      /* LED pulse period = 90kHz */
140     LTR659_LED_PULSE_100kHZ = 0x07,                     /* LED pulse period = 100kHz */
141 } LTR659_CFG_LED_PULSE_FREQUENCY;
142 
143 typedef enum {
144     LTR659_PS_MEAS_RATE_50 = 0x00,                      /* PS Measurement Repeat Rate = 50ms */
145     LTR659_PS_MEAS_RATE_70 = 0x01,                      /* PS Measurement Repeat Rate = 70ms */
146     LTR659_PS_MEAS_RATE_100 = 0x02,                     /* PS Measurement Repeat Rate = 100ms (default) */
147     LTR659_PS_MEAS_RATE_200 = 0x03,                     /* PS Measurement Repeat Rate = 20ms */
148     LTR659_PS_MEAS_RATE_500 = 0x04,                     /* PS Measurement Repeat Rate = 500ms */
149     LTR659_PS_MEAS_RATE_1000 = 0x05,                    /* PS Measurement Repeat Rate = 1000ms */
150     LTR659_PS_MEAS_RATE_2000 = 0x06,                    /* PS Measurement Repeat Rate = 2000ms */
151     LTR659_PS_MEAS_RATE_10 = 0x08,                      /* PS Measurement Repeat Rate = 10ms */
152 } LTR659_CFG_PS_MEAS_RPT_RATE;
153 
154 typedef enum {
155     LTR659_PS_DATA_STATUS_OLD = 0x00,
156     LTR659_PS_DATA_STATUS_NEW = 0x01,
157 } LTR659_CFG_PS_DATA_STATUS;
158 
159 typedef enum {
160     LTR659_PS_INT_STATUS_INACTIVE = 0x00,
161     LTR659_PS_INT_STATUS_ACTIVE = 0x01,
162 } LTR659_CFG_PS_INT_STATUS;
163 
164 typedef enum {
165     LTR659_PS_INT_MODE_DISABLE = 0x00,
166     LTR659_PS_INT_MODE_ENABLE = 0x01,
167 } LTR659_CFG_PS_INT_MODE;
168 
169 typedef enum {
170     LTR659_PS_INT_POLARITY_ACTIVE_LO = 0x00,
171     LTR659_PS_INT_POLARITY_ACTIVE_HI = 0x01,
172 } LTR659_CFG_PS_INT_POLARITY;
173 
174 i2c_dev_t ltr659_ctx = {
175     .port = 3,
176     .config.address_width = 8,
177     .config.freq = 100000,
178     .config.dev_addr = LTR659_I2C_ADDR,
179 };
180 
181 static uint8_t g_init_bitwise = 0;
182 
drv_ps_liteon_ltr659_validate_id(i2c_dev_t * drv,uint8_t part_id,uint8_t manufac_id)183 static int drv_ps_liteon_ltr659_validate_id(i2c_dev_t* drv, uint8_t part_id, uint8_t manufac_id)
184 {
185     int     ret = 0;
186     uint8_t part_id_value = 0;
187     uint8_t manufac_id_value = 0;
188 
189     if (drv == NULL) {
190         return -1;
191     }
192 
193     ret = sensor_i2c_read(drv, LTR659_PART_ID, &part_id_value, I2C_DATA_LEN, I2C_OP_RETRIES);
194     if (unlikely(ret)) {
195         return ret;
196     }
197 
198     ret = sensor_i2c_read(drv, LTR659_MANUFAC_ID, &manufac_id_value, I2C_DATA_LEN, I2C_OP_RETRIES);
199     if (unlikely(ret)) {
200         return ret;
201     }
202 
203     if (part_id_value != part_id || manufac_id_value != manufac_id) {
204         return -1;
205     }
206 
207     return 0;
208 }
209 
drv_ps_liteon_ltr659_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)210 static int drv_ps_liteon_ltr659_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
211 {
212     int     ret = 0;
213     uint8_t dev_mode = 0;
214     uint8_t value = 0;
215 
216     ret = sensor_i2c_read(drv, LTR659_PS_CONTR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
217     if (unlikely(ret)) {
218         return ret;
219     }
220 
221     switch (mode) {
222         case DEV_POWER_OFF:
223         case DEV_SLEEP:
224             dev_mode = LTR659_SET_BITSLICE(value, PS_CONTR_REG_PS_MODE, LTR659_PS_STANDBY);
225             break;
226         case DEV_POWER_ON:
227             dev_mode = LTR659_SET_BITSLICE(value, PS_CONTR_REG_PS_MODE, LTR659_PS_ACTIVE);
228             break;
229         default:
230             return -1;
231     }
232 
233     ret = sensor_i2c_write(drv, LTR659_PS_CONTR, &dev_mode, I2C_DATA_LEN, I2C_OP_RETRIES);
234     if (unlikely(ret)) {
235         return ret;
236     }
237 
238     return 0;
239 }
240 
drv_ps_liteon_ltr659_is_ready(i2c_dev_t * drv)241 UNUSED static int drv_ps_liteon_ltr659_is_ready(i2c_dev_t* drv)
242 {
243     int     ret = 0;
244     uint8_t value = 0;
245 
246     ret = sensor_i2c_read(drv, LTR659_PS_STATUS, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
247     if (unlikely(ret)) {
248         return 0;
249     }
250 
251     ret = (LTR659_GET_BITSLICE(value, PS_STATUS_REG_PS_DATA_STATUS) == LTR659_PS_DATA_STATUS_NEW) ? 1 : 0;
252 
253     return ret;
254 }
255 
drv_ps_liteon_ltr659_set_default_config(i2c_dev_t * drv)256 static int drv_ps_liteon_ltr659_set_default_config(i2c_dev_t* drv)
257 {
258     int     ret = 0;
259     uint8_t value = 0;
260 
261     ret = sensor_i2c_read(drv, LTR659_PS_CONTR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
262     if (unlikely(ret)) {
263         return ret;
264     }
265     value = LTR659_SET_BITSLICE(value, PS_CONTR_REG_PS_GAIN, LTR659_PS_GAIN_16X);
266     value = LTR659_SET_BITSLICE(value, PS_CONTR_REG_PS_SAT_IND_EN, LTR659_PS_SAT_IND_FALSE);
267     ret = sensor_i2c_write(drv, LTR659_PS_CONTR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
268     if (unlikely(ret)) {
269         return ret;
270     }
271 
272     value = 0;
273     value = LTR659_SET_BITSLICE(value, PS_LED_REG_LED_CURR, LTR659_LED_PEAK_CURRENT_100);
274     value = LTR659_SET_BITSLICE(value, PS_LED_REG_LED_DUTY, LTR659_LED_DUTY_CYCLE_100PCT);
275     value = LTR659_SET_BITSLICE(value, PS_LED_REG_LED_PULSE, LTR659_LED_PULSE_60kHZ);
276     ret = sensor_i2c_write(drv, LTR659_PS_LED, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
277     if (unlikely(ret)) {
278         return ret;
279     }
280 
281     value = 0;
282     value = LTR659_SET_BITSLICE(value, PS_N_PULSES_REG_PULSES, 4);
283     ret = sensor_i2c_write(drv, LTR659_PS_N_PULSES, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
284     if (unlikely(ret)) {
285         return ret;
286     }
287 
288     value = 0;
289     value = LTR659_SET_BITSLICE(value, PS_MEAS_RATE_REG_MEAS_RPT_RATE, LTR659_PS_MEAS_RATE_100);
290     ret = sensor_i2c_write(drv, LTR659_PS_MEAS_RATE, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
291     if (unlikely(ret)) {
292         return ret;
293     }
294 
295     return 0;
296 }
297 
drv_ps_liteon_ltr659_irq_handle(void)298 static void drv_ps_liteon_ltr659_irq_handle(void)
299 {
300     /* no handle so far */
301 }
302 
drv_ps_liteon_ltr659_open(void)303 static int drv_ps_liteon_ltr659_open(void)
304 {
305     int ret = 0;
306 
307     ret = drv_ps_liteon_ltr659_set_power_mode(&ltr659_ctx, DEV_POWER_ON);
308     if (unlikely(ret)) {
309         return -1;
310     }
311 
312     LOG("%s %s successfully \n", SENSOR_STR, __func__);
313     return 0;
314 
315 }
316 
drv_ps_liteon_ltr659_close(void)317 static int drv_ps_liteon_ltr659_close(void)
318 {
319     int ret = 0;
320 
321     ret = drv_ps_liteon_ltr659_set_power_mode(&ltr659_ctx, DEV_POWER_OFF);
322     if (unlikely(ret)) {
323         return -1;
324     }
325 
326     LOG("%s %s successfully \n", SENSOR_STR, __func__);
327     return 0;
328 }
329 
drv_ps_liteon_ltr659_read(void * buf,size_t len)330 static int drv_ps_liteon_ltr659_read(void *buf, size_t len)
331 {
332     int ret = 0;
333     size_t size;
334     uint8_t reg_data[2] = { 0 };
335     proximity_data_t * pdata = (proximity_data_t *) buf;
336 
337     if (buf == NULL) {
338         return -1;
339     }
340 
341     size = sizeof(proximity_data_t);
342     if (len < size) {
343         return -1;
344     }
345 
346     ret = sensor_i2c_read(&ltr659_ctx, LTR659_PS_DATA_0, &reg_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
347     if (unlikely(ret)) {
348         return -1;
349     }
350     ret = sensor_i2c_read(&ltr659_ctx, LTR659_PS_DATA_1, &reg_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
351     if (unlikely(ret)) {
352         return -1;
353     }
354 
355     pdata->present = (((uint32_t) (reg_data[1] & 0x07) << 8) | reg_data[0]);
356     pdata->timestamp = aos_now_ms();
357 
358     return (int) size;
359 }
360 
drv_ps_liteon_ltr659_write(const void * buf,size_t len)361 static int drv_ps_liteon_ltr659_write(const void *buf, size_t len)
362 {
363     (void) buf;
364     (void) len;
365 
366     return 0;
367 }
368 
drv_ps_liteon_ltr659_ioctl(int cmd,unsigned long arg)369 static int drv_ps_liteon_ltr659_ioctl(int cmd, unsigned long arg)
370 {
371     int ret = 0;
372 
373     switch (cmd) {
374         case SENSOR_IOCTL_SET_POWER: {
375             ret = drv_ps_liteon_ltr659_set_power_mode(&ltr659_ctx, arg);
376             if (unlikely(ret)) {
377                 return -1;
378             }
379         } break;
380         case SENSOR_IOCTL_GET_INFO: {
381             /* fill the dev info here */
382             dev_sensor_info_t *info = (dev_sensor_info_t *) arg;
383             info->vendor = DEV_SENSOR_VENDOR_LITEON;
384             info->model = "LTR659";
385             info->unit = cm;
386         } break;
387         default:
388             return -1;
389     }
390 
391     LOG("%s %s successfully \n", SENSOR_STR, __func__);
392     return 0;
393 }
394 
drv_ps_liteon_ltr659_init(void)395 int drv_ps_liteon_ltr659_init(void)
396 {
397     int ret = 0;
398     sensor_obj_t sensor_ps;
399     memset(&sensor_ps, 0, sizeof(sensor_ps));
400 
401     if (!g_init_bitwise) {
402         ret = drv_ps_liteon_ltr659_validate_id(&ltr659_ctx, LTR659_PART_ID_VAL, LTR659_MANUFAC_ID_VAL);
403         if (unlikely(ret)) {
404             return -1;
405         }
406     }
407 
408     if (!g_init_bitwise) {
409         /* fill the sensor_ps obj parameters here */
410         sensor_ps.tag = TAG_DEV_PS;
411         sensor_ps.path = dev_ps_path;
412         sensor_ps.io_port = I2C_PORT;
413         sensor_ps.mode = DEV_POLLING;
414         sensor_ps.power = DEV_POWER_OFF;
415         sensor_ps.open = drv_ps_liteon_ltr659_open;
416         sensor_ps.close = drv_ps_liteon_ltr659_close;
417         sensor_ps.read = drv_ps_liteon_ltr659_read;
418         sensor_ps.write = drv_ps_liteon_ltr659_write;
419         sensor_ps.ioctl = drv_ps_liteon_ltr659_ioctl;
420         sensor_ps.irq_handle = drv_ps_liteon_ltr659_irq_handle;
421 
422         ret = sensor_create_obj(&sensor_ps);
423         if (unlikely(ret)) {
424             return -1;
425         }
426 
427         ret = drv_ps_liteon_ltr659_set_default_config(&ltr659_ctx);
428         if (unlikely(ret)) {
429             return -1;
430         }
431 
432         g_init_bitwise = 1;
433     }
434 
435     LOG("%s %s successfully \n", SENSOR_STR, __func__);
436     return 0;
437 }
438 
439 SENSOR_DRV_ADD(drv_ps_liteon_ltr659_init);
440 
441