struct qe_pin { /* * The qe_gpio_chip name is unfortunate, we should change that to * something like qe_pio_controller. Someday.
*/ struct qe_gpio_chip *controller; int num;
};
/** * qe_pin_request - Request a QE pin * @dev: device to get the pin from * @index: index of the pin in the device tree * Context: non-atomic * * This function return qe_pin so that you could use it with the rest of * the QE Pin Multiplexing API.
*/ struct qe_pin *qe_pin_request(struct device *dev, int index)
{ struct qe_pin *qe_pin; struct gpio_chip *gc; struct gpio_desc *gpiod; int gpio_num; int err;
/* * Request gpio as nonexclusive as it was likely reserved by the * caller, and we are not planning on controlling it, we only need * the descriptor to the to the gpio chip structure.
*/
gpiod = gpiod_get_index(dev, NULL, index,
GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
err = PTR_ERR_OR_ZERO(gpiod); if (err) goto err0;
gc = gpiod_to_chip(gpiod);
gpio_num = desc_to_gpio(gpiod); /* We no longer need this descriptor */
gpiod_put(gpiod);
if (WARN_ON(!gc)) {
err = -ENODEV; goto err0;
}
qe_pin->controller = gpiochip_get_data(gc); /* * FIXME: this gets the local offset on the gpio_chip so that the driver * can manipulate pin control settings through its custom API. The real * solution is to create a real pin control driver for this.
*/
qe_pin->num = gpio_num - gc->base;
if (!fwnode_device_is_compatible(gc->fwnode, "fsl,mpc8323-qe-pario-bank")) {
dev_dbg(dev, "%s: tried to get a non-qe pin\n", __func__);
err = -EINVAL; goto err0;
} return qe_pin;
err0:
kfree(qe_pin);
dev_dbg(dev, "%s failed with status %d\n", __func__, err); return ERR_PTR(err);
}
EXPORT_SYMBOL(qe_pin_request);
/** * qe_pin_free - Free a pin * @qe_pin: pointer to the qe_pin structure * Context: any * * This function frees the qe_pin structure and makes a pin available * for further qe_pin_request() calls.
*/ void qe_pin_free(struct qe_pin *qe_pin)
{
kfree(qe_pin);
}
EXPORT_SYMBOL(qe_pin_free);
/** * qe_pin_set_dedicated - Revert a pin to a dedicated peripheral function mode * @qe_pin: pointer to the qe_pin structure * Context: any * * This function resets a pin to a dedicated peripheral function that * has been set up by the firmware.
*/ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
{ struct qe_gpio_chip *qe_gc = qe_pin->controller; struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; struct qe_pio_regs *sregs = &qe_gc->saved_regs; int pin = qe_pin->num;
u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1));
u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2); bool second_reg = pin > (QE_PIO_PINS / 2) - 1; unsignedlong flags;
/** * qe_pin_set_gpio - Set a pin to the GPIO mode * @qe_pin: pointer to the qe_pin structure * Context: any * * This function sets a pin to the GPIO mode.
*/ void qe_pin_set_gpio(struct qe_pin *qe_pin)
{ struct qe_gpio_chip *qe_gc = qe_pin->controller; struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs; unsignedlong flags;
spin_lock_irqsave(&qe_gc->lock, flags);
/* Let's make it input by default, GPIO API is able to change that. */
__par_io_config_pin(regs, qe_pin->num, QE_PIO_DIR_IN, 0, 0, 0);
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.