gpio: tc3589x: implement open drain/source callback
[linux-2.6-microblaze.git] / drivers / gpio / gpio-tc3589x.c
index 2845653..15552fd 100644 (file)
@@ -85,6 +85,46 @@ static int tc3589x_gpio_direction_input(struct gpio_chip *chip,
        return tc3589x_set_bits(tc3589x, reg, BIT(pos), 0);
 }
 
+static int tc3589x_gpio_single_ended(struct gpio_chip *chip,
+                                    unsigned offset,
+                                    enum single_ended_mode mode)
+{
+       struct tc3589x_gpio *tc3589x_gpio = gpiochip_get_data(chip);
+       struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
+       /*
+        * These registers are alterated at each second address
+        * ODM bit 0 = drive to GND or Hi-Z (open drain)
+        * ODM bit 1 = drive to VDD or Hi-Z (open source)
+        */
+       u8 odmreg = TC3589x_GPIOODM0 + (offset / 8) * 2;
+       u8 odereg = TC3589x_GPIOODE0 + (offset / 8) * 2;
+       unsigned pos = offset % 8;
+       int ret;
+
+       switch(mode) {
+       case LINE_MODE_OPEN_DRAIN:
+               /* Set open drain mode */
+               ret = tc3589x_set_bits(tc3589x, odmreg, BIT(pos), 0);
+               if (ret)
+                       return ret;
+               /* Enable open drain/source mode */
+               return tc3589x_set_bits(tc3589x, odereg, BIT(pos), BIT(pos));
+       case LINE_MODE_OPEN_SOURCE:
+               /* Set open source mode */
+               ret = tc3589x_set_bits(tc3589x, odmreg, BIT(pos), BIT(pos));
+               if (ret)
+                       return ret;
+               /* Enable open drain/source mode */
+               return tc3589x_set_bits(tc3589x, odereg, BIT(pos), BIT(pos));
+       case LINE_MODE_PUSH_PULL:
+               /* Disable open drain/source mode */
+               return tc3589x_set_bits(tc3589x, odereg, BIT(pos), 0);
+       default:
+               break;
+       }
+       return -ENOTSUPP;
+}
+
 static struct gpio_chip template_chip = {
        .label                  = "tc3589x",
        .owner                  = THIS_MODULE,
@@ -92,6 +132,7 @@ static struct gpio_chip template_chip = {
        .get                    = tc3589x_gpio_get,
        .direction_output       = tc3589x_gpio_direction_output,
        .set                    = tc3589x_gpio_set,
+       .set_single_ended       = tc3589x_gpio_single_ended,
        .can_sleep              = true,
 };