@@ -48,6 +48,112 @@ static void apds9960_gpio_callback(const struct device *dev,
4848}
4949#endif
5050
51+ #if CONFIG_APDS9960_ENABLE_GESTURE
52+ static int apds9960_gesture_fetch (const struct device * dev )
53+ {
54+ const struct apds9960_config * config = dev -> config ;
55+ struct apds9960_data * data = dev -> data ;
56+
57+ uint8_t gesture_fifo_cnt ;
58+ uint8_t gstatus ;
59+ uint8_t gesture_fifo [4 ];
60+ int tmp_up ;
61+ int tmp_left ;
62+ int net_up = 0 ;
63+ int net_left = 0 ;
64+
65+ bool up_trig = false;
66+ bool down_trig = false;
67+ bool left_trig = false;
68+ bool right_trig = false;
69+
70+ data -> gesture = APDS9960_GESTURE_NONE ;
71+
72+ if (i2c_reg_read_byte_dt (& config -> i2c ,
73+ APDS9960_GSTATUS_REG , & gstatus )) {
74+ return - EIO ;
75+ }
76+
77+ while (gstatus & APDS9960_GSTATUS_GVALID ) {
78+ if (i2c_reg_read_byte_dt (& config -> i2c ,
79+ APDS9960_GFLVL_REG , & gesture_fifo_cnt )) {
80+ return - EIO ;
81+ }
82+
83+ for (int i = 0 ; i < gesture_fifo_cnt ; ++ i ) {
84+ /* Read up fifo and adjacent registers */
85+ if (i2c_burst_read_dt (& config -> i2c ,
86+ APDS9960_GFIFO_U_REG ,
87+ (uint8_t * ) gesture_fifo ,
88+ 4 )) {
89+ return - EIO ;
90+ }
91+
92+ tmp_up = (int ) gesture_fifo [0 ] - (int ) gesture_fifo [1 ];
93+ tmp_left = (int ) gesture_fifo [2 ] - (int ) gesture_fifo [3 ];
94+
95+ if (abs (tmp_up ) > config -> gesture_config .ir_difference ) {
96+ net_up = tmp_up ;
97+ }
98+ if (abs (tmp_left ) > config -> gesture_config .ir_difference ) {
99+ net_left = tmp_left ;
100+ }
101+
102+ if (net_up > 0 ) {
103+ if (down_trig ) {
104+ data -> gesture = APDS9960_GESTURE_DOWN ;
105+ up_trig = false;
106+ down_trig = false;
107+ left_trig = false;
108+ right_trig = false;
109+ } else {
110+ up_trig = true;
111+ }
112+ } else if (net_up < 0 ) {
113+ if (up_trig ) {
114+ data -> gesture = APDS9960_GESTURE_UP ;
115+ up_trig = false;
116+ down_trig = false;
117+ left_trig = false;
118+ right_trig = false;
119+ } else {
120+ down_trig = true;
121+ }
122+ }
123+ if (net_left > 0 ) {
124+ if (right_trig ) {
125+ data -> gesture = APDS9960_GESTURE_RIGHT ;
126+ up_trig = false;
127+ down_trig = false;
128+ left_trig = false;
129+ right_trig = false;
130+ } else {
131+ left_trig = true;
132+ }
133+ } else if (net_left < 0 ) {
134+ if (left_trig ) {
135+ data -> gesture = APDS9960_GESTURE_LEFT ;
136+ up_trig = false;
137+ down_trig = false;
138+ left_trig = false;
139+ right_trig = false;
140+ } else {
141+ right_trig = true;
142+ }
143+ }
144+ }
145+
146+ if (i2c_reg_read_byte_dt (& config -> i2c ,
147+ APDS9960_GSTATUS_REG , & gstatus )) {
148+ return - EIO ;
149+ }
150+ }
151+ LOG_DBG ("Net up: 0x%x, Net left: 0x%x" , net_up , net_left );
152+
153+ return 0 ;
154+ }
155+ #endif
156+
51157static int apds9960_sample_fetch (const struct device * dev ,
52158 enum sensor_channel chan )
53159{
@@ -63,6 +169,12 @@ static int apds9960_sample_fetch(const struct device *dev,
63169 return - ENOTSUP ;
64170 }
65171
172+ #ifdef CONFIG_APDS9960_ENABLE_GESTURE
173+ if (apds9960_gesture_fetch (dev )) {
174+ return - EIO ;
175+ }
176+ #endif
177+
66178#ifndef CONFIG_APDS9960_TRIGGER
67179#ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT
68180 apds9960_setup_int (config , true);
@@ -90,16 +202,9 @@ static int apds9960_sample_fetch(const struct device *dev,
90202 start_time = k_uptime_get ();
91203#ifdef CONFIG_APDS9960_ENABLE_ALS
92204 while (!(tmp & APDS9960_STATUS_AINT )) {
93- k_sleep (K_MSEC (APDS9960_DEFAULT_WAIT_TIME ));
94- if (i2c_reg_read_byte_dt (& config -> i2c , APDS9960_STATUS_REG , & tmp )) {
95- return - EIO ;
96- }
97- if ((k_uptime_get () - start_time ) > APDS9960_MAX_WAIT_TIME ) {
98- return - ETIMEDOUT ;
99- }
100- }
101205#else
102206 while (!(tmp & APDS9960_STATUS_PINT )) {
207+ #endif
103208 k_sleep (K_MSEC (APDS9960_DEFAULT_WAIT_TIME ));
104209 if (i2c_reg_read_byte_dt (& config -> i2c , APDS9960_STATUS_REG , & tmp )) {
105210 return - EIO ;
@@ -108,7 +213,6 @@ static int apds9960_sample_fetch(const struct device *dev,
108213 return - ETIMEDOUT ;
109214 }
110215 }
111- #endif
112216#endif
113217
114218 LOG_DBG ("status: 0x%x" , tmp );
@@ -172,6 +276,12 @@ static int apds9960_channel_get(const struct device *dev,
172276 val -> val1 = sys_le16_to_cpu (data -> sample_crgb [3 ]);
173277 val -> val2 = 0 ;
174278 break ;
279+ #endif
280+ #ifdef CONFIG_APDS9960_ENABLE_GESTURE
281+ case SENSOR_CHAN_APDS9960_GESTURE :
282+ val -> val1 = data -> gesture ;
283+ val -> val2 = 0 ;
284+ break ;
175285#endif
176286 case SENSOR_CHAN_PROX :
177287 val -> val1 = data -> pdata ;
@@ -304,6 +414,45 @@ static int apds9960_ambient_setup(const struct device *dev)
304414}
305415#endif
306416
417+ #ifdef CONFIG_APDS9960_ENABLE_GESTURE
418+ static int apds9960_gesture_setup (const struct device * dev )
419+ {
420+ const struct apds9960_config * config = dev -> config ;
421+
422+ if (i2c_reg_write_byte_dt (& config -> i2c ,
423+ APDS9960_GPENTH_REG , config -> gesture_config .proximity )) {
424+ LOG_ERR ("Gesture proximity enter not set." );
425+ return - EIO ;
426+ }
427+ if (i2c_reg_write_byte_dt (& config -> i2c ,
428+ APDS9960_GEXTH_REG , config -> gesture_config .proximity )) {
429+ LOG_ERR ("Gesture proximity exit not set." );
430+ return - EIO ;
431+ }
432+ if (i2c_reg_write_byte_dt (& config -> i2c ,
433+ APDS9960_GCONFIG1_REG , 0 )) {
434+ LOG_ERR ("Gesture config 1 not set." );
435+ return - EIO ;
436+ }
437+ if (i2c_reg_write_byte_dt (& config -> i2c ,
438+ APDS9960_GCONFIG2_REG , APDS9960_GGAIN_4X )) {
439+ LOG_ERR ("Gesture config 2 not set." );
440+ return - EIO ;
441+ }
442+ if (i2c_reg_write_byte_dt (& config -> i2c ,
443+ APDS9960_GCONFIG4_REG , 0 )) {
444+ LOG_ERR ("Gesture config 4 not set." );
445+ return - EIO ;
446+ }
447+ if (i2c_reg_update_byte_dt (& config -> i2c , APDS9960_ENABLE_REG , APDS9960_ENABLE_GEN ,
448+ APDS9960_ENABLE_GEN )) {
449+ LOG_ERR ("Gesture on bit not set." );
450+ return - EIO ;
451+ }
452+ return 0 ;
453+ }
454+ #endif
455+
307456static int apds9960_sensor_setup (const struct device * dev )
308457{
309458 const struct apds9960_config * config = dev -> config ;
@@ -385,6 +534,13 @@ static int apds9960_sensor_setup(const struct device *dev)
385534 }
386535#endif
387536
537+ #ifdef CONFIG_APDS9960_ENABLE_GESTURE
538+ if (apds9960_gesture_setup (dev )) {
539+ LOG_ERR ("Failed to setup gesture functionality" );
540+ return - EIO ;
541+ }
542+ #endif
543+
388544#ifdef CONFIG_APDS9960_FETCH_MODE_POLL
389545 if (i2c_reg_update_byte_dt (& config -> i2c , APDS9960_ENABLE_REG , APDS9960_ENABLE_PON ,
390546 APDS9960_ENABLE_PON )) {
0 commit comments