cregit-Linux how code gets into the kernel

Release 4.7 drivers/gpio/gpio-wm8994.c

Directory: drivers/gpio
/*
 * gpiolib support for Wolfson WM8994
 *
 * Copyright 2009 Wolfson Microelectronics PLC.
 *
 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/mfd/core.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <linux/regmap.h>

#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/mfd/wm8994/gpio.h>
#include <linux/mfd/wm8994/registers.h>


struct wm8994_gpio {
	
struct wm8994 *wm8994;
	
struct gpio_chip gpio_chip;
};


static int wm8994_gpio_request(struct gpio_chip *chip, unsigned offset) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; switch (wm8994->type) { case WM8958: switch (offset) { case 1: case 2: case 3: case 4: case 6: return -EINVAL; } break; default: break; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown7498.67%150.00%
linus walleijlinus walleij11.33%150.00%
Total75100.00%2100.00%


static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_DIR, WM8994_GPN_DIR); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown4697.87%150.00%
linus walleijlinus walleij12.13%150.00%
Total47100.00%2100.00%


static int wm8994_gpio_get(struct gpio_chip *chip, unsigned offset) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; int ret; ret = wm8994_reg_read(wm8994, WM8994_GPIO_1 + offset); if (ret < 0) return ret; if (ret & WM8994_GPN_LVL) return 1; else return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown6898.55%150.00%
linus walleijlinus walleij11.45%150.00%
Total69100.00%2100.00%


static int wm8994_gpio_direction_out(struct gpio_chip *chip, unsigned offset, int value) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; if (value) value = WM8994_GPN_LVL; return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_DIR | WM8994_GPN_LVL, value); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown5998.33%266.67%
linus walleijlinus walleij11.67%133.33%
Total60100.00%3100.00%


static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; if (value) value = WM8994_GPN_LVL; wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown5698.25%150.00%
linus walleijlinus walleij11.75%150.00%
Total57100.00%2100.00%


static int wm8994_gpio_set_single_ended(struct gpio_chip *chip, unsigned int offset, enum single_ended_mode mode) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; switch (mode) { case LINE_MODE_OPEN_DRAIN: return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_OP_CFG_MASK, WM8994_GPN_OP_CFG); case LINE_MODE_PUSH_PULL: return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_OP_CFG_MASK, 0); default: break; } return -ENOTSUPP; }

Contributors

PersonTokensPropCommitsCommitProp
linus walleijlinus walleij84100.00%1100.00%
Total84100.00%1100.00%


static int wm8994_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; return regmap_irq_get_virq(wm8994->irq_data, offset); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown4297.67%266.67%
linus walleijlinus walleij12.33%133.33%
Total43100.00%3100.00%

#ifdef CONFIG_DEBUG_FS
static const char *wm8994_gpio_fn(u16 fn) { switch (fn) { case WM8994_GP_FN_PIN_SPECIFIC: return "pin-specific"; case WM8994_GP_FN_GPIO: return "GPIO"; case WM8994_GP_FN_SDOUT: return "SDOUT"; case WM8994_GP_FN_IRQ: return "IRQ"; case WM8994_GP_FN_TEMPERATURE: return "Temperature"; case WM8994_GP_FN_MICBIAS1_DET: return "MICBIAS1 detect"; case WM8994_GP_FN_MICBIAS1_SHORT: return "MICBIAS1 short"; case WM8994_GP_FN_MICBIAS2_DET: return "MICBIAS2 detect"; case WM8994_GP_FN_MICBIAS2_SHORT: return "MICBIAS2 short"; case WM8994_GP_FN_FLL1_LOCK: return "FLL1 lock"; case WM8994_GP_FN_FLL2_LOCK: return "FLL2 lock"; case WM8994_GP_FN_SRC1_LOCK: return "SRC1 lock"; case WM8994_GP_FN_SRC2_LOCK: return "SRC2 lock"; case WM8994_GP_FN_DRC1_ACT: return "DRC1 activity"; case WM8994_GP_FN_DRC2_ACT: return "DRC2 activity"; case WM8994_GP_FN_DRC3_ACT: return "DRC3 activity"; case WM8994_GP_FN_WSEQ_STATUS: return "Write sequencer"; case WM8994_GP_FN_FIFO_ERROR: return "FIFO error"; case WM8994_GP_FN_OPCLK: return "OPCLK"; case WM8994_GP_FN_THW: return "Thermal warning"; case WM8994_GP_FN_DCS_DONE: return "DC servo"; case WM8994_GP_FN_FLL1_OUT: return "FLL1 output"; case WM8994_GP_FN_FLL2_OUT: return "FLL1 output"; default: return "Unknown"; } }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown159100.00%1100.00%
Total159100.00%1100.00%


static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct wm8994_gpio *wm8994_gpio = gpiochip_get_data(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; int i; for (i = 0; i < chip->ngpio; i++) { int gpio = i + chip->base; int reg; const char *label; /* We report the GPIO even if it's not requested since * we're also reporting things like alternate * functions which apply even when the GPIO is not in * use as a GPIO. */ label = gpiochip_is_requested(chip, i); if (!label) label = "Unrequested"; seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label); reg = wm8994_reg_read(wm8994, WM8994_GPIO_1 + i); if (reg < 0) { dev_err(wm8994->dev, "GPIO control %d read failed: %d\n", gpio, reg); seq_printf(s, "\n"); continue; } if (reg & WM8994_GPN_DIR) seq_printf(s, "in "); else seq_printf(s, "out "); if (reg & WM8994_GPN_PU) seq_printf(s, "pull up "); if (reg & WM8994_GPN_PD) seq_printf(s, "pull down "); if (reg & WM8994_GPN_POL) seq_printf(s, "inverted "); else seq_printf(s, "noninverted "); if (reg & WM8994_GPN_OP_CFG) seq_printf(s, "open drain "); else seq_printf(s, "push-pull "); seq_printf(s, "%s (%x)\n", wm8994_gpio_fn(reg & WM8994_GPN_FN_MASK), reg); } }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown24599.19%250.00%
linus walleijlinus walleij20.81%250.00%
Total247100.00%4100.00%

