]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/gpio/pca9698.c
3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
5 * SPDX-License-Identifier: GPL-2.0+
9 * Driver for NXP's pca9698 40 bit I2C gpio expander
14 #include <linux/errno.h>
18 * The pca9698 registers
21 #define PCA9698_REG_INPUT 0x00
22 #define PCA9698_REG_OUTPUT 0x08
23 #define PCA9698_REG_POLARITY 0x10
24 #define PCA9698_REG_CONFIG 0x18
26 #define PCA9698_BUFFER_SIZE 5
27 #define PCA9698_GPIO_COUNT 40
29 static int pca9698_read40(u8 addr
, u8 offset
, u8
*buffer
)
31 u8 command
= offset
| 0x80; /* autoincrement */
33 return i2c_read(addr
, command
, 1, buffer
, PCA9698_BUFFER_SIZE
);
36 static int pca9698_write40(u8 addr
, u8 offset
, u8
*buffer
)
38 u8 command
= offset
| 0x80; /* autoincrement */
40 return i2c_write(addr
, command
, 1, buffer
, PCA9698_BUFFER_SIZE
);
43 static void pca9698_set_bit(unsigned gpio
, u8
*buffer
, unsigned value
)
45 unsigned byte
= gpio
/ 8;
46 unsigned bit
= gpio
% 8;
49 buffer
[byte
] |= (1 << bit
);
51 buffer
[byte
] &= ~(1 << bit
);
54 int pca9698_request(unsigned gpio
, const char *label
)
56 if (gpio
>= PCA9698_GPIO_COUNT
)
62 void pca9698_free(unsigned gpio
)
66 int pca9698_direction_input(u8 addr
, unsigned gpio
)
68 u8 data
[PCA9698_BUFFER_SIZE
];
71 res
= pca9698_read40(addr
, PCA9698_REG_CONFIG
, data
);
75 pca9698_set_bit(gpio
, data
, 1);
77 return pca9698_write40(addr
, PCA9698_REG_CONFIG
, data
);
80 int pca9698_direction_output(u8 addr
, unsigned gpio
, int value
)
82 u8 data
[PCA9698_BUFFER_SIZE
];
85 res
= pca9698_set_value(addr
, gpio
, value
);
89 res
= pca9698_read40(addr
, PCA9698_REG_CONFIG
, data
);
93 pca9698_set_bit(gpio
, data
, 0);
95 return pca9698_write40(addr
, PCA9698_REG_CONFIG
, data
);
98 int pca9698_get_value(u8 addr
, unsigned gpio
)
100 unsigned config_byte
= gpio
/ 8;
101 unsigned config_bit
= gpio
% 8;
103 u8 data
[PCA9698_BUFFER_SIZE
];
106 res
= pca9698_read40(addr
, PCA9698_REG_INPUT
, data
);
110 value
= data
[config_byte
] & (1 << config_bit
);
115 int pca9698_set_value(u8 addr
, unsigned gpio
, int value
)
117 u8 data
[PCA9698_BUFFER_SIZE
];
120 res
= pca9698_read40(addr
, PCA9698_REG_OUTPUT
, data
);
124 pca9698_set_bit(gpio
, data
, value
);
126 return pca9698_write40(addr
, PCA9698_REG_OUTPUT
, data
);