/* * The Device Configuration and UART Configuration Registers * for each UART channel take 1KB of memory address space.
*/ #define EXAR_UART_CHANNEL_SIZE 0x400
#define DRIVER_NAME "gpio_exar"
static DEFINE_IDA(ida_index);
struct exar_gpio_chip { struct gpio_chip gpio_chip; struct regmap *regmap; int index; char name[20]; unsignedint first_pin; /* * The offset to the cascaded device's (if existing) * Device Configuration Registers.
*/ unsignedint cascaded_offset;
};
/* * regmap_write_bits() forces value to be written when an external * pull up/down might otherwise indicate value was already set.
*/ return regmap_write_bits(exar_gpio->regmap, addr, BIT(bit), bit_value);
}
staticint exar_direction_output(struct gpio_chip *chip, unsignedint offset, int value)
{ struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip); unsignedint addr = exar_offset_to_sel_addr(exar_gpio, offset); unsignedint bit = exar_offset_to_bit(exar_gpio, offset); int ret;
ret = exar_set_value(chip, offset, value); if (ret) return ret;
/* * The UART driver must have mapped region 0 prior to registering this * device - use it.
*/
p = pcim_iomap_table(pcidev)[0]; if (!p) return -ENOMEM;
ret = device_property_read_u32(dev, "exar,first-pin", &first_pin); if (ret) return ret;
ret = device_property_read_u32(dev, "ngpios", &ngpios); if (ret) return ret;
exar_gpio = devm_kzalloc(dev, sizeof(*exar_gpio), GFP_KERNEL); if (!exar_gpio) return -ENOMEM;
/* * If cascaded, secondary xr17v354 or xr17v358 have the same amount * of MPIOs as their primaries and the last 4 bits of the primary's * PCI Device ID is the number of its UART channels.
*/ if (pcidev->device & GENMASK(15, 12)) {
ngpios += ngpios;
exar_gpio->cascaded_offset = (pcidev->device & GENMASK(3, 0)) *
EXAR_UART_CHANNEL_SIZE;
}
/* * We don't need to check the return values of mmio regmap operations (unless * the regmap has a clock attached which is not the case here).
*/
exar_gpio->regmap = devm_regmap_init_mmio(dev, p, &exar_regmap_config); if (IS_ERR(exar_gpio->regmap)) return PTR_ERR(exar_gpio->regmap);
index = ida_alloc(&ida_index, GFP_KERNEL); if (index < 0) return index;
ret = devm_add_action_or_reset(dev, exar_devm_ida_free, exar_gpio); if (ret) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.