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 
9 /*******************************************************************************
10  *********************************   MACROS   **********************************
11  ******************************************************************************/
12 #define LTR381_ADDR_TRANS(n)                                ((n) << 1)
13 #define LTR381_GET_BITSLICE(uint8Val, bitName)              (((uint8Val) & (LTR381_##bitName##__MSK)) >> (LTR381_##bitName##__POS))
14 #define LTR381_SET_BITSLICE(uint8Val, bitName, bitVal)      (((uint8Val) & ~(LTR381_##bitName##__MSK)) | ((bitVal << (LTR381_##bitName##__POS)) & (LTR381_##bitName##__MSK)))
15 
16 /*******************************************************************************
17  **************************   SENSOR SPECIFICATIONS   **************************
18  ******************************************************************************/
19 /* I2C device address */
20 #define LTR381_SLAVE_ADDR                       (0x53)
21 #define LTR381_I2C_ADDR                         LTR381_ADDR_TRANS(LTR381_SLAVE_ADDR)
22 
23 /* Device info */
24 #define LTR381_PART_ID_VAL                      0xC2
25 #define LTR381_MANUFAC_ID_VAL                   0x05
26 
27 #define LTR381_WAIT_TIME_PER_CHECK              (10)
28 #define LTR381_WAIT_TIME_TOTAL                  (100)
29 
30 /*******************************************************************************
31  *************   Non-Configurable (Unless data sheet is updated)   *************
32  ******************************************************************************/
33 /* Device register set address */
34 #define LTR381_MAIN_CTRL_REG                    (0x00)
35 #define LTR381_ALS_CS_MEAS_RATE_REG             (0x04)
36 #define LTR381_ALS_CS_GAIN_REG                  (0x05)
37 #define LTR381_PART_ID_REG                      (0x06)
38 #define LTR381_MAIN_STATUS_REG                  (0x07)
39 #define LTR381_CS_DATA_IR_0_REG                 (0x0A)
40 #define LTR381_CS_DATA_IR_1_REG                 (0x0B)
41 #define LTR381_CS_DATA_IR_2_REG                 (0x0C)
42 #define LTR381_CS_DATA_GREEN_0_REG              (0x0D)
43 #define LTR381_CS_DATA_GREEN_1_REG              (0x0E)
44 #define LTR381_CS_DATA_GREEN_2_REG              (0x0F)
45 #define LTR381_CS_DATA_RED_0_REG                (0x10)
46 #define LTR381_CS_DATA_RED_1_REG                (0x11)
47 #define LTR381_CS_DATA_RED_2_REG                (0x12)
48 #define LTR381_CS_DATA_BLUE_0_REG               (0x13)
49 #define LTR381_CS_DATA_BLUE_1_REG               (0x14)
50 #define LTR381_CS_DATA_BLUE_2_REG               (0x15)
51 #define LTR381_INT_CFG_REG                      (0x19)
52 #define LTR381_INT_PST_REG                      (0x1A)
53 #define LTR381_ALS_THRES_UP_0_REG               (0x21)
54 #define LTR381_ALS_THRES_UP_1_REG               (0x22)
55 #define LTR381_ALS_THRES_UP_2_REG               (0x23)
56 #define LTR381_ALS_THRES_LOW_0_REG              (0x24)
57 #define LTR381_ALS_THRES_LOW_1_REG              (0x25)
58 #define LTR381_ALS_THRES_LOW_2_REG              (0x26)
59 
60 /* Register MAIN_CTRL field */
61 #define LTR381_ALS_CS_ENABLE__REG               (LTR381_MAIN_CTRL_REG)
62 #define LTR381_ALS_CS_ENABLE__POS               (1)
63 #define LTR381_ALS_CS_ENABLE__MSK               (0x02)
64 #define LTR381_CS_MODE__REG                     (LTR381_MAIN_CTRL_REG)
65 #define LTR381_CS_MODE__POS                     (2)
66 #define LTR381_CS_MODE__MSK                     (4)
67 #define LTR381_SW_RESET__REG                    (LTR381_MAIN_CTRL_REG)
68 #define LTR381_SW_RESET__POS                    (4)
69 #define LTR381_SW_RESET__MSK                    (0x10)
70 
71 /* Register ALS_CS_MEAS_RATE field */
72 #define LTR381_ALS_CS_MEAS_RATE__REG            (LTR381_ALS_CS_MEAS_RATE_REG)
73 #define LTR381_ALS_CS_MEAS_RATE__POS            (0)
74 #define LTR381_ALS_CS_MEAS_RATE__MSK            (0x07)
75 #define LTR381_ALS_CS_RESOLUTION__REG           (LTR381_ALS_CS_MEAS_RATE_REG)
76 #define LTR381_ALS_CS_RESOLUTION__POS           (4)
77 #define LTR381_ALS_CS_RESOLUTION__MSK           (0x70)
78 
79 /* Register ALS_CS_GAIN field */
80 #define LTR381_ALS_CS_GAIN_RANGE__REG           (LTR381_ALS_CS_GAIN_REG)
81 #define LTR381_ALS_CS_GAIN_RANGE__POS           (0)
82 #define LTR381_ALS_CS_GAIN_RANGE__MSK           (0x07)
83 
84 /* Register PART_ID field */
85 #define LTR381_PART_NUMBER_ID__REG              (LTR381_PART_ID_REG)
86 #define LTR381_PART_NUMBER_ID__POS              (4)
87 #define LTR381_PART_NUMBER_ID__MSK              (0xF0)
88 
89 /* Register MAIN_STATUS field */
90 #define LTR381_ALS_CS_DATA_STATUS__REG          (LTR381_MAIN_STATUS_REG)
91 #define LTR381_ALS_CS_DATA_STATUS__POS          (3)
92 #define LTR381_ALS_CS_DATA_STATUS__MSK          (0x08)
93 #define LTR381_ALS_CS_INT_STATUS__REG           (LTR381_MAIN_STATUS_REG)
94 #define LTR381_ALS_CS_INT_STATUS__POS           (4)
95 #define LTR381_ALS_CS_INT_STATUS__MSK           (0x10)
96 #define LTR381_POWER_ON_STATUS__REG             (LTR381_MAIN_STATUS_REG)
97 #define LTR381_POWER_ON_STATUS__POS             (5)
98 #define LTR381_POWER_ON_STATUS__MSK             (0x20)
99 
100 /* Register INT_CFG field */
101 #define LTR381_ALS_INT_PIN_EN__REG              (LTR381_INT_CFG_REG)
102 #define LTR381_ALS_INT_PIN_EN__POS              (2)
103 #define LTR381_ALS_INT_PIN_EN__MSK              (0x04)
104 #define LTR381_ALS_INT_SEL__REG                 (LTR381_INT_CFG_REG)
105 #define LTR381_ALS_INT_SEL__POS                 (4)
106 #define LTR381_ALS_INT_SEL__MSK                 (0x30)
107 
108 /* Register INT_PST field */
109 #define LTR381_ALS_CS_PERSIST__REG              (LTR381_INT_PST_REG)
110 #define LTR381_ALS_CS_PERSIST__POS              (4)
111 #define LTR381_ALS_CS_PERSIST__MSK              (0xF0)
112 
113 /* Field value enumeration */
114 typedef enum {
115     LTR381_ALS_STANDBY_MODE = 0x00,
116     LTR381_ALS_ACTIVE_MODE = 0x01,
117 } LTR381_ALS_CS_ENABLE_VAL;
118 
119 typedef enum {
120     LTR381_ALS_MODE = 0x00,
121     LTR381_CS_MODE = 0x01,
122 } LTR381_ALS_CS_MODE_VAL;
123 
124 typedef enum {
125     LTR381_ALS_NO_RESET = 0x00,
126     LTR381_ALS_RESET = 0x01,
127 } LTR381_SW_RESET_VAL;
128 
129 typedef enum {
130     LTR381_ALS_CS_MEAS_RATE_25MS = 0x00,
131     LTR381_ALS_CS_MEAS_RATE_50MS = 0x01,
132     LTR381_ALS_CS_MEAS_RATE_100MS = 0x02,
133     LTR381_ALS_CS_MEAS_RATE_200MS = 0x03,
134     LTR381_ALS_CS_MEAS_RATE_500MS = 0x04,
135     LTR381_ALS_CS_MEAS_RATE_1000MS = 0x05,
136     LTR381_ALS_CS_MEAS_RATE_2000MS = 0x06,
137 } LTR381_ALS_CS_MEAS_RATE_VAL;
138 
139 typedef enum {
140     LTR381_ALS_CS_RESOLUTION_20BIT = 0x00,
141     LTR381_ALS_CS_RESOLUTION_19BIT = 0x01,
142     LTR381_ALS_CS_RESOLUTION_18BIT = 0x02,
143     LTR381_ALS_CS_RESOLUTION_17BIT = 0x03,
144     LTR381_ALS_CS_RESOLUTION_16BIT = 0x04,
145 } LTR381_ALS_CS_RESOLUTION_VAL;
146 
147 typedef enum {
148     LTR381_ALS_CS_GAIN_RANGE_1 = 0x00,
149     LTR381_ALS_CS_GAIN_RANGE_3 = 0x01,
150     LTR381_ALS_CS_GAIN_RANGE_6 = 0x02,
151     LTR381_ALS_CS_GAIN_RANGE_9 = 0x03,
152     LTR381_ALS_CS_GAIN_RANGE_18 = 0x04,
153 } LTR381_ALS_CS_GAIN_RANGE_VAL;
154 
155 typedef enum {
156     LTR381_CS_ALS_DATA_OLD = 0x00,
157     LTR381_CS_ALS_DATA_NEW = 0x01,
158 } LTR381_CS_ALS_DATA_STATUS_VAL;
159 
160 typedef enum {
161     LTR381_CS_ALS_INT_FALSE = 0x00,
162     LTR381_CS_ALS_INT_TRUE = 0x01,
163 } LTR381_CS_ALS_INT_STATUS_VAL;
164 
165 typedef enum {
166     LTR381_POWER_ON_NORMAL = 0x00,
167     LTR381_POWER_ON_GOING = 0x01,
168 } LTR381_POWER_ON_STATUS_VAL;
169 
170 typedef enum {
171     LTR381_ALS_INT_INACTIVE = 0x00,
172     LTR381_ALS_INT_ACTIVE = 0x01,
173 } LTR381_ALS_INT_PIN_EN_VAL;
174 
175 typedef enum {
176     LTR381_ALS_INT_IR_CHANNEL = 0x00,
177     LTR381_ALS_INT_GREEN_CHANNEL = 0x01,
178     LTR381_ALS_INT_BLUE_CHANNEL = 0x02,
179     LTR381_ALS_INT_RED_CHANNEL = 0x03,
180 } LTR381_ALS_INT_SELECT_VAL;
181 
182 
183 i2c_dev_t ltr381_ctx = {
184     .port = 3,
185     .config.address_width = 8,
186     .config.freq = 100000,
187     .config.dev_addr = LTR381_I2C_ADDR,
188 };
189 
190 static uint8_t g_init_bitwise = 0;
191 
192 
drv_rgb_liteon_ltr381_validate_id(i2c_dev_t * drv,uint8_t part_id)193 static int drv_rgb_liteon_ltr381_validate_id(i2c_dev_t* drv, uint8_t part_id)
194 {
195     int     ret = 0;
196     uint8_t part_id_value = 0;
197 
198     if (drv == NULL) {
199         return -1;
200     }
201 
202     ret = sensor_i2c_read(drv, LTR381_PART_ID_REG, &part_id_value, I2C_DATA_LEN, I2C_OP_RETRIES);
203     if (unlikely(ret)) {
204         return ret;
205     }
206 
207     if (part_id_value != part_id) {
208         return -1;
209     }
210 
211     return 0;
212 }
213 
drv_rgb_liteon_ltr381_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)214 static int drv_rgb_liteon_ltr381_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
215 {
216     int     ret = 0;
217     uint8_t dev_mode = 0;
218     uint8_t value = 0;
219 
220     ret = sensor_i2c_read(drv, LTR381_MAIN_CTRL_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
221     if (unlikely(ret)) {
222         return ret;
223     }
224 
225     switch (mode) {
226         case DEV_POWER_OFF:
227         case DEV_SLEEP:
228             dev_mode = LTR381_SET_BITSLICE(value, ALS_CS_ENABLE, LTR381_ALS_STANDBY_MODE);
229             break;
230         case DEV_POWER_ON:
231             dev_mode = LTR381_SET_BITSLICE(value, ALS_CS_ENABLE, LTR381_ALS_ACTIVE_MODE);
232             break;
233         default:
234             return -1;
235     }
236 
237     ret = sensor_i2c_write(drv, LTR381_MAIN_CTRL_REG, &dev_mode, I2C_DATA_LEN, I2C_OP_RETRIES);
238     if (unlikely(ret)) {
239         return ret;
240     }
241 
242     return 0;
243 }
244 
drv_rgb_liteon_ltr381_is_ready(i2c_dev_t * drv)245 UNUSED static int drv_rgb_liteon_ltr381_is_ready(i2c_dev_t* drv)
246 {
247     int     ret = 0;
248     uint8_t value = 0;
249 
250     ret = sensor_i2c_read(drv, LTR381_MAIN_STATUS_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
251     if (unlikely(ret)) {
252         return 0;
253     }
254 
255     ret = (LTR381_GET_BITSLICE(value, ALS_CS_DATA_STATUS) == LTR381_CS_ALS_DATA_NEW) ? 1 : 0;
256 
257     return ret;
258 }
259 
drv_rgb_liteon_ltr381_set_default_config(i2c_dev_t * drv)260 static int drv_rgb_liteon_ltr381_set_default_config(i2c_dev_t* drv)
261 {
262     int     ret = 0;
263     uint8_t value = 0;
264 
265     value = LTR381_SET_BITSLICE(value, ALS_CS_ENABLE, LTR381_ALS_STANDBY_MODE);
266     value = LTR381_SET_BITSLICE(value, CS_MODE, LTR381_CS_MODE);
267     value = LTR381_SET_BITSLICE(value, SW_RESET, LTR381_ALS_NO_RESET);
268     ret = sensor_i2c_write(drv, LTR381_MAIN_CTRL_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
269     if (unlikely(ret)) {
270         return ret;
271     }
272 
273     value = 0;
274     value = LTR381_SET_BITSLICE(value, ALS_CS_MEAS_RATE, LTR381_ALS_CS_MEAS_RATE_100MS);
275     value = LTR381_SET_BITSLICE(value, ALS_CS_RESOLUTION, LTR381_ALS_CS_RESOLUTION_18BIT);
276     ret = sensor_i2c_write(drv, LTR381_ALS_CS_MEAS_RATE_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
277     if (unlikely(ret)) {
278         return ret;
279     }
280 
281     value = 0;
282     value = LTR381_SET_BITSLICE(value, ALS_CS_GAIN_RANGE, LTR381_ALS_CS_GAIN_RANGE_3);
283     ret = sensor_i2c_write(drv, LTR381_ALS_CS_GAIN_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
284     if (unlikely(ret)) {
285         return ret;
286     }
287 
288     value = 0;
289     value = LTR381_SET_BITSLICE(value, ALS_INT_PIN_EN, LTR381_ALS_INT_INACTIVE);
290     value = LTR381_SET_BITSLICE(value, ALS_INT_SEL, LTR381_ALS_INT_GREEN_CHANNEL);
291     ret = sensor_i2c_write(drv, LTR381_INT_CFG_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
292     if (unlikely(ret)) {
293         return ret;
294     }
295 
296     value = 0;
297     ret = sensor_i2c_write(drv, LTR381_INT_PST_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
298     if (unlikely(ret)) {
299         return ret;
300     }
301 
302     return 0;
303 }
304 
drv_rgb_liteon_ltr381_irq_handle(void)305 static void drv_rgb_liteon_ltr381_irq_handle(void)
306 {
307     /* no handle so far */
308 }
309 
drv_rgb_liteon_ltr381_open(void)310 static int drv_rgb_liteon_ltr381_open(void)
311 {
312     int ret = 0;
313 
314     ret = drv_rgb_liteon_ltr381_set_power_mode(&ltr381_ctx, DEV_POWER_ON);
315     if (unlikely(ret)) {
316         return -1;
317     }
318 
319     LOG("%s %s successfully \n", SENSOR_STR, __func__);
320     return 0;
321 }
322 
drv_rgb_liteon_ltr381_close(void)323 static int drv_rgb_liteon_ltr381_close(void)
324 {
325     int ret = 0;
326 
327     ret = drv_rgb_liteon_ltr381_set_power_mode(&ltr381_ctx, DEV_POWER_OFF);
328     if (unlikely(ret)) {
329         return -1;
330     }
331 
332     LOG("%s %s successfully \n", SENSOR_STR, __func__);
333     return 0;
334 }
335 
drv_rgb_liteon_ltr381_read(void * buf,size_t len)336 static int drv_rgb_liteon_ltr381_read(void *buf, size_t len)
337 {
338     int ret = 0;
339     size_t size;
340     uint8_t reg_ch_red_data[3] = { 0 };
341     uint8_t reg_ch_green_data[3] = { 0 };
342     uint8_t reg_ch_blue_data[3] = { 0 };
343     uint32_t ch_red_data = 0;
344     uint32_t ch_green_data = 0;
345     uint32_t ch_blue_data = 0;
346     rgb_data_t * pdata = (rgb_data_t *) buf;
347 
348     if (buf == NULL){
349         return -1;
350     }
351 
352     size = sizeof(rgb_data_t);
353     if (len < size){
354         return -1;
355     }
356 
357     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_GREEN_0_REG, &reg_ch_green_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
358     if (unlikely(ret)) {
359         return -1;
360     }
361 
362     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_GREEN_1_REG, &reg_ch_green_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
363     if (unlikely(ret)) {
364         return -1;
365     }
366 
367     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_GREEN_2_REG, &reg_ch_green_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
368     if (unlikely(ret)) {
369         return -1;
370     }
371 
372     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_RED_0_REG, &reg_ch_red_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
373     if (unlikely(ret)) {
374         return -1;
375     }
376 
377     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_RED_1_REG, &reg_ch_red_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
378     if (unlikely(ret)) {
379         return -1;
380     }
381 
382     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_RED_2_REG, &reg_ch_red_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
383     if (unlikely(ret)) {
384         return -1;
385     }
386 
387     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_BLUE_0_REG, &reg_ch_blue_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
388     if (unlikely(ret)) {
389         return -1;
390     }
391 
392     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_BLUE_1_REG, &reg_ch_blue_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
393     if (unlikely(ret)) {
394         return -1;
395     }
396 
397     ret = sensor_i2c_read(&ltr381_ctx, LTR381_CS_DATA_BLUE_2_REG, &reg_ch_blue_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
398     if (unlikely(ret)) {
399         return -1;
400     }
401 
402     ch_red_data = (((uint32_t) reg_ch_red_data[2] << 16) | ((uint32_t) reg_ch_red_data[1] << 8) | reg_ch_red_data[0]);
403     ch_green_data = (((uint32_t) reg_ch_green_data[2] << 16) | ((uint32_t) reg_ch_green_data[1] << 8) | reg_ch_green_data[0]);
404     ch_blue_data = (((uint32_t) reg_ch_blue_data[2] << 16) | ((uint32_t) reg_ch_blue_data[1] << 8) | reg_ch_blue_data[0]);
405     pdata->data[0] = ch_red_data;
406     pdata->data[1] = ch_green_data;
407     pdata->data[2] = ch_blue_data;
408     pdata->timestamp = aos_now_ms();
409 
410     return (int) size;
411 }
412 
drv_rgb_liteon_ltr381_write(const void * buf,size_t len)413 static int drv_rgb_liteon_ltr381_write(const void *buf, size_t len)
414 {
415     (void) buf;
416     (void) len;
417 
418     return 0;
419 }
420 
drv_rgb_liteon_ltr381_ioctl(int cmd,unsigned long arg)421 static int drv_rgb_liteon_ltr381_ioctl(int cmd, unsigned long arg)
422 {
423     int ret = 0;
424 
425     switch (cmd) {
426         case SENSOR_IOCTL_SET_POWER: {
427             ret = drv_rgb_liteon_ltr381_set_power_mode(&ltr381_ctx, arg);
428             if (unlikely(ret)) {
429                 return -1;
430             }
431         } break;
432         case SENSOR_IOCTL_GET_INFO: {
433             /* fill the dev info here */
434             dev_sensor_info_t *info = (dev_sensor_info_t *) arg;
435             info->vendor = DEV_SENSOR_VENDOR_LITEON;
436             info->model = "LTR381";
437             info->unit = lux;
438         } break;
439         default:
440             return -1;
441     }
442 
443     LOG("%s %s successfully \n", SENSOR_STR, __func__);
444     return 0;
445 }
446 
drv_rgb_liteon_ltr381_init(void)447 int drv_rgb_liteon_ltr381_init(void)
448 {
449     int ret = 0;
450     sensor_obj_t sensor_rgb;
451     memset(&sensor_rgb, 0, sizeof(sensor_rgb));
452 
453     if (!g_init_bitwise) {
454         ret = drv_rgb_liteon_ltr381_validate_id(&ltr381_ctx, LTR381_PART_ID_VAL);
455         if (unlikely(ret)) {
456             return -1;
457         }
458     }
459 
460     if (!g_init_bitwise) {
461         /* fill the sensor_rgb obj parameters here */
462         sensor_rgb.path = dev_rgb_path;
463         sensor_rgb.tag = TAG_DEV_RGB;
464         sensor_rgb.io_port = I2C_PORT;
465         sensor_rgb.mode = DEV_POLLING;
466         sensor_rgb.power = DEV_POWER_OFF;
467         sensor_rgb.open = drv_rgb_liteon_ltr381_open;
468         sensor_rgb.close = drv_rgb_liteon_ltr381_close;
469         sensor_rgb.read = drv_rgb_liteon_ltr381_read;
470         sensor_rgb.write = drv_rgb_liteon_ltr381_write;
471         sensor_rgb.ioctl = drv_rgb_liteon_ltr381_ioctl;
472         sensor_rgb.irq_handle = drv_rgb_liteon_ltr381_irq_handle;
473 
474         ret = sensor_create_obj(&sensor_rgb);
475         if (unlikely(ret)) {
476             return -1;
477         }
478 
479         ret = drv_rgb_liteon_ltr381_set_default_config(&ltr381_ctx);
480         if (unlikely(ret)) {
481             return -1;
482         }
483 
484         g_init_bitwise |= 1;
485     }
486 
487     LOG("%s %s successfully \n", SENSOR_STR, __func__);
488     return 0;
489 }
490 
491 SENSOR_DRV_ADD(drv_rgb_liteon_ltr381_init);
492 
493