#else #define wm8994_gpio_dbg_show NULL #endif static struct gpio_chip template_chip = { .label = "wm8994", .owner = THIS_MODULE, .request = wm8994_gpio_request, .direction_input = wm8994_gpio_direction_in, .get = wm8994_gpio_get, .direction_output = wm8994_gpio_direction_out, .set = wm8994_gpio_set, .set_single_ended = wm8994_gpio_set_single_ended, .to_irq = wm8994_gpio_to_irq, .dbg_show = wm8994_gpio_dbg_show, .can_sleep = true, };
static int wm8994_gpio_probe(struct platform_device *pdev) { struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent); struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev); struct wm8994_gpio *wm8994_gpio; int ret; wm8994_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm8994_gpio), GFP_KERNEL); if (wm8994_gpio == NULL) return -ENOMEM; wm8994_gpio->wm8994 = wm8994; wm8994_gpio->gpio_chip = template_chip; wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX; wm8994_gpio->gpio_chip.parent = &pdev->dev; if (pdata && pdata->gpio_base) wm8994_gpio->gpio_chip.base = pdata->gpio_base; else wm8994_gpio->gpio_chip.base = -1; ret = devm_gpiochip_add_data(&pdev->dev, &wm8994_gpio->gpio_chip, wm8994_gpio); if (ret < 0) { dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); return ret; } platform_set_drvdata(pdev, wm8994_gpio); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown16590.66%228.57%
laxman dewanganlaxman dewangan94.95%114.29%
linus walleijlinus walleij31.65%228.57%
jingoo hanjingoo han31.65%114.29%
abdoulaye bertheabdoulaye berthe21.10%114.29%
Total182100.00%7100.00%

static struct platform_driver wm8994_gpio_driver = { .driver.name = "wm8994-gpio", .driver.owner = THIS_MODULE, .probe = wm8994_gpio_probe, };
static int __init wm8994_gpio_init(void) { return platform_driver_register(&wm8994_gpio_driver); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown16100.00%1100.00%
Total16100.00%1100.00%

subsys_initcall(wm8994_gpio_init);
static void __exit wm8994_gpio_exit(void) { platform_driver_unregister(&wm8994_gpio_driver); }

Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown15100.00%1100.00%
Total15100.00%1100.00%

module_exit(wm8994_gpio_exit); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_DESCRIPTION("GPIO interface for WM8994"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:wm8994-gpio");

Overall Contributors

PersonTokensPropCommitsCommitProp
mark brownmark brown111590.36%847.06%
linus walleijlinus walleij1018.18%423.53%
laxman dewanganlaxman dewangan90.73%15.88%
tejun heotejun heo30.24%15.88%
jingoo hanjingoo han30.24%15.88%
abdoulaye bertheabdoulaye berthe20.16%15.88%
grant likelygrant likely10.08%15.88%
Total1234100.00%17100.00%
Directory: drivers/gpio
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}