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 LTR390_I2C_SLAVE_ADDR 0x53
9
10 #define LTR390_MAIN_CTRL 0x00 /* Operation mode control */
11 #define LTR390_ALS_UVS_MEAS_RATE 0x04 /* Measurement rate and resolution */
12 #define LTR390_ALS_UVS_GAIN 0x05 /* Analog gain range*/
13 #define LTR390_PART_ID 0x06
14 #define LTR390_MAIN_STATUS 0x07
15 #define LTR390_ALS_DATA_0 0x0D
16 #define LTR390_ALS_DATA_1 0x0E
17 #define LTR390_ALS_DATA_2 0x0F
18 #define LTR390_UVS_DATA_0 0x10
19 #define LTR390_UVS_DATA_1 0x11
20 #define LTR390_UVS_DATA_2 0x12
21 #define LTR390_INT_CFG 0x19
22 #define LTR390_INT_PST 0x1A /* Interrupt persist setting */
23 #define LTR390_ALS_UVS_THRES_UP_0 0x21 /* Interrupt upper threshold, lower byte */
24 #define LTR390_ALS_UVS_THRES_UP_1 0x22 /* Interrupt upper threshold, middle byte */
25 #define LTR390_ALS_UVS_THRES_UP_2 0x23 /* Interrupt upper threshold, upper byte */
26 #define LTR390_ALS_UVS_THRES_LOW_0 0x24 /* Interrupt lower threshold, lower byte */
27 #define LTR390_ALS_UVS_THRES_LOW_1 0x25 /* Interrupt lower threshold, middle byte */
28 #define LTR390_ALS_UVS_THRES_LOW_2 0x26 /* Interrupt lower threshold, upper byte */
29
30 #define LTR390_ADDR_TRANS(n) ((n) << 1)
31 #define LTR390_I2C_ADDR LTR390_ADDR_TRANS(LTR390_I2C_SLAVE_ADDR)
32 #define LTR390_PART_ID_VAL 0xB2
33
34 #define LTR390_MAIN_CTRL_REG_ALS_UVS_EN__POS (1)
35 #define LTR390_MAIN_CTRL_REG_ALS_UVS_EN__MSK (0x02)
36 #define LTR390_MAIN_CTRL_REG_ALS_UVS_EN__REG (LTR390_MAIN_CTRL)
37
38 #define LTR390_MAIN_CTRL_REG_UVS_MODE__POS (3)
39 #define LTR390_MAIN_CTRL_REG_UVS_MODE__MSK (0x08)
40 #define LTR390_MAIN_CTRL_REG_UVS_MODE__REG (LTR390_MAIN_CTRL)
41
42 #define LTR390_MAIN_CTRL_REG_SW_RESET__POS (4)
43 #define LTR390_MAIN_CTRL_REG_SW_RESET__MSK (0x10)
44 #define LTR390_MAIN_CTRL_REG_SW_RESET__REG (LTR390_MAIN_CTRL)
45
46 #define LTR390_ALS_UVS_MEAS_RATE_REG_MEAS_RATE__POS (0)
47 #define LTR390_ALS_UVS_MEAS_RATE_REG_MEAS_RATE__MSK (0x07)
48 #define LTR390_ALS_UVS_MEAS_RATE_REG_MEAS_RATE__REG (LTR390_ALS_UVS_MEAS_RATE)
49
50 #define LTR390_ALS_UVS_MEAS_RATE_REG_RESOLUTION__POS (4)
51 #define LTR390_ALS_UVS_MEAS_RATE_REG_RESOLUTION__MSK (0x70)
52 #define LTR390_ALS_UVS_MEAS_RATE_REG_RESOLUTION__REG (LTR390_ALS_UVS_MEAS_RATE)
53
54 #define LTR390_ALS_UVS_GAIN_REG_GAIN_RANGE__POS (0)
55 #define LTR390_ALS_UVS_GAIN_REG_GAIN_RANGE__MSK (0x07)
56 #define LTR390_ALS_UVS_GAIN_REG_GAIN_RANGE__REG (LTR390_ALS_UVS_GAIN)
57
58 #define LTR390_MAIN_STATUS_REG_ALS_UVS_DATA_STATUS__POS (3)
59 #define LTR390_MAIN_STATUS_REG_ALS_UVS_DATA_STATUS__MSK (0x08)
60 #define LTR390_MAIN_STATUS_REG_ALS_UVS_DATA_STATUS__REG (LTR390_MAIN_STATUS)
61
62 #define LTR390_MAIN_STATUS_REG_ALS_UVS_INT_STATUS__POS (4)
63 #define LTR390_MAIN_STATUS_REG_ALS_UVS_INT_STATUS__MSK (0x10)
64 #define LTR390_MAIN_STATUS_REG_ALS_UVS_INT_STATUS__REG (LTR390_MAIN_STATUS)
65
66 #define LTR390_MAIN_STATUS_REG_POWER_ON_STATUS__POS (5)
67 #define LTR390_MAIN_STATUS_REG_POWER_ON_STATUS__MSK (0x20)
68 #define LTR390_MAIN_STATUS_REG_POWER_ON_STATUS__REG (LTR390_MAIN_STATUS)
69
70 #define LTR390_INT_CFG_REG_LS_INT_EN__POS (2)
71 #define LTR390_INT_CFG_REG_LS_INT_EN__MSK (0x04)
72 #define LTR390_INT_CFG_REG_LS_INT_EN__REG (LTR390_INT_CFG)
73
74 #define LTR390_INT_CFG_REG_LS_INT_SEL__POS (4)
75 #define LTR390_INT_CFG_REG_LS_INT_SEL__MSK (0x30)
76 #define LTR390_INT_CFG_REG_LS_INT_SEL__REG (LTR390_INT_CFG)
77
78 #define LTR390_INT_PST_REG_ALS_UV_PERSIST__POS (4)
79 #define LTR390_INT_PST_REG_ALS_UV_PERSIST__MSK (0xF0)
80 #define LTR390_INT_PST_REG_ALS_UV_PERSIST__REG (LTR390_INT_PST)
81
82 #define LTR390_GET_BITSLICE(regvar, bitname) ((regvar & LTR390_##bitname##__MSK) >> LTR390_##bitname##__POS)
83 #define LTR390_SET_BITSLICE(regvar, bitname, val) ((regvar & ~LTR390_##bitname##__MSK) | ((val<<LTR390_##bitname##__POS)<R390_##bitname##__MSK))
84
85 #define LTR390_WAIT_TIME_PER_CHECK (10)
86 #define LTR390_WAIT_TIME_TOTAL (100)
87
88 typedef enum {
89 LTR390_ALS_UVS_STANDBY = 0x00,
90 LTR390_ALS_UVS_ACTIVE = 0x01,
91 } LTR390_CFG_ALS_UVS_EN;
92
93 typedef enum {
94 LTR390_ALS_MODE = 0x00,
95 LTR390_UVS_MODE = 0x01,
96 } LTR390_CFG_ALS_UVS_MODE;
97
98 typedef enum {
99 LTR390_SW_RESET_FALSE = 0x00,
100 LTR390_SW_RESET_TRUE = 0x01,
101 } LTR390_CFG_SW_RESET;
102
103 typedef enum {
104 LTR390_ALS_UVS_MEAS_RATE_25 = 0x00, /* Measurement Repeat Rate = 25ms */
105 LTR390_ALS_UVS_MEAS_RATE_50 = 0x01, /* Measurement Repeat Rate = 50ms */
106 LTR390_ALS_UVS_MEAS_RATE_100 = 0x02, /* Measurement Repeat Rate = 100ms (default) */
107 LTR390_ALS_UVS_MEAS_RATE_200 = 0x03, /* Measurement Repeat Rate = 200ms */
108 LTR390_ALS_UVS_MEAS_RATE_500 = 0x04, /* Measurement Repeat Rate = 500ms */
109 LTR390_ALS_UVS_MEAS_RATE_1000 = 0x05, /* Measurement Repeat Rate = 1000ms */
110 LTR390_ALS_UVS_MEAS_RATE_2000 = 0x06, /* Measurement Repeat Rate = 2000ms */
111 } LTR390_CFG_ALS_UVS_MEAS_RATE;
112
113 typedef enum {
114 LTR390_ALS_UVS_RESOLUTION_20BIT = 0x00, /* 20 bit, conversion time = 400ms */
115 LTR390_ALS_UVS_RESOLUTION_19BIT = 0x01, /* 19 bit, conversion time = 200ms */
116 LTR390_ALS_UVS_RESOLUTION_18BIT = 0x02, /* 18 bit, conversion time = 100ms (default) */
117 LTR390_ALS_UVS_RESOLUTION_17BIT = 0x03, /* 17 bit, conversion time = 50ms */
118 LTR390_ALS_UVS_RESOLUTION_16BIT = 0x04, /* 16 bit, conversion time = 25ms */
119 LTR390_ALS_UVS_RESOLUTION_13BIT = 0x05, /* 13 bit, conversion time = 12.5ms */
120 } LTR390_CFG_ALS_UVS_RESOLUTION;
121
122 typedef enum {
123 LTR390_ALS_UVS_GAIN_RANGE_1 = 0x00,
124 LTR390_ALS_UVS_GAIN_RANGE_3 = 0x01,
125 LTR390_ALS_UVS_GAIN_RANGE_6 = 0x02,
126 LTR390_ALS_UVS_GAIN_RANGE_9 = 0x03,
127 LTR390_ALS_UVS_GAIN_RANGE_18 = 0x04,
128 } LTR390_CFG_ALS_UVS_GAIN_RANGE;
129
130 typedef enum {
131 LTR390_ALS_UVS_DATA_STATUS_OLD = 0x00,
132 LTR390_ALS_UVS_DATA_STATUS_NEW = 0x01,
133 } LTR390_CFG_ALS_UVS_DATA_STATUS;
134
135 typedef enum {
136 LTR390_ALS_UVS_INT_STATUS_INACTIVE = 0x00,
137 LTR390_ALS_UVS_INT_STATUS_ACTIVE = 0x01,
138 } LTR390_CFG_ALS_UVS_INT_STATUS;
139
140 typedef enum {
141 LTR390_ALS_UVS_POWER_ON_STATUS_FALSE = 0x00,
142 LTR390_ALS_UVS_POWER_ON_STATUS_TRUE = 0x01,
143 } LTR390_CFG_ALS_UVS_POWER_ON_STATUS;
144
145 typedef enum {
146 LTR390_LS_INT_DISABLE = 0x00,
147 LTR390_LS_INT_ENABLE = 0x01,
148 } LTR390_CFG_LS_INT_EN;
149
150 typedef enum {
151 LTR390_LS_INT_SEL_ALS_CHANNEL = 0x01,
152 LTR390_LS_INT_SEL_UVS_CHANNEL = 0x03,
153 } LTR390_CFG_LS_INT_SEL;
154
155 i2c_dev_t ltr390_ctx = {
156 .port = 3,
157 .config.address_width = 8,
158 .config.freq = 100000,
159 .config.dev_addr = LTR390_I2C_ADDR,
160 };
161
162 static uint8_t g_init_bitwise = 0;
163
drv_uv_liteon_ltr390_validate_id(i2c_dev_t * drv,uint8_t part_id)164 static int drv_uv_liteon_ltr390_validate_id(i2c_dev_t* drv, uint8_t part_id)
165 {
166 int ret = 0;
167 uint8_t part_id_value = 0;
168
169 if (drv == NULL) {
170 return -1;
171 }
172
173 ret = sensor_i2c_read(drv, LTR390_PART_ID, &part_id_value, I2C_DATA_LEN, I2C_OP_RETRIES);
174 if (unlikely(ret)) {
175 return ret;
176 }
177
178 if (part_id_value != part_id) {
179 return -1;
180 }
181
182 return 0;
183 }
184
drv_uv_liteon_ltr390_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)185 static int drv_uv_liteon_ltr390_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
186 {
187 int ret = 0;
188 uint8_t dev_mode = 0;
189 uint8_t value = 0;
190
191 ret = sensor_i2c_read(drv, LTR390_MAIN_CTRL, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
192 if (unlikely(ret)) {
193 return ret;
194 }
195
196 switch (mode) {
197 case DEV_POWER_OFF:
198 case DEV_SLEEP:
199 dev_mode = LTR390_SET_BITSLICE(value, MAIN_CTRL_REG_ALS_UVS_EN, LTR390_ALS_UVS_STANDBY);
200 break;
201 case DEV_POWER_ON:
202 dev_mode = LTR390_SET_BITSLICE(value, MAIN_CTRL_REG_ALS_UVS_EN, LTR390_ALS_UVS_ACTIVE);
203 break;
204 default:
205 return -1;
206 }
207
208 ret = sensor_i2c_write(drv, LTR390_MAIN_CTRL, &dev_mode, I2C_DATA_LEN, I2C_OP_RETRIES);
209 if (unlikely(ret)) {
210 return ret;
211 }
212
213 return 0;
214 }
215
drv_uv_liteon_ltr390_is_ready(i2c_dev_t * drv)216 UNUSED static int drv_uv_liteon_ltr390_is_ready(i2c_dev_t* drv)
217 {
218 int ret = 0;
219 uint8_t value = 0;
220
221 ret = sensor_i2c_read(drv, LTR390_MAIN_STATUS, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
222 if (unlikely(ret)) {
223 return 0;
224 }
225
226 ret = (LTR390_GET_BITSLICE(value, MAIN_STATUS_REG_ALS_UVS_DATA_STATUS) == LTR390_ALS_UVS_DATA_STATUS_NEW) ? 1 : 0;
227
228 return ret;
229 }
230
drv_uv_liteon_ltr390_set_default_config(i2c_dev_t * drv)231 static int drv_uv_liteon_ltr390_set_default_config(i2c_dev_t* drv)
232 {
233 int ret = 0;
234 uint8_t value = 0;
235
236 ret = sensor_i2c_read(drv, LTR390_MAIN_CTRL, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
237 if (unlikely(ret)) {
238 return ret;
239 }
240 value = LTR390_SET_BITSLICE(value, MAIN_CTRL_REG_UVS_MODE, LTR390_UVS_MODE);
241 ret = sensor_i2c_write(drv, LTR390_MAIN_CTRL, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
242 if (unlikely(ret)) {
243 return ret;
244 }
245
246 value = 0;
247 value = LTR390_SET_BITSLICE(value, ALS_UVS_MEAS_RATE_REG_MEAS_RATE, LTR390_ALS_UVS_MEAS_RATE_100);
248 value = LTR390_SET_BITSLICE(value, ALS_UVS_MEAS_RATE_REG_RESOLUTION, LTR390_ALS_UVS_RESOLUTION_16BIT);
249 ret = sensor_i2c_write(drv, LTR390_ALS_UVS_MEAS_RATE, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
250 if (unlikely(ret)) {
251 return ret;
252 }
253
254 value = 0;
255 value = LTR390_SET_BITSLICE(value, ALS_UVS_GAIN_REG_GAIN_RANGE, LTR390_ALS_UVS_GAIN_RANGE_18);
256 ret = sensor_i2c_write(drv, LTR390_ALS_UVS_GAIN, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
257 if (unlikely(ret)) {
258 return ret;
259 }
260
261 value = 0;
262 value = LTR390_SET_BITSLICE(value, INT_CFG_REG_LS_INT_EN, LTR390_LS_INT_DISABLE);
263 value = LTR390_SET_BITSLICE(value, INT_CFG_REG_LS_INT_SEL, LTR390_LS_INT_SEL_ALS_CHANNEL);
264 ret = sensor_i2c_write(drv, LTR390_INT_CFG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
265 if (unlikely(ret)) {
266 return ret;
267 }
268
269 return 0;
270 }
271
drv_uv_liteon_ltr390_irq_handle(void)272 static void drv_uv_liteon_ltr390_irq_handle(void)
273 {
274 /* no handle so far */
275 }
276
drv_uv_liteon_ltr390_open(void)277 static int drv_uv_liteon_ltr390_open(void)
278 {
279 int ret = 0;
280
281 ret = drv_uv_liteon_ltr390_set_power_mode(<r390_ctx, DEV_POWER_ON);
282 if (unlikely(ret)) {
283 return -1;
284 }
285
286 LOG("%s %s successfully \n", SENSOR_STR, __func__);
287 return 0;
288
289 }
290
drv_uv_liteon_ltr390_close(void)291 static int drv_uv_liteon_ltr390_close(void)
292 {
293 int ret = 0;
294
295 ret = drv_uv_liteon_ltr390_set_power_mode(<r390_ctx, DEV_POWER_OFF);
296 if (unlikely(ret)) {
297 return -1;
298 }
299
300 LOG("%s %s successfully \n", SENSOR_STR, __func__);
301 return 0;
302 }
303
drv_uv_liteon_ltr390_read(void * buf,size_t len)304 static int drv_uv_liteon_ltr390_read(void *buf, size_t len)
305 {
306 int ret = 0;
307 size_t size;
308 uint8_t reg_data[3] = { 0 };
309 uv_data_t * pdata = (uv_data_t *) buf;
310
311 if (buf == NULL) {
312 return -1;
313 }
314
315 size = sizeof(uv_data_t);
316 if (len < size) {
317 return -1;
318 }
319
320 ret = sensor_i2c_read(<r390_ctx, LTR390_UVS_DATA_0, ®_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
321 if (unlikely(ret)) {
322 return -1;
323 }
324 ret = sensor_i2c_read(<r390_ctx, LTR390_UVS_DATA_1, ®_data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
325 if (unlikely(ret)) {
326 return -1;
327 }
328 ret = sensor_i2c_read(<r390_ctx, LTR390_UVS_DATA_2, ®_data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
329 if (unlikely(ret)) {
330 return -1;
331 }
332
333 pdata->uvi = ((((uint16_t) (reg_data[1] & 0xFF)) << 8) | reg_data[0]);
334 pdata->timestamp = aos_now_ms();
335
336 return (int) size;
337 }
338
drv_uv_liteon_ltr390_write(const void * buf,size_t len)339 static int drv_uv_liteon_ltr390_write(const void *buf, size_t len)
340 {
341 (void) buf;
342 (void) len;
343
344 return 0;
345 }
346
drv_uv_liteon_ltr390_ioctl(int cmd,unsigned long arg)347 static int drv_uv_liteon_ltr390_ioctl(int cmd, unsigned long arg)
348 {
349 int ret = 0;
350
351 switch (cmd) {
352 case SENSOR_IOCTL_SET_POWER: {
353 ret = drv_uv_liteon_ltr390_set_power_mode(<r390_ctx, arg);
354 if (unlikely(ret)) {
355 return -1;
356 }
357 } break;
358 case SENSOR_IOCTL_GET_INFO: {
359 /* fill the dev info here */
360 dev_sensor_info_t *info = (dev_sensor_info_t *) arg;
361 info->vendor = DEV_SENSOR_VENDOR_LITEON;
362 info->model = "LTR390";
363 info->unit = lux;
364 } break;
365 default:
366 return -1;
367 }
368
369 LOG("%s %s successfully \n", SENSOR_STR, __func__);
370 return 0;
371 }
372
drv_uv_liteon_ltr390_init(void)373 int drv_uv_liteon_ltr390_init(void)
374 {
375 int ret = 0;
376 sensor_obj_t sensor_uv;
377 memset(&sensor_uv, 0, sizeof(sensor_uv));
378
379 if (!g_init_bitwise) {
380 ret = drv_uv_liteon_ltr390_validate_id(<r390_ctx, LTR390_PART_ID_VAL);
381 if (unlikely(ret)) {
382 return -1;
383 }
384 }
385
386 if (!g_init_bitwise) {
387 /* fill the sensor_uv obj parameters here */
388 sensor_uv.tag = TAG_DEV_UV;
389 sensor_uv.path = dev_uv_path;
390 sensor_uv.io_port = I2C_PORT;
391 sensor_uv.mode = DEV_POLLING;
392 sensor_uv.power = DEV_POWER_OFF;
393 sensor_uv.open = drv_uv_liteon_ltr390_open;
394 sensor_uv.close = drv_uv_liteon_ltr390_close;
395 sensor_uv.read = drv_uv_liteon_ltr390_read;
396 sensor_uv.write = drv_uv_liteon_ltr390_write;
397 sensor_uv.ioctl = drv_uv_liteon_ltr390_ioctl;
398 sensor_uv.irq_handle = drv_uv_liteon_ltr390_irq_handle;
399
400 ret = sensor_create_obj(&sensor_uv);
401 if (unlikely(ret)) {
402 return -1;
403 }
404
405 ret = drv_uv_liteon_ltr390_set_default_config(<r390_ctx);
406 if (unlikely(ret)) {
407 return -1;
408 }
409
410 g_init_bitwise = 1;
411 }
412
413 LOG("%s %s successfully \n", SENSOR_STR, __func__);
414 return 0;
415 }
416
417 SENSOR_DRV_ADD(drv_uv_liteon_ltr390_init);
418
419