Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1636)

Unified Diff: drivers/gpio/nm10_gpio.c

Issue 3333016: Add ability to change gpio directions. (Closed) Base URL: http://git.chromium.org/git/kernel.git
Patch Set: Add support to change of GPIO pins' directions to NM10 driver. Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: drivers/gpio/nm10_gpio.c
diff --git a/drivers/gpio/nm10_gpio.c b/drivers/gpio/nm10_gpio.c
index 2802f55a286eb3afd3cee9e1419303fe64ab528f..2250f6e85de6b9695de6296a47ab6e2734460ac8 100644
--- a/drivers/gpio/nm10_gpio.c
+++ b/drivers/gpio/nm10_gpio.c
@@ -95,6 +95,41 @@ struct nm10_gpio {
};
/**
+ * nm10_get_parameters() - get value of a GPIO bit
+ *
+ * Inputs:
+ * @chip: generic gpio chip handle associated with this module
+ * @offset: zero based GPIO bit number (in this controller's scope).
+ *
+ * Outputs:
+ * @psection - pointer to the NM10 section number containing bit offset
+ * @pbit,- pointer to the offset's bit mask within the section
+ * @pgpio - pointer to address of this nm10_gpio instance.
+ *
+ * Returns zero on errors or nonzero on success.
+ */
+static int nm10_get_parameters(struct gpio_chip *chip, unsigned offset,
+ u8* psection, u32* pbit,
+ struct nm10_gpio **pgpio)
Olof Johansson 2010/09/03 19:35:14 I would prefer having a couple of macros instead o
+{
+ *pgpio = container_of(chip, struct nm10_gpio, chip);
+
+ *psection = offset / NM10_GPIO_BITS_PER_SECTION;
+ *pbit = BIT(offset % NM10_GPIO_BITS_PER_SECTION);
+
+ if (*psection >= NM10_GPIO_SECTIONS) {
+ printk(KERN_ERR "%s: bad offset %d\n",
+ gpio_driver_name, offset);
+ return 0;
+ }
+
+ if (!(*pbit & (*pgpio)->cached_select[*psection])) {
+ return 0; /* this bit is not used for GPIO */
+ }
+ return ~0;
+}
+
+/**
* nm10_gpio_get() - get value of a GPIO bit
* @chip: generic gpio chip handle associated with this module
* @offset: zero based GPIO bit number (in this controller's scope).
@@ -109,26 +144,19 @@ static int nm10_gpio_get(struct gpio_chip *chip, unsigned offset)
u32 bit;
struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
- section = offset / NM10_GPIO_BITS_PER_SECTION;
- bit = BIT(offset % NM10_GPIO_BITS_PER_SECTION);
-
- if (section >= NM10_GPIO_SECTIONS) {
- printk(KERN_ERR "%s: bad offset %d\n",
- gpio_driver_name, offset);
+ if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
return 0;
}
- if (!(bit & pgpio->cached_select[section])) {
- return 0; /* this bit is not used for GPIO */
- }
return inl(pgpio->io_base +
nm10_gpio_sections[section].io_level_offset) & bit;
}
/**
- * nm10_gpio_set() - get value of a GPIO bit
+ * nm10_gpio_set() - set value of a GPIO bit
* @chip: generic gpio chip handle associated with this module
* @offset: zero based GPIO bit number (in this controller's scope).
+ * @value: the value to set the output to
*
* If the offset is of a valid bit (used for GPIO output) - the bit state is
* changed to reflect the value. All other in range offset values are ignored.
@@ -138,19 +166,11 @@ static void nm10_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
u8 section;
u32 bit;
const struct nm10_gpio_info *pinfo;
- struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
+ struct nm10_gpio *pgpio;
u32 gpio_reg_value;
- section = offset / NM10_GPIO_BITS_PER_SECTION;
- bit = BIT(offset % NM10_GPIO_BITS_PER_SECTION);
-
- if (section >= NM10_GPIO_SECTIONS) {
- printk(KERN_ERR "%s: bad offset %d\n",
- gpio_driver_name, offset);
- }
-
- if (!(bit & pgpio->cached_select[section])) {
- return; /* this bit is not used for GPIO */
+ if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
+ return;
}
pinfo = nm10_gpio_sections + section;
@@ -168,6 +188,55 @@ static void nm10_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
outl(gpio_reg_value, pgpio->io_base + pinfo->io_level_offset);
}
+/**
+ * nm10_gpio_direction_inp() configure signal "offset" as input, or return error
+ * @chip: generic gpio chip handle associated with this module
+ * @offset: zero based GPIO bit number (in this controller's scope).
+ */
+static int nm10_gpio_direction_inp(struct gpio_chip *chip,
+ unsigned offset)
+{
+ u8 section;
+ u32 bit;
+ struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
+ u32 io_select_offset;
+
+ if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
+ return -1;
+ }
+
+ io_select_offset = pgpio->io_base +
+ nm10_gpio_sections[section].io_select_offset;
+ outl(inl(io_select_offset) | bit, io_select_offset);
+ return 0;
+}
+
+/**
+ * nm10_gpio_direction_out() configure signal "offset" as output,
+ * or return error
+ * @chip: generic gpio chip handle associated with this module
+ * @offset: zero based GPIO bit number (in this controller's scope).
+ * @value: the value to set the output to
+ */
+static int nm10_gpio_direction_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ u8 section;
+ u32 bit;
+ struct nm10_gpio *pgpio = container_of(chip, struct nm10_gpio, chip);
+ u32 io_select_offset;
+
+ if (!nm10_get_parameters(chip, offset, &section, &bit, &pgpio)) {
+ return -1;
+ }
+
+ io_select_offset = pgpio->io_base +
+ nm10_gpio_sections[section].io_select_offset;
+ outl(inl(io_select_offset) & ~bit, io_select_offset);
+ nm10_gpio_set(chip, offset, value);
+ return 0;
+}
+
static int __devinit nm10_gpio_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -213,6 +282,8 @@ static int __devinit nm10_gpio_probe(struct pci_dev *pdev,
pgpio->chip.label = dev_name(&pdev->dev);
pgpio->chip.get = nm10_gpio_get;
pgpio->chip.set = nm10_gpio_set;
+ pgpio->chip.direction_input = nm10_gpio_direction_inp;
+ pgpio->chip.direction_output = nm10_gpio_direction_out;
pgpio->chip.ngpio = NM10_MAX_GPIO_BITS;
pgpio->chip.can_sleep = 0;
pci_set_drvdata(pdev, pgpio);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698