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)<R659_##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(<r659_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(<r659_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(<r659_ctx, LTR659_PS_DATA_0, ®_data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
347 if (unlikely(ret)) {
348 return -1;
349 }
350 ret = sensor_i2c_read(<r659_ctx, LTR659_PS_DATA_1, ®_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(<r659_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(<r659_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(<r659_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