]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - drivers/gpio/pca9698.c
1 // SPDX-License-Identifier: GPL-2.0+
4 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
8 * Driver for NXP's pca9698 40 bit I2C gpio expander
13 #include <linux/errno.h>
17 * The pca9698 registers
20 #define PCA9698_REG_INPUT 0x00
21 #define PCA9698_REG_OUTPUT 0x08
22 #define PCA9698_REG_POLARITY 0x10
23 #define PCA9698_REG_CONFIG 0x18
25 #define PCA9698_BUFFER_SIZE 5
26 #define PCA9698_GPIO_COUNT 40
28 static int pca9698_read40(u8 addr
, u8 offset
, u8
*buffer
)
30 u8 command
= offset
| 0x80; /* autoincrement */
32 return i2c_read(addr
, command
, 1, buffer
, PCA9698_BUFFER_SIZE
);
35 static int pca9698_write40(u8 addr
, u8 offset
, u8
*buffer
)
37 u8 command
= offset
| 0x80; /* autoincrement */
39 return i2c_write(addr
, command
, 1, buffer
, PCA9698_BUFFER_SIZE
);
42 static void pca9698_set_bit(unsigned gpio
, u8
*buffer
, unsigned value
)
44 unsigned byte
= gpio
/ 8;
45 unsigned bit
= gpio
% 8;
48 buffer
[byte
] |= (1 << bit
);
50 buffer
[byte
] &= ~(1 << bit
);
53 int pca9698_request(unsigned gpio
, const char *label
)
55 if (gpio
>= PCA9698_GPIO_COUNT
)
61 void pca9698_free(unsigned gpio
)
65 int pca9698_direction_input(u8 addr
, unsigned gpio
)
67 u8 data
[PCA9698_BUFFER_SIZE
];
70 res
= pca9698_read40(addr
, PCA9698_REG_CONFIG
, data
);
74 pca9698_set_bit(gpio
, data
, 1);
76 return pca9698_write40(addr
, PCA9698_REG_CONFIG
, data
);
79 int pca9698_direction_output(u8 addr
, unsigned gpio
, int value
)
81 u8 data
[PCA9698_BUFFER_SIZE
];
84 res
= pca9698_set_value(addr
, gpio
, value
);
88 res
= pca9698_read40(addr
, PCA9698_REG_CONFIG
, data
);
92 pca9698_set_bit(gpio
, data
, 0);
94 return pca9698_write40(addr
, PCA9698_REG_CONFIG
, data
);
97 int pca9698_get_value(u8 addr
, unsigned gpio
)
99 unsigned config_byte
= gpio
/ 8;
100 unsigned config_bit
= gpio
% 8;
102 u8 data
[PCA9698_BUFFER_SIZE
];
105 res
= pca9698_read40(addr
, PCA9698_REG_INPUT
, data
);
109 value
= data
[config_byte
] & (1 << config_bit
);
114 int pca9698_set_value(u8 addr
, unsigned gpio
, int value
)
116 u8 data
[PCA9698_BUFFER_SIZE
];
119 res
= pca9698_read40(addr
, PCA9698_REG_OUTPUT
, data
);
123 pca9698_set_bit(gpio
, data
, value
);
125 return pca9698_write40(addr
, PCA9698_REG_OUTPUT
, data
);