I got the old driver working with this patch:
--- gpio-fxl6408_toradex.c 2025-04-30 09:11:27.114399994 +0100
+++ gpio-fxl6408.c 2025-04-30 09:10:47.525653972 +0100
@@ -68,6 +68,7 @@
/* Caches of register values so we don't have to read-modify-write. */
u8 reg_io_dir;
u8 reg_output;
+ u8 reg_pullup;
};
static int fxl6408_gpio_direction_input(struct gpio_chip *gc, unsigned off)
@@ -148,6 +149,38 @@
mutex_unlock(&chip->i2c_lock);
}
+static int fxl6408_gpio_set_config(struct gpio_chip* gc, unsigned int off, unsigned long cfg)
+{
+ struct fxl6408_chip* chip = gpiochip_get_data(gc);
+ enum pin_config_param param = pinconf_to_config_param(cfg);
+
+ int ret;
+
+ mutex_lock(&chip->i2c_lock);
+
+ switch(param)
+ {
+ case PIN_CONFIG_BIAS_PULL_UP:
+ chip->reg_pullup |= BIT(off);
+ ret = i2c_smbus_write_byte_data(chip->client, FXL6408_PULL_UP, chip->reg_pullup);
+ // dev_info(&chip->client->dev, "FXL6408 setting PULLUP on %u - reg pullup %u - ret %d\n", off, chip->reg_pullup, ret);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ chip->reg_pullup &= ~BIT(off);
+ ret = i2c_smbus_write_byte_data(chip->client, FXL6408_PULL_UP, chip->reg_pullup);
+ // dev_info(&chip->client->dev, "FXL6408 setting PULLDOWN on %u - reg pullup %u - ret %d\n", off, chip->reg_pullup, ret);
+ break;
+ default:
+ ret = -ENOTSUPP;
+ // dev_info(&chip->client->dev, "FXL6408 unsupported param %d for off %u\n", param, off);
+ break;
+ }
+
+ mutex_unlock(&chip->i2c_lock);
+
+ return ret;
+}
+
static int fxl6408_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -184,7 +217,7 @@
chip->client = client;
mutex_init(&chip->i2c_lock);
- /* if configured, set initial output state and direction,
+ /* if configured, set initial output state, direction and pull-up state
* otherwise read them from the chip */
if (of_property_read_u32(dev->of_node, "inital_io_dir", &val)) {
chip->reg_io_dir = i2c_smbus_read_byte_data(client, FXL6408_IO_DIR);
@@ -198,6 +231,12 @@
chip->reg_output = val & 0xff;
i2c_smbus_write_byte_data(client, FXL6408_OUTPUT, chip->reg_output);
}
+ if (of_property_read_u32(dev->of_node, "inital_pullup", &val)) {
+ chip->reg_pullup = i2c_smbus_read_byte_data(client, FXL6408_PULL_UP);
+ } else {
+ chip->reg_pullup = val & 0xff;
+ i2c_smbus_write_byte_data(client, FXL6408_PULL_UP, chip->reg_pullup);
+ }
gc = &chip->gpio_chip;
gc->direction_input = fxl6408_gpio_direction_input;
@@ -206,6 +245,7 @@
gc->get = fxl6408_gpio_get_value;
gc->set = fxl6408_gpio_set_value;
gc->set_multiple = fxl6408_gpio_set_multiple;
+ gc->set_config = fxl6408_gpio_set_config;
gc->can_sleep = true;
gc->base =-1;