gpio: mockup: add set_config to support pull up/down
Add support for the pull up/down state set via gpiolib line requests to be reflected in the state of the mockup. Use case is for testing of the GPIO uAPI, specifically the pull up/down flags. Signed-off-by: Kent Gibson <warthog618@gmail.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This commit is contained in:
parent
2821ae5f30
commit
64e7112ee3
|
@ -141,6 +141,61 @@ static void gpio_mockup_set_multiple(struct gpio_chip *gc,
|
|||
mutex_unlock(&chip->lock);
|
||||
}
|
||||
|
||||
static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
|
||||
unsigned int offset, int value)
|
||||
{
|
||||
struct gpio_desc *desc;
|
||||
struct gpio_chip *gc;
|
||||
struct irq_sim *sim;
|
||||
int curr, irq, irq_type;
|
||||
|
||||
gc = &chip->gc;
|
||||
desc = &gc->gpiodev->descs[offset];
|
||||
sim = &chip->irqsim;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
if (test_bit(FLAG_REQUESTED, &desc->flags) &&
|
||||
!test_bit(FLAG_IS_OUT, &desc->flags)) {
|
||||
curr = __gpio_mockup_get(chip, offset);
|
||||
if (curr == value)
|
||||
goto out;
|
||||
|
||||
irq = irq_sim_irqnum(sim, offset);
|
||||
irq_type = irq_get_trigger_type(irq);
|
||||
|
||||
if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
|
||||
(value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
|
||||
irq_sim_fire(sim, offset);
|
||||
}
|
||||
|
||||
/* Change the value unless we're actively driving the line. */
|
||||
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
|
||||
!test_bit(FLAG_IS_OUT, &desc->flags))
|
||||
__gpio_mockup_set(chip, offset, value);
|
||||
|
||||
out:
|
||||
chip->lines[offset].pull = value;
|
||||
mutex_unlock(&chip->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_mockup_set_config(struct gpio_chip *gc,
|
||||
unsigned int offset, unsigned long config)
|
||||
{
|
||||
struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
|
||||
|
||||
switch (pinconf_to_config_param(config)) {
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
return gpio_mockup_apply_pull(chip, offset, 1);
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
return gpio_mockup_apply_pull(chip, offset, 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static int gpio_mockup_dirout(struct gpio_chip *gc,
|
||||
unsigned int offset, int value)
|
||||
{
|
||||
|
@ -221,12 +276,8 @@ static ssize_t gpio_mockup_debugfs_write(struct file *file,
|
|||
size_t size, loff_t *ppos)
|
||||
{
|
||||
struct gpio_mockup_dbgfs_private *priv;
|
||||
int rv, val, curr, irq, irq_type;
|
||||
struct gpio_mockup_chip *chip;
|
||||
int rv, val;
|
||||
struct seq_file *sfile;
|
||||
struct gpio_desc *desc;
|
||||
struct gpio_chip *gc;
|
||||
struct irq_sim *sim;
|
||||
|
||||
if (*ppos != 0)
|
||||
return -EINVAL;
|
||||
|
@ -239,35 +290,9 @@ static ssize_t gpio_mockup_debugfs_write(struct file *file,
|
|||
|
||||
sfile = file->private_data;
|
||||
priv = sfile->private;
|
||||
chip = priv->chip;
|
||||
gc = &chip->gc;
|
||||
desc = &gc->gpiodev->descs[priv->offset];
|
||||
sim = &chip->irqsim;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
if (test_bit(FLAG_REQUESTED, &desc->flags) &&
|
||||
!test_bit(FLAG_IS_OUT, &desc->flags)) {
|
||||
curr = __gpio_mockup_get(chip, priv->offset);
|
||||
if (curr == val)
|
||||
goto out;
|
||||
|
||||
irq = irq_sim_irqnum(sim, priv->offset);
|
||||
irq_type = irq_get_trigger_type(irq);
|
||||
|
||||
if ((val == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
|
||||
(val == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
|
||||
irq_sim_fire(sim, priv->offset);
|
||||
}
|
||||
|
||||
/* Change the value unless we're actively driving the line. */
|
||||
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
|
||||
!test_bit(FLAG_IS_OUT, &desc->flags))
|
||||
__gpio_mockup_set(chip, priv->offset, val);
|
||||
|
||||
out:
|
||||
chip->lines[priv->offset].pull = val;
|
||||
mutex_unlock(&chip->lock);
|
||||
rv = gpio_mockup_apply_pull(priv->chip, priv->offset, val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -413,6 +438,7 @@ static int gpio_mockup_probe(struct platform_device *pdev)
|
|||
gc->direction_output = gpio_mockup_dirout;
|
||||
gc->direction_input = gpio_mockup_dirin;
|
||||
gc->get_direction = gpio_mockup_get_direction;
|
||||
gc->set_config = gpio_mockup_set_config;
|
||||
gc->to_irq = gpio_mockup_to_irq;
|
||||
gc->free = gpio_mockup_free;
|
||||
|
||||
|
|
Loading…
Reference in a new issue