^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * RDC321x MFD southbridge driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mfd/rdc321x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static struct rdc321x_wdt_pdata rdc321x_wdt_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static struct resource rdc321x_wdt_resource[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .name = "wdt-reg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .start = RDC321X_WDT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .end = RDC321X_WDT_CTRL + 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .flags = IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .max_gpios = RDC321X_NUM_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct resource rdc321x_gpio_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .name = "gpio-reg1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .start = RDC321X_GPIO_CTRL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .end = RDC321X_GPIO_CTRL_REG1 + 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .flags = IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .name = "gpio-reg2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .start = RDC321X_GPIO_CTRL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .end = RDC321X_GPIO_CTRL_REG2 + 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .flags = IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static const struct mfd_cell rdc321x_sb_cells[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .name = "rdc321x-wdt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .resources = rdc321x_wdt_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .num_resources = ARRAY_SIZE(rdc321x_wdt_resource),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .platform_data = &rdc321x_wdt_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .pdata_size = sizeof(rdc321x_wdt_pdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .name = "rdc321x-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .resources = rdc321x_gpio_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .num_resources = ARRAY_SIZE(rdc321x_gpio_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .platform_data = &rdc321x_gpio_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .pdata_size = sizeof(rdc321x_gpio_pdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int rdc321x_sb_probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dev_err(&pdev->dev, "failed to enable device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) rdc321x_gpio_pdata.sb_pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) rdc321x_wdt_pdata.sb_pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return devm_mfd_add_devices(&pdev->dev, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) rdc321x_sb_cells,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ARRAY_SIZE(rdc321x_sb_cells),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) NULL, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static const struct pci_device_id rdc321x_sb_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MODULE_DEVICE_TABLE(pci, rdc321x_sb_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct pci_driver rdc321x_sb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .name = "RDC321x Southbridge",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .id_table = rdc321x_sb_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .probe = rdc321x_sb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) module_pci_driver(rdc321x_sb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");