linux/drivers/gpio/gpio-hlwd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// Copyright (C) 2008-2009 The GameCube Linux Team
   3// Copyright (C) 2008,2009 Albert Herranz
   4// Copyright (C) 2017-2018 Jonathan Neuschäfer
   5//
   6// Nintendo Wii (Hollywood) GPIO driver
   7
   8#include <linux/gpio/driver.h>
   9#include <linux/io.h>
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/of.h>
  13#include <linux/of_platform.h>
  14#include <linux/slab.h>
  15
  16/*
  17 * Register names and offsets courtesy of WiiBrew:
  18 * https://wiibrew.org/wiki/Hardware/Hollywood_GPIOs
  19 *
  20 * Note that for most registers, there are two versions:
  21 * - HW_GPIOB_* Is always accessible by the Broadway PowerPC core, but does
  22 *   always give access to all GPIO lines
  23 * - HW_GPIO_* Is only accessible by the Broadway PowerPC code if the memory
  24 *   firewall (AHBPROT) in the Hollywood chipset has been configured to allow
  25 *   such access.
  26 *
  27 * The ownership of each GPIO line can be configured in the HW_GPIO_OWNER
  28 * register: A one bit configures the line for access via the HW_GPIOB_*
  29 * registers, a zero bit indicates access via HW_GPIO_*. This driver uses
  30 * HW_GPIOB_*.
  31 */
  32#define HW_GPIOB_OUT            0x00
  33#define HW_GPIOB_DIR            0x04
  34#define HW_GPIOB_IN             0x08
  35#define HW_GPIOB_INTLVL         0x0c
  36#define HW_GPIOB_INTFLAG        0x10
  37#define HW_GPIOB_INTMASK        0x14
  38#define HW_GPIOB_INMIR          0x18
  39#define HW_GPIO_ENABLE          0x1c
  40#define HW_GPIO_OUT             0x20
  41#define HW_GPIO_DIR             0x24
  42#define HW_GPIO_IN              0x28
  43#define HW_GPIO_INTLVL          0x2c
  44#define HW_GPIO_INTFLAG         0x30
  45#define HW_GPIO_INTMASK         0x34
  46#define HW_GPIO_INMIR           0x38
  47#define HW_GPIO_OWNER           0x3c
  48
  49struct hlwd_gpio {
  50        struct gpio_chip gpioc;
  51        void __iomem *regs;
  52};
  53
  54static int hlwd_gpio_probe(struct platform_device *pdev)
  55{
  56        struct hlwd_gpio *hlwd;
  57        struct resource *regs_resource;
  58        u32 ngpios;
  59        int res;
  60
  61        hlwd = devm_kzalloc(&pdev->dev, sizeof(*hlwd), GFP_KERNEL);
  62        if (!hlwd)
  63                return -ENOMEM;
  64
  65        regs_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  66        hlwd->regs = devm_ioremap_resource(&pdev->dev, regs_resource);
  67        if (IS_ERR(hlwd->regs))
  68                return PTR_ERR(hlwd->regs);
  69
  70        /*
  71         * Claim all GPIOs using the OWNER register. This will not work on
  72         * systems where the AHBPROT memory firewall hasn't been configured to
  73         * permit PPC access to HW_GPIO_*.
  74         *
  75         * Note that this has to happen before bgpio_init reads the
  76         * HW_GPIOB_OUT and HW_GPIOB_DIR, because otherwise it reads the wrong
  77         * values.
  78         */
  79        iowrite32be(0xffffffff, hlwd->regs + HW_GPIO_OWNER);
  80
  81        res = bgpio_init(&hlwd->gpioc, &pdev->dev, 4,
  82                        hlwd->regs + HW_GPIOB_IN, hlwd->regs + HW_GPIOB_OUT,
  83                        NULL, hlwd->regs + HW_GPIOB_DIR, NULL,
  84                        BGPIOF_BIG_ENDIAN_BYTE_ORDER);
  85        if (res < 0) {
  86                dev_warn(&pdev->dev, "bgpio_init failed: %d\n", res);
  87                return res;
  88        }
  89
  90        res = of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios);
  91        if (res)
  92                ngpios = 32;
  93        hlwd->gpioc.ngpio = ngpios;
  94
  95        return devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
  96}
  97
  98static const struct of_device_id hlwd_gpio_match[] = {
  99        { .compatible = "nintendo,hollywood-gpio", },
 100        {},
 101};
 102MODULE_DEVICE_TABLE(of, hlwd_gpio_match);
 103
 104static struct platform_driver hlwd_gpio_driver = {
 105        .driver = {
 106                .name           = "gpio-hlwd",
 107                .of_match_table = hlwd_gpio_match,
 108        },
 109        .probe  = hlwd_gpio_probe,
 110};
 111module_platform_driver(hlwd_gpio_driver);
 112
 113MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>");
 114MODULE_DESCRIPTION("Nintendo Wii GPIO driver");
 115MODULE_LICENSE("GPL");
 116