28
28
#include <zephyr/logging/log.h>
29
29
LOG_MODULE_REGISTER (gpio_pca95xx );
30
30
31
+ #if CONFIG_LITTLE_ENDIAN
32
+ #define LOW_BYTE_LE16_IDX 0
33
+ #define HIGH_BYTE_LE16_IDX 1
34
+ #else
35
+ #define LOW_BYTE_LE16_IDX 1
36
+ #define HIGH_BYTE_LE16_IDX 0
37
+ #endif
38
+
31
39
/* Register definitions */
32
40
#define REG_INPUT_PORT0 0x00
33
41
#define REG_INPUT_PORT1 0x01
@@ -36,7 +44,7 @@ LOG_MODULE_REGISTER(gpio_pca95xx);
36
44
#define REG_POL_INV_PORT0 0x04
37
45
#define REG_POL_INV_PORT1 0x05
38
46
#define REG_CONF_PORT0 0x06
39
- #define REG_CONG_PORT1 0x07
47
+ #define REG_CONF_PORT1 0x07
40
48
#define REG_OUT_DRV_STRENGTH_PORT0_L 0x40
41
49
#define REG_OUT_DRV_STRENGTH_PORT0_H 0x41
42
50
#define REG_OUT_DRV_STRENGTH_PORT1_L 0x42
@@ -108,6 +116,37 @@ struct gpio_pca95xx_drv_data {
108
116
#endif
109
117
};
110
118
119
+ static int read_port_reg (const struct device * dev , uint8_t reg , uint8_t pin ,
120
+ uint16_t * cache , uint16_t * buf )
121
+ {
122
+ const struct gpio_pca95xx_config * const config = dev -> config ;
123
+ uint8_t b_buf ;
124
+ int ret ;
125
+
126
+ if (pin >= 8 )
127
+ reg ++ ;
128
+
129
+ ret = i2c_reg_read_byte_dt (& config -> bus , reg , & b_buf );
130
+ if (ret != 0 ) {
131
+ LOG_ERR ("PCA95XX[0x%X]: error reading register 0x%X (%d)" ,
132
+ config -> bus .addr , reg , ret );
133
+ return ret ;
134
+ }
135
+
136
+ if (pin < 8 ) {
137
+ ((uint8_t * )cache )[LOW_BYTE_LE16_IDX ] = b_buf ;
138
+ } else {
139
+ ((uint8_t * )cache )[HIGH_BYTE_LE16_IDX ] = b_buf ;
140
+ }
141
+
142
+ * buf = * cache ;
143
+
144
+ LOG_DBG ("PCA95XX[0x%X]: Read: REG[0x%X] = 0x%X" ,
145
+ config -> bus .addr , reg , b_buf );
146
+
147
+ return 0 ;
148
+ }
149
+
111
150
/**
112
151
* @brief Read both port 0 and port 1 registers of certain register function.
113
152
*
@@ -145,6 +184,36 @@ static int read_port_regs(const struct device *dev, uint8_t reg,
145
184
return 0 ;
146
185
}
147
186
187
+
188
+ static int write_port_reg (const struct device * dev , uint8_t reg , uint8_t pin ,
189
+ uint16_t * cache , uint16_t value )
190
+ {
191
+ const struct gpio_pca95xx_config * const config = dev -> config ;
192
+ uint8_t buf [2 ];
193
+ int ret ;
194
+
195
+ if (pin < 8 ) {
196
+ buf [1 ] = value ;
197
+ } else {
198
+ buf [1 ] = value >> 8 ;
199
+ reg ++ ;
200
+ }
201
+ buf [0 ] = reg ;
202
+
203
+ LOG_DBG ("PCA95XX[0x%X]: Write: REG[0x%X] = 0x%X" , config -> bus .addr ,
204
+ reg , buf [1 ]);
205
+
206
+ ret = i2c_write_dt (& config -> bus , buf , sizeof (buf ));
207
+ if (ret == 0 ) {
208
+ * cache = value ;
209
+ } else {
210
+ LOG_ERR ("PCA95XX[0x%X]: error writing to register 0x%X "
211
+ "(%d)" , config -> bus .addr , reg , ret );
212
+ }
213
+
214
+ return ret ;
215
+ }
216
+
148
217
/**
149
218
* @brief Write both port 0 and port 1 registers of certain register function.
150
219
*
@@ -182,6 +251,16 @@ static int write_port_regs(const struct device *dev, uint8_t reg,
182
251
return ret ;
183
252
}
184
253
254
+ static inline int update_input_reg (const struct device * dev , uint8_t pin ,
255
+ uint16_t * buf )
256
+ {
257
+ struct gpio_pca95xx_drv_data * const drv_data =
258
+ (struct gpio_pca95xx_drv_data * const )dev -> data ;
259
+
260
+ return read_port_reg (dev , REG_INPUT_PORT0 , pin ,
261
+ & drv_data -> reg_cache .input , buf );
262
+ }
263
+
185
264
static inline int update_input_regs (const struct device * dev , uint16_t * buf )
186
265
{
187
266
struct gpio_pca95xx_drv_data * const drv_data =
@@ -191,6 +270,16 @@ static inline int update_input_regs(const struct device *dev, uint16_t *buf)
191
270
& drv_data -> reg_cache .input , buf );
192
271
}
193
272
273
+ static inline int update_output_reg (const struct device * dev , uint8_t pin ,
274
+ uint16_t value )
275
+ {
276
+ struct gpio_pca95xx_drv_data * const drv_data =
277
+ (struct gpio_pca95xx_drv_data * const )dev -> data ;
278
+
279
+ return write_port_reg (dev , REG_OUTPUT_PORT0 , pin ,
280
+ & drv_data -> reg_cache .output , value );
281
+ }
282
+
194
283
static inline int update_output_regs (const struct device * dev , uint16_t value )
195
284
{
196
285
struct gpio_pca95xx_drv_data * const drv_data =
@@ -200,43 +289,45 @@ static inline int update_output_regs(const struct device *dev, uint16_t value)
200
289
& drv_data -> reg_cache .output , value );
201
290
}
202
291
203
- static inline int update_direction_regs (const struct device * dev ,
292
+ static inline int update_direction_reg (const struct device * dev , uint8_t pin ,
204
293
uint16_t value )
205
294
{
206
295
struct gpio_pca95xx_drv_data * const drv_data =
207
296
(struct gpio_pca95xx_drv_data * const )dev -> data ;
208
297
209
- return write_port_regs (dev , REG_CONF_PORT0 ,
210
- & drv_data -> reg_cache .dir , value );
298
+ return write_port_reg (dev , REG_CONF_PORT0 , pin ,
299
+ & drv_data -> reg_cache .dir , value );
211
300
}
212
301
213
- static inline int update_pul_sel_regs (const struct device * dev ,
214
- uint16_t value )
302
+ static inline int update_pul_sel_reg (const struct device * dev , uint8_t pin ,
303
+ uint16_t value )
215
304
{
216
305
struct gpio_pca95xx_drv_data * const drv_data =
217
306
(struct gpio_pca95xx_drv_data * const )dev -> data ;
218
307
219
- return write_port_regs (dev , REG_PUD_SEL_PORT0 ,
220
- & drv_data -> reg_cache .pud_sel , value );
308
+ return write_port_reg (dev , REG_PUD_SEL_PORT0 , pin ,
309
+ & drv_data -> reg_cache .pud_sel , value );
221
310
}
222
311
223
- static inline int update_pul_en_regs (const struct device * dev , uint16_t value )
312
+ static inline int update_pul_en_reg (const struct device * dev , uint8_t pin ,
313
+ uint8_t value )
224
314
{
225
315
struct gpio_pca95xx_drv_data * const drv_data =
226
316
(struct gpio_pca95xx_drv_data * const )dev -> data ;
227
317
228
- return write_port_regs (dev , REG_PUD_EN_PORT0 ,
229
- & drv_data -> reg_cache .pud_en , value );
318
+ return write_port_reg (dev , REG_PUD_EN_PORT0 , pin ,
319
+ & drv_data -> reg_cache .pud_en , value );
230
320
}
231
321
232
322
#ifdef CONFIG_GPIO_PCA95XX_INTERRUPT
233
- static inline int update_int_mask_regs (const struct device * dev , uint16_t value )
323
+ static inline int update_int_mask_reg (const struct device * dev , uint8_t pin ,
324
+ uint16_t value )
234
325
{
235
326
struct gpio_pca95xx_drv_data * const drv_data =
236
327
(struct gpio_pca95xx_drv_data * const )dev -> data ;
237
328
238
- return write_port_regs (dev , REG_INT_MASK_PORT0 ,
239
- & drv_data -> reg_cache .int_mask , value );
329
+ return write_port_reg (dev , REG_INT_MASK_PORT0 , pin ,
330
+ & drv_data -> reg_cache .int_mask , value );
240
331
}
241
332
#endif /* CONFIG_GPIO_PCA95XX_INTERRUPT */
242
333
@@ -264,7 +355,7 @@ static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags)
264
355
} else if ((flags & GPIO_OUTPUT_INIT_LOW ) != 0U ) {
265
356
reg_out &= ~BIT (pin );
266
357
}
267
- ret = update_output_regs (dev , reg_out );
358
+ ret = update_output_reg (dev , pin , reg_out );
268
359
if (ret != 0 ) {
269
360
return ret ;
270
361
}
@@ -273,7 +364,7 @@ static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags)
273
364
reg_dir |= BIT (pin );
274
365
}
275
366
276
- ret = update_direction_regs (dev , reg_dir );
367
+ ret = update_direction_reg (dev , pin , reg_dir );
277
368
278
369
return ret ;
279
370
}
@@ -319,7 +410,7 @@ static int setup_pin_pullupdown(const struct device *dev, uint32_t pin,
319
410
/* pull down == 0, pull up == 1 */
320
411
WRITE_BIT (reg_pud , pin , (flags & GPIO_PULL_UP ) != 0U );
321
412
322
- ret = update_pul_sel_regs (dev , reg_pud );
413
+ ret = update_pul_sel_reg (dev , pin , reg_pud );
323
414
if (ret ) {
324
415
return ret ;
325
416
}
@@ -331,7 +422,7 @@ static int setup_pin_pullupdown(const struct device *dev, uint32_t pin,
331
422
WRITE_BIT (reg_pud , pin ,
332
423
(flags & (GPIO_PULL_UP | GPIO_PULL_DOWN )) != 0U );
333
424
334
- ret = update_pul_en_regs (dev , reg_pud );
425
+ ret = update_pul_en_reg (dev , pin , reg_pud );
335
426
336
427
return ret ;
337
428
}
@@ -394,8 +485,7 @@ static int gpio_pca95xx_config(const struct device *dev,
394
485
return ret ;
395
486
}
396
487
397
- static int gpio_pca95xx_port_get_raw (const struct device * dev ,
398
- uint32_t * value )
488
+ static int gpio_pca95xx_port_get_raw (const struct device * dev , uint32_t * value )
399
489
{
400
490
struct gpio_pca95xx_drv_data * const drv_data =
401
491
(struct gpio_pca95xx_drv_data * const )dev -> data ;
@@ -587,7 +677,7 @@ static int gpio_pca95xx_pin_interrupt_configure(const struct device *dev,
587
677
reg_out = drv_data -> reg_cache .int_mask ;
588
678
WRITE_BIT (reg_out , pin , (mode == GPIO_INT_MODE_DISABLED ));
589
679
590
- ret = update_int_mask_regs (dev , reg_out );
680
+ ret = update_int_mask_reg (dev , pin , reg_out );
591
681
if (ret != 0 ) {
592
682
LOG_ERR ("PCA95XX[0x%X]: failed to update int mask (%d)" ,
593
683
config -> bus .addr , ret );
0 commit comments