mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
intel-pinctrl for v5.6-1
* Tiger Lake appears to have _HID enumeration, thus driver has been updated * Coffee Lake-S has the same IP as Sunrisepoint, thus ID has been added * Baytrail has got more clean ups and bug fixes, such as direct IRQ handling * Lynxpoint GPIO has been converted to true pin control driver * The common driver now uses IRQ chip enumeration via GPIO chip The following is an automated git shortlog grouped by driver: baytrail: - Replace WARN with dev_info_once when setting direct-irq pin to output - Do not clear IRQ flags on direct-irq enabled pins - Reuse struct intel_pinctrl in the driver - Use local variable to keep device pointer - Keep pointer to struct device instead of its container - Use GPIO direction definitions - Move IRQ valid mask initialization to a dedicated callback - Group GPIO IRQ chip initialization - Allocate IRQ chip dynamic cherryview: - Use GPIO direction definitions intel: - Pass irqchip when adding gpiochip - Add GPIO <-> pin mapping ranges via callback - Share struct intel_pinctrl for wider use - Use GPIO direction definitions lynxpoint: - Update summary in the driver - Switch to pin control API - Add GPIO <-> pin mapping ranges via callback - Implement ->pin_dbg_show() - Add pin control operations - Reuse struct intel_pinctrl in the driver - Add pin control data structures - Implement intel_gpio_get_direction callback - Implement ->irq_ack() callback - Move ownership check to IRQ chip - Move lp_irq_type() closer to IRQ related routines - Move ->remove closer to ->probe() - Extract lp_gpio_acpi_use() for future use - Convert unsigned to unsigned int - Switch to memory mapped IO accessors - Keep pointer to struct device instead of its container - Relax GPIO request rules - Assume 2 bits for mode selector - Use standard pattern for memory allocation - Use %pR to print IO resource - Drop useless assignment - Correct amount of pins - Use raw_spinlock for locking - Move GPIO driver to pin controller folder sunrisepoint: - Add Coffee Lake-S ACPI ID - Add missing Interrupt Status register offset tigerlake: - Tiger Lake uses _HID enumeration -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqaflIX74DDDzMJJtb7wzTHR8rCgFAl4lfB4ACgkQb7wzTHR8 rCgy3g//VHTbsBk7+6NFXbI5iXgbU1sr9F9cIYbzawA3YLbR1Ioq9P89U3JPCeCz zaoxtd9HAxOxQrUFJGZKbsof6jS7Ee80mcvm0KQt2GNBmM4bZGS6qHofj5FAOxuz 4MBjGINrlIntzG1RqjYxD+p2xuQ3p9H2yQIds9UTM1NB+hBIDLPx+3HUM2qbbf4s rbLQRc+kmVHoapmse6lV4lA2OyOW9BmgiTxeMaua/E6zyZ6WVNXLxXx+yXrEtUjj Q9M6moNZd4OP3pN/mGCyClLTMFyOcmaah6wdXy3GJRZ7/YD5+AnqbVTGsYLKy6To 1w25Z6e6ygzbL8sqr5JwMiX9GnX6FeGEleY63zxvZ+WCC3TGWRzPWaTJuQIRToAz K3pdYWXOoK/J1fyzdjdkYHbqBbqjpB5oT/dWFx7Ii50kv41b8TEXPhDrWZSqvn9I J0KW/vICbsqPk8TBsQQ83nV6ILSTY5KakI8Qs5ngDov5oeKl0F/cLT9KqcY9nQdJ 2mhJU5mn8cq4SvtyPD/NSRQHxX5xHx6Yi4KG2cXw0wJTZ+jP8rpl2di8ogDCFUK4 fkQ/g+PhcPsW36kTKvLv57vhTqZ2u9rf9BcaJ7LGo9wsOjpGH6d4RCTiJ0VSn++T rkomWdFVgfMKmnsUwykyIV39mQzDy5e4vNO45wMs7LCimiRSkMA= =+ZAJ -----END PGP SIGNATURE----- Merge tag 'intel-pinctrl-v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into devel intel-pinctrl for v5.6-1 * Tiger Lake appears to have _HID enumeration, thus driver has been updated * Coffee Lake-S has the same IP as Sunrisepoint, thus ID has been added * Baytrail has got more clean ups and bug fixes, such as direct IRQ handling * Lynxpoint GPIO has been converted to true pin control driver * The common driver now uses IRQ chip enumeration via GPIO chip The following is an automated git shortlog grouped by driver: baytrail: - Replace WARN with dev_info_once when setting direct-irq pin to output - Do not clear IRQ flags on direct-irq enabled pins - Reuse struct intel_pinctrl in the driver - Use local variable to keep device pointer - Keep pointer to struct device instead of its container - Use GPIO direction definitions - Move IRQ valid mask initialization to a dedicated callback - Group GPIO IRQ chip initialization - Allocate IRQ chip dynamic cherryview: - Use GPIO direction definitions intel: - Pass irqchip when adding gpiochip - Add GPIO <-> pin mapping ranges via callback - Share struct intel_pinctrl for wider use - Use GPIO direction definitions lynxpoint: - Update summary in the driver - Switch to pin control API - Add GPIO <-> pin mapping ranges via callback - Implement ->pin_dbg_show() - Add pin control operations - Reuse struct intel_pinctrl in the driver - Add pin control data structures - Implement intel_gpio_get_direction callback - Implement ->irq_ack() callback - Move ownership check to IRQ chip - Move lp_irq_type() closer to IRQ related routines - Move ->remove closer to ->probe() - Extract lp_gpio_acpi_use() for future use - Convert unsigned to unsigned int - Switch to memory mapped IO accessors - Keep pointer to struct device instead of its container - Relax GPIO request rules - Assume 2 bits for mode selector - Use standard pattern for memory allocation - Use %pR to print IO resource - Drop useless assignment - Correct amount of pins - Use raw_spinlock for locking - Move GPIO driver to pin controller folder sunrisepoint: - Add Coffee Lake-S ACPI ID - Add missing Interrupt Status register offset tigerlake: - Tiger Lake uses _HID enumeration
This commit is contained in:
commit
a1dd4bfb14
13 changed files with 1486 additions and 1008 deletions
|
@ -8347,7 +8347,6 @@ S: Maintained
|
|||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git
|
||||
F: drivers/gpio/gpio-ich.c
|
||||
F: drivers/gpio/gpio-intel-mid.c
|
||||
F: drivers/gpio/gpio-lynxpoint.c
|
||||
F: drivers/gpio/gpio-merrifield.c
|
||||
F: drivers/gpio/gpio-ml-ioh.c
|
||||
F: drivers/gpio/gpio-pch.c
|
||||
|
|
|
@ -335,14 +335,6 @@ config GPIO_LPC32XX
|
|||
Select this option to enable GPIO driver for
|
||||
NXP LPC32XX devices.
|
||||
|
||||
config GPIO_LYNXPOINT
|
||||
tristate "Intel Lynxpoint GPIO support"
|
||||
depends on ACPI && X86
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
driver for GPIO functionality on Intel Lynxpoint PCH chipset
|
||||
Requires ACPI device enumeration code to set up a platform device.
|
||||
|
||||
config GPIO_MB86S7X
|
||||
tristate "GPIO support for Fujitsu MB86S7x Platforms"
|
||||
help
|
||||
|
|
|
@ -76,7 +76,6 @@ obj-$(CONFIG_GPIO_LP873X) += gpio-lp873x.o
|
|||
obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
|
||||
obj-$(CONFIG_GPIO_LPC18XX) += gpio-lpc18xx.o
|
||||
obj-$(CONFIG_GPIO_LPC32XX) += gpio-lpc32xx.o
|
||||
obj-$(CONFIG_GPIO_LYNXPOINT) += gpio-lynxpoint.o
|
||||
obj-$(CONFIG_GPIO_MADERA) += gpio-madera.o
|
||||
obj-$(CONFIG_GPIO_MAX3191X) += gpio-max3191x.o
|
||||
obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
|
||||
|
|
|
@ -1,471 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* GPIO controller driver for Intel Lynxpoint PCH chipset>
|
||||
* Copyright (c) 2012, Intel Corporation.
|
||||
*
|
||||
* Author: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* LynxPoint chipset has support for 94 gpio pins */
|
||||
|
||||
#define LP_NUM_GPIO 94
|
||||
|
||||
/* Bitmapped register offsets */
|
||||
#define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */
|
||||
#define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */
|
||||
#define LP_INT_STAT 0x80
|
||||
#define LP_INT_ENABLE 0x90
|
||||
|
||||
/* Each pin has two 32 bit config registers, starting at 0x100 */
|
||||
#define LP_CONFIG1 0x100
|
||||
#define LP_CONFIG2 0x104
|
||||
|
||||
/* LP_CONFIG1 reg bits */
|
||||
#define OUT_LVL_BIT BIT(31)
|
||||
#define IN_LVL_BIT BIT(30)
|
||||
#define TRIG_SEL_BIT BIT(4) /* 0: Edge, 1: Level */
|
||||
#define INT_INV_BIT BIT(3) /* Invert interrupt triggering */
|
||||
#define DIR_BIT BIT(2) /* 0: Output, 1: Input */
|
||||
#define USE_SEL_BIT BIT(0) /* 0: Native, 1: GPIO */
|
||||
|
||||
/* LP_CONFIG2 reg bits */
|
||||
#define GPINDIS_BIT BIT(2) /* disable input sensing */
|
||||
#define GPIWP_BIT (BIT(0) | BIT(1)) /* weak pull options */
|
||||
|
||||
struct lp_gpio {
|
||||
struct gpio_chip chip;
|
||||
struct platform_device *pdev;
|
||||
spinlock_t lock;
|
||||
unsigned long reg_base;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lynxpoint gpios are controlled through both bitmapped registers and
|
||||
* per gpio specific registers. The bitmapped registers are in chunks of
|
||||
* 3 x 32bit registers to cover all 94 gpios
|
||||
*
|
||||
* per gpio specific registers consist of two 32bit registers per gpio
|
||||
* (LP_CONFIG1 and LP_CONFIG2), with 94 gpios there's a total of
|
||||
* 188 config registers.
|
||||
*
|
||||
* A simplified view of the register layout look like this:
|
||||
*
|
||||
* LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31 (bitmapped registers)
|
||||
* LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63
|
||||
* LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94
|
||||
* ...
|
||||
* LP_INT_ENABLE[31:0] ...
|
||||
* LP_INT_ENABLE[63:31] ...
|
||||
* LP_INT_ENABLE[94:64] ...
|
||||
* LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers)
|
||||
* LP0_CONFIG2 (gpio 0) config2 reg for gpio 0
|
||||
* LP1_CONFIG1 (gpio 1) config1 reg for gpio 1
|
||||
* LP1_CONFIG2 (gpio 1) config2 reg for gpio 1
|
||||
* LP2_CONFIG1 (gpio 2) ...
|
||||
* LP2_CONFIG2 (gpio 2) ...
|
||||
* ...
|
||||
* LP94_CONFIG1 (gpio 94) ...
|
||||
* LP94_CONFIG2 (gpio 94) ...
|
||||
*/
|
||||
|
||||
static unsigned long lp_gpio_reg(struct gpio_chip *chip, unsigned offset,
|
||||
int reg)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
int reg_offset;
|
||||
|
||||
if (reg == LP_CONFIG1 || reg == LP_CONFIG2)
|
||||
/* per gpio specific config registers */
|
||||
reg_offset = offset * 8;
|
||||
else
|
||||
/* bitmapped registers */
|
||||
reg_offset = (offset / 32) * 4;
|
||||
|
||||
return lg->reg_base + reg + reg_offset;
|
||||
}
|
||||
|
||||
static int lp_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
|
||||
unsigned long acpi_use = lp_gpio_reg(chip, offset, LP_ACPI_OWNED);
|
||||
|
||||
pm_runtime_get(&lg->pdev->dev); /* should we put if failed */
|
||||
|
||||
/* Fail if BIOS reserved pin for ACPI use */
|
||||
if (!(inl(acpi_use) & BIT(offset % 32))) {
|
||||
dev_err(&lg->pdev->dev, "gpio %d reserved for ACPI\n", offset);
|
||||
return -EBUSY;
|
||||
}
|
||||
/* Fail if pin is in alternate function mode (not GPIO mode) */
|
||||
if (!(inl(reg) & USE_SEL_BIT))
|
||||
return -ENODEV;
|
||||
|
||||
/* enable input sensing */
|
||||
outl(inl(conf2) & ~GPINDIS_BIT, conf2);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
unsigned long conf2 = lp_gpio_reg(chip, offset, LP_CONFIG2);
|
||||
|
||||
/* disable input sensing */
|
||||
outl(inl(conf2) | GPINDIS_BIT, conf2);
|
||||
|
||||
pm_runtime_put(&lg->pdev->dev);
|
||||
}
|
||||
|
||||
static int lp_irq_type(struct irq_data *d, unsigned type)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct lp_gpio *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
|
||||
|
||||
if (hwirq >= lg->chip.ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&lg->lock, flags);
|
||||
value = inl(reg);
|
||||
|
||||
/* set both TRIG_SEL and INV bits to 0 for rising edge */
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
value &= ~(TRIG_SEL_BIT | INT_INV_BIT);
|
||||
|
||||
/* TRIG_SEL bit 0, INV bit 1 for falling edge */
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT;
|
||||
|
||||
/* TRIG_SEL bit 1, INV bit 0 for level low */
|
||||
if (type & IRQ_TYPE_LEVEL_LOW)
|
||||
value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT;
|
||||
|
||||
/* TRIG_SEL bit 1, INV bit 1 for level high */
|
||||
if (type & IRQ_TYPE_LEVEL_HIGH)
|
||||
value |= TRIG_SEL_BIT | INT_INV_BIT;
|
||||
|
||||
outl(value, reg);
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_BOTH)
|
||||
irq_set_handler_locked(d, handle_edge_irq);
|
||||
else if (type & IRQ_TYPE_LEVEL_MASK)
|
||||
irq_set_handler_locked(d, handle_level_irq);
|
||||
|
||||
spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
return !!(inl(reg) & IN_LVL_BIT);
|
||||
}
|
||||
|
||||
static void lp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
if (value)
|
||||
outl(inl(reg) | OUT_LVL_BIT, reg);
|
||||
else
|
||||
outl(inl(reg) & ~OUT_LVL_BIT, reg);
|
||||
|
||||
spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&lg->lock, flags);
|
||||
outl(inl(reg) | DIR_BIT, reg);
|
||||
spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
unsigned long reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
unsigned long flags;
|
||||
|
||||
lp_gpio_set(chip, offset, value);
|
||||
|
||||
spin_lock_irqsave(&lg->lock, flags);
|
||||
outl(inl(reg) & ~DIR_BIT, reg);
|
||||
spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lp_gpio_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct irq_data *data = irq_desc_get_irq_data(desc);
|
||||
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||
struct lp_gpio *lg = gpiochip_get_data(gc);
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
unsigned long reg, ena, pending;
|
||||
u32 base, pin;
|
||||
|
||||
/* check from GPIO controller which pin triggered the interrupt */
|
||||
for (base = 0; base < lg->chip.ngpio; base += 32) {
|
||||
reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
|
||||
ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
|
||||
|
||||
/* Only interrupts that are enabled */
|
||||
pending = inl(reg) & inl(ena);
|
||||
|
||||
for_each_set_bit(pin, &pending, 32) {
|
||||
unsigned irq;
|
||||
|
||||
/* Clear before handling so we don't lose an edge */
|
||||
outl(BIT(pin), reg);
|
||||
|
||||
irq = irq_find_mapping(lg->chip.irq.domain, base + pin);
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
}
|
||||
chip->irq_eoi(data);
|
||||
}
|
||||
|
||||
static void lp_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static void lp_irq_mask(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static void lp_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct lp_gpio *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&lg->lock, flags);
|
||||
outl(inl(reg) | BIT(hwirq % 32), reg);
|
||||
spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static void lp_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct lp_gpio *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&lg->lock, flags);
|
||||
outl(inl(reg) & ~BIT(hwirq % 32), reg);
|
||||
spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip lp_irqchip = {
|
||||
.name = "LP-GPIO",
|
||||
.irq_mask = lp_irq_mask,
|
||||
.irq_unmask = lp_irq_unmask,
|
||||
.irq_enable = lp_irq_enable,
|
||||
.irq_disable = lp_irq_disable,
|
||||
.irq_set_type = lp_irq_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
|
||||
{
|
||||
struct lp_gpio *lg = gpiochip_get_data(chip);
|
||||
unsigned long reg;
|
||||
unsigned base;
|
||||
|
||||
for (base = 0; base < lg->chip.ngpio; base += 32) {
|
||||
/* disable gpio pin interrupts */
|
||||
reg = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
|
||||
outl(0, reg);
|
||||
/* Clear interrupt status register */
|
||||
reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
|
||||
outl(0xffffffff, reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct lp_gpio *lg;
|
||||
struct gpio_chip *gc;
|
||||
struct resource *io_rc, *irq_rc;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned long reg_len;
|
||||
int ret = -ENODEV;
|
||||
|
||||
lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
|
||||
if (!lg)
|
||||
return -ENOMEM;
|
||||
|
||||
lg->pdev = pdev;
|
||||
platform_set_drvdata(pdev, lg);
|
||||
|
||||
io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
|
||||
if (!io_rc) {
|
||||
dev_err(dev, "missing IO resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lg->reg_base = io_rc->start;
|
||||
reg_len = resource_size(io_rc);
|
||||
|
||||
if (!devm_request_region(dev, lg->reg_base, reg_len, "lp-gpio")) {
|
||||
dev_err(dev, "failed requesting IO region 0x%x\n",
|
||||
(unsigned int)lg->reg_base);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
spin_lock_init(&lg->lock);
|
||||
|
||||
gc = &lg->chip;
|
||||
gc->label = dev_name(dev);
|
||||
gc->owner = THIS_MODULE;
|
||||
gc->request = lp_gpio_request;
|
||||
gc->free = lp_gpio_free;
|
||||
gc->direction_input = lp_gpio_direction_input;
|
||||
gc->direction_output = lp_gpio_direction_output;
|
||||
gc->get = lp_gpio_get;
|
||||
gc->set = lp_gpio_set;
|
||||
gc->base = -1;
|
||||
gc->ngpio = LP_NUM_GPIO;
|
||||
gc->can_sleep = false;
|
||||
gc->parent = dev;
|
||||
|
||||
/* set up interrupts */
|
||||
if (irq_rc && irq_rc->start) {
|
||||
struct gpio_irq_chip *girq;
|
||||
|
||||
girq = &gc->irq;
|
||||
girq->chip = &lp_irqchip;
|
||||
girq->init_hw = lp_gpio_irq_init_hw;
|
||||
girq->parent_handler = lp_gpio_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
|
||||
sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->parents[0] = (unsigned)irq_rc->start;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
}
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, gc, lg);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed adding lp-gpio chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_runtime_resume(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_resume(struct device *dev)
|
||||
{
|
||||
struct lp_gpio *lg = dev_get_drvdata(dev);
|
||||
unsigned long reg;
|
||||
int i;
|
||||
|
||||
/* on some hardware suspend clears input sensing, re-enable it here */
|
||||
for (i = 0; i < lg->chip.ngpio; i++) {
|
||||
if (gpiochip_is_requested(&lg->chip, i) != NULL) {
|
||||
reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2);
|
||||
outl(inl(reg) & ~GPINDIS_BIT, reg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops lp_gpio_pm_ops = {
|
||||
.runtime_suspend = lp_gpio_runtime_suspend,
|
||||
.runtime_resume = lp_gpio_runtime_resume,
|
||||
.resume = lp_gpio_resume,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = {
|
||||
{ "INT33C7", 0 },
|
||||
{ "INT3437", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
|
||||
|
||||
static int lp_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver lp_gpio_driver = {
|
||||
.probe = lp_gpio_probe,
|
||||
.remove = lp_gpio_remove,
|
||||
.driver = {
|
||||
.name = "lp_gpio",
|
||||
.pm = &lp_gpio_pm_ops,
|
||||
.acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init lp_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&lp_gpio_driver);
|
||||
}
|
||||
|
||||
static void __exit lp_gpio_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&lp_gpio_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(lp_gpio_init);
|
||||
module_exit(lp_gpio_exit);
|
||||
|
||||
MODULE_AUTHOR("Mathias Nyman (Intel)");
|
||||
MODULE_DESCRIPTION("GPIO interface for Intel Lynxpoint");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:lp_gpio");
|
|
@ -31,6 +31,19 @@ config PINCTRL_CHERRYVIEW
|
|||
Cherryview/Braswell pinctrl driver provides an interface that
|
||||
allows configuring of SoC pins and using them as GPIOs.
|
||||
|
||||
config PINCTRL_LYNXPOINT
|
||||
tristate "Intel Lynxpoint pinctrl and GPIO driver"
|
||||
depends on ACPI
|
||||
select PINMUX
|
||||
select PINCONF
|
||||
select GENERIC_PINCONF
|
||||
select GPIOLIB
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Lynxpoint is the PCH of Intel Haswell. This pinctrl driver
|
||||
provides an interface that allows configuring of PCH pins and
|
||||
using them as GPIOs.
|
||||
|
||||
config PINCTRL_MERRIFIELD
|
||||
tristate "Intel Merrifield pinctrl driver"
|
||||
depends on X86_INTEL_MID
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
|
||||
obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o
|
||||
obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o
|
||||
obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o
|
||||
obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o
|
||||
obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
#define BYT_DEFAULT_GPIO_MUX 0
|
||||
#define BYT_ALTER_GPIO_MUX 1
|
||||
|
||||
struct byt_gpio_pin_context {
|
||||
struct intel_pad_context {
|
||||
u32 conf0;
|
||||
u32 val;
|
||||
};
|
||||
|
@ -105,16 +105,6 @@ struct byt_gpio_pin_context {
|
|||
.pad_map = (map),\
|
||||
}
|
||||
|
||||
struct byt_gpio {
|
||||
struct gpio_chip chip;
|
||||
struct platform_device *pdev;
|
||||
struct pinctrl_dev *pctl_dev;
|
||||
struct pinctrl_desc pctl_desc;
|
||||
const struct intel_pinctrl_soc_data *soc_data;
|
||||
struct intel_community *communities_copy;
|
||||
struct byt_gpio_pin_context *saved_context;
|
||||
};
|
||||
|
||||
/* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
|
||||
static const struct pinctrl_pin_desc byt_score_pins[] = {
|
||||
PINCTRL_PIN(0, "SATA_GP0"),
|
||||
|
@ -550,14 +540,14 @@ static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
|
|||
|
||||
static DEFINE_RAW_SPINLOCK(byt_lock);
|
||||
|
||||
static struct intel_community *byt_get_community(struct byt_gpio *vg,
|
||||
static struct intel_community *byt_get_community(struct intel_pinctrl *vg,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct intel_community *comm;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < vg->soc_data->ncommunities; i++) {
|
||||
comm = vg->communities_copy + i;
|
||||
for (i = 0; i < vg->ncommunities; i++) {
|
||||
comm = vg->communities + i;
|
||||
if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
|
||||
return comm;
|
||||
}
|
||||
|
@ -565,7 +555,7 @@ static struct intel_community *byt_get_community(struct byt_gpio *vg,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
|
||||
static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset,
|
||||
int reg)
|
||||
{
|
||||
struct intel_community *comm = byt_get_community(vg, offset);
|
||||
|
@ -592,17 +582,17 @@ static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
|
|||
|
||||
static int byt_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return vg->soc_data->ngroups;
|
||||
return vg->soc->ngroups;
|
||||
}
|
||||
|
||||
static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return vg->soc_data->groups[selector].name;
|
||||
return vg->soc->groups[selector].name;
|
||||
}
|
||||
|
||||
static int byt_get_group_pins(struct pinctrl_dev *pctldev,
|
||||
|
@ -610,10 +600,10 @@ static int byt_get_group_pins(struct pinctrl_dev *pctldev,
|
|||
const unsigned int **pins,
|
||||
unsigned int *num_pins)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*pins = vg->soc_data->groups[selector].pins;
|
||||
*num_pins = vg->soc_data->groups[selector].npins;
|
||||
*pins = vg->soc->groups[selector].pins;
|
||||
*num_pins = vg->soc->groups[selector].npins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -626,17 +616,17 @@ static const struct pinctrl_ops byt_pinctrl_ops = {
|
|||
|
||||
static int byt_get_functions_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return vg->soc_data->nfunctions;
|
||||
return vg->soc->nfunctions;
|
||||
}
|
||||
|
||||
static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return vg->soc_data->functions[selector].name;
|
||||
return vg->soc->functions[selector].name;
|
||||
}
|
||||
|
||||
static int byt_get_function_groups(struct pinctrl_dev *pctldev,
|
||||
|
@ -644,15 +634,15 @@ static int byt_get_function_groups(struct pinctrl_dev *pctldev,
|
|||
const char * const **groups,
|
||||
unsigned int *num_groups)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*groups = vg->soc_data->functions[selector].groups;
|
||||
*num_groups = vg->soc_data->functions[selector].ngroups;
|
||||
*groups = vg->soc->functions[selector].groups;
|
||||
*num_groups = vg->soc->functions[selector].ngroups;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void byt_set_group_simple_mux(struct byt_gpio *vg,
|
||||
static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
|
||||
const struct intel_pingroup group,
|
||||
unsigned int func)
|
||||
{
|
||||
|
@ -667,7 +657,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg,
|
|||
|
||||
padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
|
||||
if (!padcfg0) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Group %s, pin %i not muxed (no padcfg0)\n",
|
||||
group.name, i);
|
||||
continue;
|
||||
|
@ -682,7 +672,7 @@ static void byt_set_group_simple_mux(struct byt_gpio *vg,
|
|||
raw_spin_unlock_irqrestore(&byt_lock, flags);
|
||||
}
|
||||
|
||||
static void byt_set_group_mixed_mux(struct byt_gpio *vg,
|
||||
static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
|
||||
const struct intel_pingroup group,
|
||||
const unsigned int *func)
|
||||
{
|
||||
|
@ -697,7 +687,7 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg,
|
|||
|
||||
padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
|
||||
if (!padcfg0) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Group %s, pin %i not muxed (no padcfg0)\n",
|
||||
group.name, i);
|
||||
continue;
|
||||
|
@ -715,9 +705,9 @@ static void byt_set_group_mixed_mux(struct byt_gpio *vg,
|
|||
static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
|
||||
unsigned int group_selector)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct intel_function func = vg->soc_data->functions[func_selector];
|
||||
const struct intel_pingroup group = vg->soc_data->groups[group_selector];
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct intel_function func = vg->soc->functions[func_selector];
|
||||
const struct intel_pingroup group = vg->soc->groups[group_selector];
|
||||
|
||||
if (group.modes)
|
||||
byt_set_group_mixed_mux(vg, group, group.modes);
|
||||
|
@ -729,22 +719,22 @@ static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned int offset)
|
||||
static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
|
||||
{
|
||||
/* SCORE pin 92-93 */
|
||||
if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) &&
|
||||
if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) &&
|
||||
offset >= 92 && offset <= 93)
|
||||
return BYT_ALTER_GPIO_MUX;
|
||||
|
||||
/* SUS pin 11-21 */
|
||||
if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) &&
|
||||
if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) &&
|
||||
offset >= 11 && offset <= 21)
|
||||
return BYT_ALTER_GPIO_MUX;
|
||||
|
||||
return BYT_DEFAULT_GPIO_MUX;
|
||||
}
|
||||
|
||||
static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
|
||||
static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
|
||||
{
|
||||
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
|
||||
unsigned long flags;
|
||||
|
@ -752,7 +742,13 @@ static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
|
|||
|
||||
raw_spin_lock_irqsave(&byt_lock, flags);
|
||||
value = readl(reg);
|
||||
value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
|
||||
|
||||
/* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
|
||||
if (value & BYT_DIRECT_IRQ_EN)
|
||||
/* nothing to do */ ;
|
||||
else
|
||||
value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
|
||||
|
||||
writel(value, reg);
|
||||
raw_spin_unlock_irqrestore(&byt_lock, flags);
|
||||
}
|
||||
|
@ -761,7 +757,7 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
|
|||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
|
||||
u32 value, gpio_mux;
|
||||
unsigned long flags;
|
||||
|
@ -784,13 +780,12 @@ static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
|
|||
value |= gpio_mux;
|
||||
writel(value, reg);
|
||||
|
||||
dev_warn(&vg->pdev->dev, FW_BUG
|
||||
"pin %u forcibly re-configured as GPIO\n", offset);
|
||||
dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset);
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&byt_lock, flags);
|
||||
|
||||
pm_runtime_get(&vg->pdev->dev);
|
||||
pm_runtime_get(vg->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -799,10 +794,10 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
|
|||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
|
||||
byt_gpio_clear_triggering(vg, offset);
|
||||
pm_runtime_put(&vg->pdev->dev);
|
||||
pm_runtime_put(vg->dev);
|
||||
}
|
||||
|
||||
static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
|
||||
|
@ -810,7 +805,7 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
|
|||
unsigned int offset,
|
||||
bool input)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
|
||||
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
|
||||
unsigned long flags;
|
||||
|
@ -822,15 +817,15 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
|
|||
value &= ~BYT_DIR_MASK;
|
||||
if (input)
|
||||
value |= BYT_OUTPUT_EN;
|
||||
else
|
||||
else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
|
||||
/*
|
||||
* Before making any direction modifications, do a check if gpio
|
||||
* is set for direct IRQ. On baytrail, setting GPIO to output
|
||||
* does not make sense, so let's at least warn the caller before
|
||||
* does not make sense, so let's at least inform the caller before
|
||||
* they shoot themselves in the foot.
|
||||
*/
|
||||
WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
|
||||
"Potential Error: Setting GPIO with direct_irq_en to output");
|
||||
dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
|
||||
|
||||
writel(value, val_reg);
|
||||
|
||||
raw_spin_unlock_irqrestore(&byt_lock, flags);
|
||||
|
@ -893,7 +888,7 @@ static int byt_set_pull_strength(u32 *reg, u16 strength)
|
|||
static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
|
||||
unsigned long *config)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
enum pin_config_param param = pinconf_to_config_param(*config);
|
||||
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
|
||||
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
|
||||
|
@ -978,7 +973,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
|
|||
unsigned long *configs,
|
||||
unsigned int num_configs)
|
||||
{
|
||||
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
|
||||
unsigned int param, arg;
|
||||
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
|
||||
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
|
||||
|
@ -1012,7 +1007,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
|
|||
if (val & BYT_INPUT_EN) {
|
||||
val &= ~BYT_INPUT_EN;
|
||||
writel(val, val_reg);
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"pin %u forcibly set to input mode\n",
|
||||
offset);
|
||||
}
|
||||
|
@ -1034,7 +1029,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
|
|||
if (val & BYT_INPUT_EN) {
|
||||
val &= ~BYT_INPUT_EN;
|
||||
writel(val, val_reg);
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"pin %u forcibly set to input mode\n",
|
||||
offset);
|
||||
}
|
||||
|
@ -1115,7 +1110,7 @@ static const struct pinctrl_desc byt_pinctrl_desc = {
|
|||
|
||||
static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(chip);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
@ -1129,7 +1124,7 @@ static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
|||
|
||||
static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(chip);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
|
||||
unsigned long flags;
|
||||
u32 old_val;
|
||||
|
@ -1148,7 +1143,7 @@ static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
|
|||
|
||||
static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(chip);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
|
@ -1161,9 +1156,9 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
raw_spin_unlock_irqrestore(&byt_lock, flags);
|
||||
|
||||
if (!(value & BYT_OUTPUT_EN))
|
||||
return 0;
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
if (!(value & BYT_INPUT_EN))
|
||||
return 1;
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1188,11 +1183,11 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
|
|||
|
||||
static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(chip);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
int i;
|
||||
u32 conf0, val;
|
||||
|
||||
for (i = 0; i < vg->soc_data->npins; i++) {
|
||||
for (i = 0; i < vg->soc->npins; i++) {
|
||||
const struct intel_community *comm;
|
||||
const char *pull_str = NULL;
|
||||
const char *pull = NULL;
|
||||
|
@ -1202,7 +1197,7 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
|
|||
unsigned int pin;
|
||||
|
||||
raw_spin_lock_irqsave(&byt_lock, flags);
|
||||
pin = vg->soc_data->pins[i].number;
|
||||
pin = vg->soc->pins[i].number;
|
||||
reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
|
||||
if (!reg) {
|
||||
seq_printf(s,
|
||||
|
@ -1297,7 +1292,7 @@ static const struct gpio_chip byt_gpio_chip = {
|
|||
static void byt_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct byt_gpio *vg = gpiochip_get_data(gc);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(gc);
|
||||
unsigned int offset = irqd_to_hwirq(d);
|
||||
void __iomem *reg;
|
||||
|
||||
|
@ -1313,7 +1308,7 @@ static void byt_irq_ack(struct irq_data *d)
|
|||
static void byt_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct byt_gpio *vg = gpiochip_get_data(gc);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(gc);
|
||||
|
||||
byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
|
||||
}
|
||||
|
@ -1321,7 +1316,7 @@ static void byt_irq_mask(struct irq_data *d)
|
|||
static void byt_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct byt_gpio *vg = gpiochip_get_data(gc);
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(gc);
|
||||
unsigned int offset = irqd_to_hwirq(d);
|
||||
unsigned long flags;
|
||||
void __iomem *reg;
|
||||
|
@ -1359,7 +1354,7 @@ static void byt_irq_unmask(struct irq_data *d)
|
|||
|
||||
static int byt_irq_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
|
||||
u32 offset = irqd_to_hwirq(d);
|
||||
u32 value;
|
||||
unsigned long flags;
|
||||
|
@ -1395,20 +1390,10 @@ static int byt_irq_type(struct irq_data *d, unsigned int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip byt_irqchip = {
|
||||
.name = "BYT-GPIO",
|
||||
.irq_ack = byt_irq_ack,
|
||||
.irq_mask = byt_irq_mask,
|
||||
.irq_unmask = byt_irq_unmask,
|
||||
.irq_set_type = byt_irq_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static void byt_gpio_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct irq_data *data = irq_desc_get_irq_data(desc);
|
||||
struct byt_gpio *vg = gpiochip_get_data(
|
||||
irq_desc_get_handler_data(desc));
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc));
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
u32 base, pin;
|
||||
void __iomem *reg;
|
||||
|
@ -1420,7 +1405,7 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
|
|||
reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
|
||||
|
||||
if (!reg) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Pin %i: could not retrieve interrupt status register\n",
|
||||
base);
|
||||
continue;
|
||||
|
@ -1441,22 +1426,9 @@ static void byt_init_irq_valid_mask(struct gpio_chip *chip,
|
|||
unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
/*
|
||||
* FIXME: currently the valid_mask is filled in as part of
|
||||
* initializing the irq_chip below in byt_gpio_irq_init_hw().
|
||||
* when converting this driver to the new way of passing the
|
||||
* gpio_irq_chip along when adding the gpio_chip, move the
|
||||
* mask initialization into this callback instead. Right now
|
||||
* this callback is here to make sure the mask gets allocated.
|
||||
*/
|
||||
}
|
||||
|
||||
static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(chip);
|
||||
struct device *dev = &vg->pdev->dev;
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
u32 base, value;
|
||||
u32 value;
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
@ -1464,12 +1436,12 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
|||
* do not use direct IRQ mode. This will prevent spurious
|
||||
* interrupts from misconfigured pins.
|
||||
*/
|
||||
for (i = 0; i < vg->soc_data->npins; i++) {
|
||||
unsigned int pin = vg->soc_data->pins[i].number;
|
||||
for (i = 0; i < vg->soc->npins; i++) {
|
||||
unsigned int pin = vg->soc->pins[i].number;
|
||||
|
||||
reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
|
||||
if (!reg) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Pin %i: could not retrieve conf0 register\n",
|
||||
i);
|
||||
continue;
|
||||
|
@ -1477,20 +1449,27 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
|||
|
||||
value = readl(reg);
|
||||
if (value & BYT_DIRECT_IRQ_EN) {
|
||||
clear_bit(i, chip->irq.valid_mask);
|
||||
dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i);
|
||||
clear_bit(i, valid_mask);
|
||||
dev_dbg(vg->dev, "excluding GPIO %d from IRQ domain\n", i);
|
||||
} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
|
||||
byt_gpio_clear_triggering(vg, i);
|
||||
dev_dbg(dev, "disabling GPIO %d\n", i);
|
||||
dev_dbg(vg->dev, "disabling GPIO %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
||||
{
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
u32 base, value;
|
||||
|
||||
/* clear interrupt status trigger registers */
|
||||
for (base = 0; base < vg->soc_data->npins; base += 32) {
|
||||
for (base = 0; base < vg->soc->npins; base += 32) {
|
||||
reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
|
||||
|
||||
if (!reg) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Pin %i: could not retrieve irq status reg\n",
|
||||
base);
|
||||
continue;
|
||||
|
@ -1501,7 +1480,7 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
|||
might be misconfigured in bios */
|
||||
value = readl(reg);
|
||||
if (value)
|
||||
dev_err(&vg->pdev->dev,
|
||||
dev_err(vg->dev,
|
||||
"GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n",
|
||||
base / 32, value);
|
||||
}
|
||||
|
@ -1511,19 +1490,20 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
|
|||
|
||||
static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
|
||||
{
|
||||
struct byt_gpio *vg = gpiochip_get_data(chip);
|
||||
struct device *dev = &vg->pdev->dev;
|
||||
struct intel_pinctrl *vg = gpiochip_get_data(chip);
|
||||
struct device *dev = vg->dev;
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc_data->npins);
|
||||
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
|
||||
if (ret)
|
||||
dev_err(dev, "failed to add GPIO pin range\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int byt_gpio_probe(struct byt_gpio *vg)
|
||||
static int byt_gpio_probe(struct intel_pinctrl *vg)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(vg->dev);
|
||||
struct gpio_chip *gc;
|
||||
struct resource *irq_rc;
|
||||
int ret;
|
||||
|
@ -1531,32 +1511,39 @@ static int byt_gpio_probe(struct byt_gpio *vg)
|
|||
/* Set up gpio chip */
|
||||
vg->chip = byt_gpio_chip;
|
||||
gc = &vg->chip;
|
||||
gc->label = dev_name(&vg->pdev->dev);
|
||||
gc->label = dev_name(vg->dev);
|
||||
gc->base = -1;
|
||||
gc->can_sleep = false;
|
||||
gc->add_pin_ranges = byt_gpio_add_pin_ranges;
|
||||
gc->parent = &vg->pdev->dev;
|
||||
gc->ngpio = vg->soc_data->npins;
|
||||
gc->irq.init_valid_mask = byt_init_irq_valid_mask;
|
||||
gc->parent = vg->dev;
|
||||
gc->ngpio = vg->soc->npins;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,
|
||||
sizeof(*vg->saved_context), GFP_KERNEL);
|
||||
if (!vg->saved_context)
|
||||
vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads),
|
||||
GFP_KERNEL);
|
||||
if (!vg->context.pads)
|
||||
return -ENOMEM;
|
||||
#endif
|
||||
|
||||
/* set up interrupts */
|
||||
irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0);
|
||||
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (irq_rc && irq_rc->start) {
|
||||
struct gpio_irq_chip *girq;
|
||||
|
||||
vg->irqchip.name = "BYT-GPIO",
|
||||
vg->irqchip.irq_ack = byt_irq_ack,
|
||||
vg->irqchip.irq_mask = byt_irq_mask,
|
||||
vg->irqchip.irq_unmask = byt_irq_unmask,
|
||||
vg->irqchip.irq_set_type = byt_irq_type,
|
||||
vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
|
||||
girq = &gc->irq;
|
||||
girq->chip = &byt_irqchip;
|
||||
girq->chip = &vg->irqchip;
|
||||
girq->init_hw = byt_gpio_irq_init_hw;
|
||||
girq->init_valid_mask = byt_init_irq_valid_mask;
|
||||
girq->parent_handler = byt_gpio_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(&vg->pdev->dev, girq->num_parents,
|
||||
girq->parents = devm_kcalloc(vg->dev, girq->num_parents,
|
||||
sizeof(*girq->parents), GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
|
@ -1565,34 +1552,35 @@ static int byt_gpio_probe(struct byt_gpio *vg)
|
|||
girq->handler = handle_bad_irq;
|
||||
}
|
||||
|
||||
ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg);
|
||||
ret = devm_gpiochip_add_data(vg->dev, gc, vg);
|
||||
if (ret) {
|
||||
dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n");
|
||||
dev_err(vg->dev, "failed adding byt-gpio chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int byt_set_soc_data(struct byt_gpio *vg,
|
||||
const struct intel_pinctrl_soc_data *soc_data)
|
||||
static int byt_set_soc_data(struct intel_pinctrl *vg,
|
||||
const struct intel_pinctrl_soc_data *soc)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(vg->dev);
|
||||
int i;
|
||||
|
||||
vg->soc_data = soc_data;
|
||||
vg->communities_copy = devm_kcalloc(&vg->pdev->dev,
|
||||
soc_data->ncommunities,
|
||||
sizeof(*vg->communities_copy),
|
||||
GFP_KERNEL);
|
||||
if (!vg->communities_copy)
|
||||
vg->soc = soc;
|
||||
|
||||
vg->ncommunities = vg->soc->ncommunities;
|
||||
vg->communities = devm_kcalloc(vg->dev, vg->ncommunities,
|
||||
sizeof(*vg->communities), GFP_KERNEL);
|
||||
if (!vg->communities)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < soc_data->ncommunities; i++) {
|
||||
struct intel_community *comm = vg->communities_copy + i;
|
||||
for (i = 0; i < vg->soc->ncommunities; i++) {
|
||||
struct intel_community *comm = vg->communities + i;
|
||||
|
||||
*comm = vg->soc_data->communities[i];
|
||||
*comm = vg->soc->communities[i];
|
||||
|
||||
comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0);
|
||||
comm->pad_regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(comm->pad_regs))
|
||||
return PTR_ERR(comm->pad_regs);
|
||||
}
|
||||
|
@ -1610,15 +1598,16 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
|||
{
|
||||
const struct intel_pinctrl_soc_data *soc_data = NULL;
|
||||
const struct intel_pinctrl_soc_data **soc_table;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *acpi_dev;
|
||||
struct byt_gpio *vg;
|
||||
struct intel_pinctrl *vg;
|
||||
int i, ret;
|
||||
|
||||
acpi_dev = ACPI_COMPANION(&pdev->dev);
|
||||
acpi_dev = ACPI_COMPANION(dev);
|
||||
if (!acpi_dev)
|
||||
return -ENODEV;
|
||||
|
||||
soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
|
||||
soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev);
|
||||
|
||||
for (i = 0; soc_table[i]; i++) {
|
||||
if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
|
||||
|
@ -1630,26 +1619,26 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
|||
if (!soc_data)
|
||||
return -ENODEV;
|
||||
|
||||
vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL);
|
||||
vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL);
|
||||
if (!vg)
|
||||
return -ENOMEM;
|
||||
|
||||
vg->pdev = pdev;
|
||||
vg->dev = dev;
|
||||
ret = byt_set_soc_data(vg, soc_data);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to set soc data\n");
|
||||
dev_err(dev, "failed to set soc data\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
vg->pctl_desc = byt_pinctrl_desc;
|
||||
vg->pctl_desc.name = dev_name(&pdev->dev);
|
||||
vg->pctl_desc.pins = vg->soc_data->pins;
|
||||
vg->pctl_desc.npins = vg->soc_data->npins;
|
||||
vg->pctldesc = byt_pinctrl_desc;
|
||||
vg->pctldesc.name = dev_name(dev);
|
||||
vg->pctldesc.pins = vg->soc->pins;
|
||||
vg->pctldesc.npins = vg->soc->npins;
|
||||
|
||||
vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg);
|
||||
if (IS_ERR(vg->pctl_dev)) {
|
||||
dev_err(&pdev->dev, "failed to register pinctrl driver\n");
|
||||
return PTR_ERR(vg->pctl_dev);
|
||||
vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
|
||||
if (IS_ERR(vg->pctldev)) {
|
||||
dev_err(dev, "failed to register pinctrl driver\n");
|
||||
return PTR_ERR(vg->pctldev);
|
||||
}
|
||||
|
||||
ret = byt_gpio_probe(vg);
|
||||
|
@ -1657,7 +1646,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, vg);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1665,30 +1654,30 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
|
|||
#ifdef CONFIG_PM_SLEEP
|
||||
static int byt_gpio_suspend(struct device *dev)
|
||||
{
|
||||
struct byt_gpio *vg = dev_get_drvdata(dev);
|
||||
struct intel_pinctrl *vg = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
raw_spin_lock_irqsave(&byt_lock, flags);
|
||||
|
||||
for (i = 0; i < vg->soc_data->npins; i++) {
|
||||
for (i = 0; i < vg->soc->npins; i++) {
|
||||
void __iomem *reg;
|
||||
u32 value;
|
||||
unsigned int pin = vg->soc_data->pins[i].number;
|
||||
unsigned int pin = vg->soc->pins[i].number;
|
||||
|
||||
reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
|
||||
if (!reg) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Pin %i: could not retrieve conf0 register\n",
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
value = readl(reg) & BYT_CONF0_RESTORE_MASK;
|
||||
vg->saved_context[i].conf0 = value;
|
||||
vg->context.pads[i].conf0 = value;
|
||||
|
||||
reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
|
||||
value = readl(reg) & BYT_VAL_RESTORE_MASK;
|
||||
vg->saved_context[i].val = value;
|
||||
vg->context.pads[i].val = value;
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&byt_lock, flags);
|
||||
|
@ -1697,29 +1686,29 @@ static int byt_gpio_suspend(struct device *dev)
|
|||
|
||||
static int byt_gpio_resume(struct device *dev)
|
||||
{
|
||||
struct byt_gpio *vg = dev_get_drvdata(dev);
|
||||
struct intel_pinctrl *vg = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
raw_spin_lock_irqsave(&byt_lock, flags);
|
||||
|
||||
for (i = 0; i < vg->soc_data->npins; i++) {
|
||||
for (i = 0; i < vg->soc->npins; i++) {
|
||||
void __iomem *reg;
|
||||
u32 value;
|
||||
unsigned int pin = vg->soc_data->pins[i].number;
|
||||
unsigned int pin = vg->soc->pins[i].number;
|
||||
|
||||
reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
|
||||
if (!reg) {
|
||||
dev_warn(&vg->pdev->dev,
|
||||
dev_warn(vg->dev,
|
||||
"Pin %i: could not retrieve conf0 register\n",
|
||||
i);
|
||||
continue;
|
||||
}
|
||||
value = readl(reg);
|
||||
if ((value & BYT_CONF0_RESTORE_MASK) !=
|
||||
vg->saved_context[i].conf0) {
|
||||
vg->context.pads[i].conf0) {
|
||||
value &= ~BYT_CONF0_RESTORE_MASK;
|
||||
value |= vg->saved_context[i].conf0;
|
||||
value |= vg->context.pads[i].conf0;
|
||||
writel(value, reg);
|
||||
dev_info(dev, "restored pin %d conf0 %#08x", i, value);
|
||||
}
|
||||
|
@ -1727,11 +1716,11 @@ static int byt_gpio_resume(struct device *dev)
|
|||
reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
|
||||
value = readl(reg);
|
||||
if ((value & BYT_VAL_RESTORE_MASK) !=
|
||||
vg->saved_context[i].val) {
|
||||
vg->context.pads[i].val) {
|
||||
u32 v;
|
||||
|
||||
v = value & ~BYT_VAL_RESTORE_MASK;
|
||||
v |= vg->saved_context[i].val;
|
||||
v |= vg->context.pads[i].val;
|
||||
if (v != value) {
|
||||
writel(v, reg);
|
||||
dev_dbg(dev, "restored pin %d val %#08x\n",
|
||||
|
|
|
@ -1289,7 +1289,10 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK;
|
||||
direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT;
|
||||
|
||||
return direction != CHV_PADCTRL0_GPIOCFG_GPO;
|
||||
if (direction == CHV_PADCTRL0_GPIOCFG_GPO)
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
}
|
||||
|
||||
static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -85,39 +85,6 @@ struct intel_community_context {
|
|||
u32 *hostown;
|
||||
};
|
||||
|
||||
struct intel_pinctrl_context {
|
||||
struct intel_pad_context *pads;
|
||||
struct intel_community_context *communities;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct intel_pinctrl - Intel pinctrl private structure
|
||||
* @dev: Pointer to the device structure
|
||||
* @lock: Lock to serialize register access
|
||||
* @pctldesc: Pin controller description
|
||||
* @pctldev: Pointer to the pin controller device
|
||||
* @chip: GPIO chip in this pin controller
|
||||
* @irqchip: IRQ chip in this pin controller
|
||||
* @soc: SoC/PCH specific pin configuration data
|
||||
* @communities: All communities in this pin controller
|
||||
* @ncommunities: Number of communities in this pin controller
|
||||
* @context: Configuration saved over system sleep
|
||||
* @irq: pinctrl/GPIO chip irq number
|
||||
*/
|
||||
struct intel_pinctrl {
|
||||
struct device *dev;
|
||||
raw_spinlock_t lock;
|
||||
struct pinctrl_desc pctldesc;
|
||||
struct pinctrl_dev *pctldev;
|
||||
struct gpio_chip chip;
|
||||
struct irq_chip irqchip;
|
||||
const struct intel_pinctrl_soc_data *soc;
|
||||
struct intel_community *communities;
|
||||
size_t ncommunities;
|
||||
struct intel_pinctrl_context context;
|
||||
int irq;
|
||||
};
|
||||
|
||||
#define pin_to_padno(c, p) ((p) - (c)->pin_base)
|
||||
#define padgroup_offset(g, p) ((p) - (g)->base)
|
||||
|
||||
|
@ -944,7 +911,10 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||
if (padcfg0 & PADCFG0_PMODE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return !!(padcfg0 & PADCFG0_GPIOTXDIS);
|
||||
if (padcfg0 & PADCFG0_GPIOTXDIS)
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
}
|
||||
|
||||
static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
|
||||
|
@ -1160,8 +1130,8 @@ static irqreturn_t intel_gpio_irq(int irq, void *data)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
|
||||
const struct intel_community *community)
|
||||
static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl,
|
||||
const struct intel_community *community)
|
||||
{
|
||||
int ret = 0, i;
|
||||
|
||||
|
@ -1181,6 +1151,24 @@ static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int intel_gpio_add_pin_ranges(struct gpio_chip *gc)
|
||||
{
|
||||
struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < pctrl->ncommunities; i++) {
|
||||
struct intel_community *community = &pctrl->communities[i];
|
||||
|
||||
ret = intel_gpio_add_community_ranges(pctrl, community);
|
||||
if (ret) {
|
||||
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
|
||||
{
|
||||
const struct intel_community *community;
|
||||
|
@ -1205,7 +1193,8 @@ static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl)
|
|||
|
||||
static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
|
||||
{
|
||||
int ret, i;
|
||||
int ret;
|
||||
struct gpio_irq_chip *girq;
|
||||
|
||||
pctrl->chip = intel_gpio_chip;
|
||||
|
||||
|
@ -1214,6 +1203,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
|
|||
pctrl->chip.label = dev_name(pctrl->dev);
|
||||
pctrl->chip.parent = pctrl->dev;
|
||||
pctrl->chip.base = -1;
|
||||
pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges;
|
||||
pctrl->irq = irq;
|
||||
|
||||
/* Setup IRQ chip */
|
||||
|
@ -1225,26 +1215,9 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
|
|||
pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake;
|
||||
pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND;
|
||||
|
||||
ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
|
||||
if (ret) {
|
||||
dev_err(pctrl->dev, "failed to register gpiochip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < pctrl->ncommunities; i++) {
|
||||
struct intel_community *community = &pctrl->communities[i];
|
||||
|
||||
ret = intel_gpio_add_pin_ranges(pctrl, community);
|
||||
if (ret) {
|
||||
dev_err(pctrl->dev, "failed to add GPIO pin range\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to request the interrupt here (instead of providing chip
|
||||
* to the irq directly) because on some platforms several GPIO
|
||||
* controllers share the same interrupt line.
|
||||
* On some platforms several GPIO controllers share the same interrupt
|
||||
* line.
|
||||
*/
|
||||
ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq,
|
||||
IRQF_SHARED | IRQF_NO_THREAD,
|
||||
|
@ -1254,14 +1227,20 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = gpiochip_irqchip_add(&pctrl->chip, &pctrl->irqchip, 0,
|
||||
handle_bad_irq, IRQ_TYPE_NONE);
|
||||
girq = &pctrl->chip.irq;
|
||||
girq->chip = &pctrl->irqchip;
|
||||
/* This will let us handle the IRQ in the driver */
|
||||
girq->parent_handler = NULL;
|
||||
girq->num_parents = 0;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
|
||||
ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl);
|
||||
if (ret) {
|
||||
dev_err(pctrl->dev, "failed to add irqchip\n");
|
||||
dev_err(pctrl->dev, "failed to register gpiochip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(&pctrl->chip, &pctrl->irqchip, irq, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
#ifndef PINCTRL_INTEL_H
|
||||
#define PINCTRL_INTEL_H
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
|
||||
struct pinctrl_pin_desc;
|
||||
struct platform_device;
|
||||
|
@ -174,6 +177,47 @@ struct intel_pinctrl_soc_data {
|
|||
size_t ncommunities;
|
||||
};
|
||||
|
||||
struct intel_pad_context;
|
||||
struct intel_community_context;
|
||||
|
||||
/**
|
||||
* struct intel_pinctrl_context - context to be saved during suspend-resume
|
||||
* @pads: Opaque context per pad (driver dependent)
|
||||
* @communities: Opaque context per community (driver dependent)
|
||||
*/
|
||||
struct intel_pinctrl_context {
|
||||
struct intel_pad_context *pads;
|
||||
struct intel_community_context *communities;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct intel_pinctrl - Intel pinctrl private structure
|
||||
* @dev: Pointer to the device structure
|
||||
* @lock: Lock to serialize register access
|
||||
* @pctldesc: Pin controller description
|
||||
* @pctldev: Pointer to the pin controller device
|
||||
* @chip: GPIO chip in this pin controller
|
||||
* @irqchip: IRQ chip in this pin controller
|
||||
* @soc: SoC/PCH specific pin configuration data
|
||||
* @communities: All communities in this pin controller
|
||||
* @ncommunities: Number of communities in this pin controller
|
||||
* @context: Configuration saved over system sleep
|
||||
* @irq: pinctrl/GPIO chip irq number
|
||||
*/
|
||||
struct intel_pinctrl {
|
||||
struct device *dev;
|
||||
raw_spinlock_t lock;
|
||||
struct pinctrl_desc pctldesc;
|
||||
struct pinctrl_dev *pctldev;
|
||||
struct gpio_chip chip;
|
||||
struct irq_chip irqchip;
|
||||
const struct intel_pinctrl_soc_data *soc;
|
||||
struct intel_community *communities;
|
||||
size_t ncommunities;
|
||||
struct intel_pinctrl_context context;
|
||||
int irq;
|
||||
};
|
||||
|
||||
int intel_pinctrl_probe_by_hid(struct platform_device *pdev);
|
||||
int intel_pinctrl_probe_by_uid(struct platform_device *pdev);
|
||||
|
||||
|
|
975
drivers/pinctrl/intel/pinctrl-lynxpoint.c
Normal file
975
drivers/pinctrl/intel/pinctrl-lynxpoint.c
Normal file
|
@ -0,0 +1,975 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Intel Lynxpoint PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (c) 2012, 2019, Intel Corporation
|
||||
* Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
* Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
|
||||
#include "pinctrl-intel.h"
|
||||
|
||||
#define COMMUNITY(p, n) \
|
||||
{ \
|
||||
.pin_base = (p), \
|
||||
.npins = (n), \
|
||||
}
|
||||
|
||||
static const struct pinctrl_pin_desc lptlp_pins[] = {
|
||||
PINCTRL_PIN(0, "GP0_UART1_RXD"),
|
||||
PINCTRL_PIN(1, "GP1_UART1_TXD"),
|
||||
PINCTRL_PIN(2, "GP2_UART1_RTSB"),
|
||||
PINCTRL_PIN(3, "GP3_UART1_CTSB"),
|
||||
PINCTRL_PIN(4, "GP4_I2C0_SDA"),
|
||||
PINCTRL_PIN(5, "GP5_I2C0_SCL"),
|
||||
PINCTRL_PIN(6, "GP6_I2C1_SDA"),
|
||||
PINCTRL_PIN(7, "GP7_I2C1_SCL"),
|
||||
PINCTRL_PIN(8, "GP8"),
|
||||
PINCTRL_PIN(9, "GP9"),
|
||||
PINCTRL_PIN(10, "GP10"),
|
||||
PINCTRL_PIN(11, "GP11_SMBALERTB"),
|
||||
PINCTRL_PIN(12, "GP12_LANPHYPC"),
|
||||
PINCTRL_PIN(13, "GP13"),
|
||||
PINCTRL_PIN(14, "GP14"),
|
||||
PINCTRL_PIN(15, "GP15"),
|
||||
PINCTRL_PIN(16, "GP16_MGPIO9"),
|
||||
PINCTRL_PIN(17, "GP17_MGPIO10"),
|
||||
PINCTRL_PIN(18, "GP18_SRC0CLKRQB"),
|
||||
PINCTRL_PIN(19, "GP19_SRC1CLKRQB"),
|
||||
PINCTRL_PIN(20, "GP20_SRC2CLKRQB"),
|
||||
PINCTRL_PIN(21, "GP21_SRC3CLKRQB"),
|
||||
PINCTRL_PIN(22, "GP22_SRC4CLKRQB_TRST2"),
|
||||
PINCTRL_PIN(23, "GP23_SRC5CLKRQB_TDI2"),
|
||||
PINCTRL_PIN(24, "GP24_MGPIO0"),
|
||||
PINCTRL_PIN(25, "GP25_USBWAKEOUTB"),
|
||||
PINCTRL_PIN(26, "GP26_MGPIO5"),
|
||||
PINCTRL_PIN(27, "GP27_MGPIO6"),
|
||||
PINCTRL_PIN(28, "GP28_MGPIO7"),
|
||||
PINCTRL_PIN(29, "GP29_SLP_WLANB_MGPIO3"),
|
||||
PINCTRL_PIN(30, "GP30_SUSWARNB_SUSPWRDNACK_MGPIO1"),
|
||||
PINCTRL_PIN(31, "GP31_ACPRESENT_MGPIO2"),
|
||||
PINCTRL_PIN(32, "GP32_CLKRUNB"),
|
||||
PINCTRL_PIN(33, "GP33_DEVSLP0"),
|
||||
PINCTRL_PIN(34, "GP34_SATA0XPCIE6L3B_SATA0GP"),
|
||||
PINCTRL_PIN(35, "GP35_SATA1XPCIE6L2B_SATA1GP"),
|
||||
PINCTRL_PIN(36, "GP36_SATA2XPCIE6L1B_SATA2GP"),
|
||||
PINCTRL_PIN(37, "GP37_SATA3XPCIE6L0B_SATA3GP"),
|
||||
PINCTRL_PIN(38, "GP38_DEVSLP1"),
|
||||
PINCTRL_PIN(39, "GP39_DEVSLP2"),
|
||||
PINCTRL_PIN(40, "GP40_OC0B"),
|
||||
PINCTRL_PIN(41, "GP41_OC1B"),
|
||||
PINCTRL_PIN(42, "GP42_OC2B"),
|
||||
PINCTRL_PIN(43, "GP43_OC3B"),
|
||||
PINCTRL_PIN(44, "GP44"),
|
||||
PINCTRL_PIN(45, "GP45_TMS2"),
|
||||
PINCTRL_PIN(46, "GP46_TDO2"),
|
||||
PINCTRL_PIN(47, "GP47"),
|
||||
PINCTRL_PIN(48, "GP48"),
|
||||
PINCTRL_PIN(49, "GP49"),
|
||||
PINCTRL_PIN(50, "GP50"),
|
||||
PINCTRL_PIN(51, "GP51_GSXDOUT"),
|
||||
PINCTRL_PIN(52, "GP52_GSXSLOAD"),
|
||||
PINCTRL_PIN(53, "GP53_GSXDIN"),
|
||||
PINCTRL_PIN(54, "GP54_GSXSRESETB"),
|
||||
PINCTRL_PIN(55, "GP55_GSXCLK"),
|
||||
PINCTRL_PIN(56, "GP56"),
|
||||
PINCTRL_PIN(57, "GP57"),
|
||||
PINCTRL_PIN(58, "GP58"),
|
||||
PINCTRL_PIN(59, "GP59"),
|
||||
PINCTRL_PIN(60, "GP60_SML0ALERTB_MGPIO4"),
|
||||
PINCTRL_PIN(61, "GP61_SUS_STATB"),
|
||||
PINCTRL_PIN(62, "GP62_SUSCLK"),
|
||||
PINCTRL_PIN(63, "GP63_SLP_S5B"),
|
||||
PINCTRL_PIN(64, "GP64_SDIO_CLK"),
|
||||
PINCTRL_PIN(65, "GP65_SDIO_CMD"),
|
||||
PINCTRL_PIN(66, "GP66_SDIO_D0"),
|
||||
PINCTRL_PIN(67, "GP67_SDIO_D1"),
|
||||
PINCTRL_PIN(68, "GP68_SDIO_D2"),
|
||||
PINCTRL_PIN(69, "GP69_SDIO_D3"),
|
||||
PINCTRL_PIN(70, "GP70_SDIO_POWER_EN"),
|
||||
PINCTRL_PIN(71, "GP71_MPHYPC"),
|
||||
PINCTRL_PIN(72, "GP72_BATLOWB"),
|
||||
PINCTRL_PIN(73, "GP73_SML1ALERTB_PCHHOTB_MGPIO8"),
|
||||
PINCTRL_PIN(74, "GP74_SML1DATA_MGPIO12"),
|
||||
PINCTRL_PIN(75, "GP75_SML1CLK_MGPIO11"),
|
||||
PINCTRL_PIN(76, "GP76_BMBUSYB"),
|
||||
PINCTRL_PIN(77, "GP77_PIRQAB"),
|
||||
PINCTRL_PIN(78, "GP78_PIRQBB"),
|
||||
PINCTRL_PIN(79, "GP79_PIRQCB"),
|
||||
PINCTRL_PIN(80, "GP80_PIRQDB"),
|
||||
PINCTRL_PIN(81, "GP81_SPKR"),
|
||||
PINCTRL_PIN(82, "GP82_RCINB"),
|
||||
PINCTRL_PIN(83, "GP83_GSPI0_CSB"),
|
||||
PINCTRL_PIN(84, "GP84_GSPI0_CLK"),
|
||||
PINCTRL_PIN(85, "GP85_GSPI0_MISO"),
|
||||
PINCTRL_PIN(86, "GP86_GSPI0_MOSI"),
|
||||
PINCTRL_PIN(87, "GP87_GSPI1_CSB"),
|
||||
PINCTRL_PIN(88, "GP88_GSPI1_CLK"),
|
||||
PINCTRL_PIN(89, "GP89_GSPI1_MISO"),
|
||||
PINCTRL_PIN(90, "GP90_GSPI1_MOSI"),
|
||||
PINCTRL_PIN(91, "GP91_UART0_RXD"),
|
||||
PINCTRL_PIN(92, "GP92_UART0_TXD"),
|
||||
PINCTRL_PIN(93, "GP93_UART0_RTSB"),
|
||||
PINCTRL_PIN(94, "GP94_UART0_CTSB"),
|
||||
};
|
||||
|
||||
static const struct intel_community lptlp_communities[] = {
|
||||
COMMUNITY(0, 95),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data lptlp_soc_data = {
|
||||
.pins = lptlp_pins,
|
||||
.npins = ARRAY_SIZE(lptlp_pins),
|
||||
.communities = lptlp_communities,
|
||||
.ncommunities = ARRAY_SIZE(lptlp_communities),
|
||||
};
|
||||
|
||||
/* LynxPoint chipset has support for 95 GPIO pins */
|
||||
|
||||
#define LP_NUM_GPIO 95
|
||||
|
||||
/* Bitmapped register offsets */
|
||||
#define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */
|
||||
#define LP_IRQ2IOXAPIC 0x10 /* Bitmap, set by bios, 1: pin routed to IOxAPIC */
|
||||
#define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */
|
||||
#define LP_INT_STAT 0x80
|
||||
#define LP_INT_ENABLE 0x90
|
||||
|
||||
/* Each pin has two 32 bit config registers, starting at 0x100 */
|
||||
#define LP_CONFIG1 0x100
|
||||
#define LP_CONFIG2 0x104
|
||||
|
||||
/* LP_CONFIG1 reg bits */
|
||||
#define OUT_LVL_BIT BIT(31)
|
||||
#define IN_LVL_BIT BIT(30)
|
||||
#define TRIG_SEL_BIT BIT(4) /* 0: Edge, 1: Level */
|
||||
#define INT_INV_BIT BIT(3) /* Invert interrupt triggering */
|
||||
#define DIR_BIT BIT(2) /* 0: Output, 1: Input */
|
||||
#define USE_SEL_MASK GENMASK(1, 0) /* 0: Native, 1: GPIO, ... */
|
||||
#define USE_SEL_NATIVE (0 << 0)
|
||||
#define USE_SEL_GPIO (1 << 0)
|
||||
|
||||
/* LP_CONFIG2 reg bits */
|
||||
#define GPINDIS_BIT BIT(2) /* disable input sensing */
|
||||
#define GPIWP_MASK GENMASK(1, 0) /* weak pull options */
|
||||
#define GPIWP_NONE 0 /* none */
|
||||
#define GPIWP_DOWN 1 /* weak pull down */
|
||||
#define GPIWP_UP 2 /* weak pull up */
|
||||
|
||||
/*
|
||||
* Lynxpoint gpios are controlled through both bitmapped registers and
|
||||
* per gpio specific registers. The bitmapped registers are in chunks of
|
||||
* 3 x 32bit registers to cover all 95 GPIOs
|
||||
*
|
||||
* per gpio specific registers consist of two 32bit registers per gpio
|
||||
* (LP_CONFIG1 and LP_CONFIG2), with 95 GPIOs there's a total of
|
||||
* 190 config registers.
|
||||
*
|
||||
* A simplified view of the register layout look like this:
|
||||
*
|
||||
* LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31 (bitmapped registers)
|
||||
* LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63
|
||||
* LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94
|
||||
* ...
|
||||
* LP_INT_ENABLE[31:0] ...
|
||||
* LP_INT_ENABLE[63:32] ...
|
||||
* LP_INT_ENABLE[94:64] ...
|
||||
* LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers)
|
||||
* LP0_CONFIG2 (gpio 0) config2 reg for gpio 0
|
||||
* LP1_CONFIG1 (gpio 1) config1 reg for gpio 1
|
||||
* LP1_CONFIG2 (gpio 1) config2 reg for gpio 1
|
||||
* LP2_CONFIG1 (gpio 2) ...
|
||||
* LP2_CONFIG2 (gpio 2) ...
|
||||
* ...
|
||||
* LP94_CONFIG1 (gpio 94) ...
|
||||
* LP94_CONFIG2 (gpio 94) ...
|
||||
*
|
||||
* IOxAPIC redirection map applies only for gpio 8-10, 13-14, 45-55.
|
||||
*/
|
||||
|
||||
static struct intel_community *lp_get_community(struct intel_pinctrl *lg,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct intel_community *comm;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lg->ncommunities; i++) {
|
||||
comm = &lg->communities[i];
|
||||
if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
|
||||
return comm;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset,
|
||||
int reg)
|
||||
{
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(chip);
|
||||
struct intel_community *comm;
|
||||
int reg_offset;
|
||||
|
||||
comm = lp_get_community(lg, offset);
|
||||
if (!comm)
|
||||
return NULL;
|
||||
|
||||
offset -= comm->pin_base;
|
||||
|
||||
if (reg == LP_CONFIG1 || reg == LP_CONFIG2)
|
||||
/* per gpio specific config registers */
|
||||
reg_offset = offset * 8;
|
||||
else
|
||||
/* bitmapped registers */
|
||||
reg_offset = (offset / 32) * 4;
|
||||
|
||||
return comm->regs + reg_offset + reg;
|
||||
}
|
||||
|
||||
static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin)
|
||||
{
|
||||
void __iomem *acpi_use;
|
||||
|
||||
acpi_use = lp_gpio_reg(&lg->chip, pin, LP_ACPI_OWNED);
|
||||
if (!acpi_use)
|
||||
return true;
|
||||
|
||||
return !(ioread32(acpi_use) & BIT(pin % 32));
|
||||
}
|
||||
|
||||
static bool lp_gpio_ioxapic_use(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
void __iomem *ioxapic_use = lp_gpio_reg(chip, offset, LP_IRQ2IOXAPIC);
|
||||
u32 value;
|
||||
|
||||
value = ioread32(ioxapic_use);
|
||||
|
||||
if (offset >= 8 && offset <= 10)
|
||||
return !!(value & BIT(offset - 8 + 0));
|
||||
if (offset >= 13 && offset <= 14)
|
||||
return !!(value & BIT(offset - 13 + 3));
|
||||
if (offset >= 45 && offset <= 55)
|
||||
return !!(value & BIT(offset - 45 + 5));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int lp_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return lg->soc->ngroups;
|
||||
}
|
||||
|
||||
static const char *lp_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return lg->soc->groups[selector].name;
|
||||
}
|
||||
|
||||
static int lp_get_group_pins(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector,
|
||||
const unsigned int **pins,
|
||||
unsigned int *num_pins)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*pins = lg->soc->groups[selector].pins;
|
||||
*num_pins = lg->soc->groups[selector].npins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lp_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
|
||||
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
|
||||
u32 value, mode;
|
||||
|
||||
value = ioread32(reg);
|
||||
|
||||
mode = value & USE_SEL_MASK;
|
||||
if (mode == USE_SEL_GPIO)
|
||||
seq_puts(s, "GPIO ");
|
||||
else
|
||||
seq_printf(s, "mode %d ", mode);
|
||||
|
||||
seq_printf(s, "0x%08x 0x%08x", value, ioread32(conf2));
|
||||
|
||||
if (lp_gpio_acpi_use(lg, pin))
|
||||
seq_puts(s, " [ACPI]");
|
||||
}
|
||||
|
||||
static const struct pinctrl_ops lptlp_pinctrl_ops = {
|
||||
.get_groups_count = lp_get_groups_count,
|
||||
.get_group_name = lp_get_group_name,
|
||||
.get_group_pins = lp_get_group_pins,
|
||||
.pin_dbg_show = lp_pin_dbg_show,
|
||||
};
|
||||
|
||||
static int lp_get_functions_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return lg->soc->nfunctions;
|
||||
}
|
||||
|
||||
static const char *lp_get_function_name(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return lg->soc->functions[selector].name;
|
||||
}
|
||||
|
||||
static int lp_get_function_groups(struct pinctrl_dev *pctldev,
|
||||
unsigned int selector,
|
||||
const char * const **groups,
|
||||
unsigned int *num_groups)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*groups = lg->soc->functions[selector].groups;
|
||||
*num_groups = lg->soc->functions[selector].ngroups;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev,
|
||||
unsigned int function, unsigned int group)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
const struct intel_pingroup *grp = &lg->soc->groups[group];
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
/* Now enable the mux setting for each pin in the group */
|
||||
for (i = 0; i < grp->npins; i++) {
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, grp->pins[i], LP_CONFIG1);
|
||||
u32 value;
|
||||
|
||||
value = ioread32(reg);
|
||||
|
||||
value &= ~USE_SEL_MASK;
|
||||
if (grp->modes)
|
||||
value |= grp->modes[i];
|
||||
else
|
||||
value |= grp->mode;
|
||||
|
||||
iowrite32(value, reg);
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
|
||||
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
|
||||
pm_runtime_get(lg->dev);
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
/*
|
||||
* Reconfigure pin to GPIO mode if needed and issue a warning,
|
||||
* since we expect firmware to configure it properly.
|
||||
*/
|
||||
value = ioread32(reg);
|
||||
if ((value & USE_SEL_MASK) != USE_SEL_GPIO) {
|
||||
iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg);
|
||||
dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", pin);
|
||||
}
|
||||
|
||||
/* Enable input sensing */
|
||||
iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2);
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lp_gpio_disable_free(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int pin)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
/* Disable input sensing */
|
||||
iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2);
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
pm_runtime_put(lg->dev);
|
||||
}
|
||||
|
||||
static int lp_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int pin, bool input)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1);
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
value = ioread32(reg);
|
||||
value &= ~DIR_BIT;
|
||||
if (input) {
|
||||
value |= DIR_BIT;
|
||||
} else {
|
||||
/*
|
||||
* Before making any direction modifications, do a check if GPIO
|
||||
* is set for direct IRQ. On Lynxpoint, setting GPIO to output
|
||||
* does not make sense, so let's at least warn the caller before
|
||||
* they shoot themselves in the foot.
|
||||
*/
|
||||
WARN(lp_gpio_ioxapic_use(&lg->chip, pin),
|
||||
"Potential Error: Setting GPIO to output with IOxAPIC redirection");
|
||||
}
|
||||
iowrite32(value, reg);
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinmux_ops lptlp_pinmux_ops = {
|
||||
.get_functions_count = lp_get_functions_count,
|
||||
.get_function_name = lp_get_function_name,
|
||||
.get_function_groups = lp_get_function_groups,
|
||||
.set_mux = lp_pinmux_set_mux,
|
||||
.gpio_request_enable = lp_gpio_request_enable,
|
||||
.gpio_disable_free = lp_gpio_disable_free,
|
||||
.gpio_set_direction = lp_gpio_set_direction,
|
||||
};
|
||||
|
||||
static int lp_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
unsigned long *config)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
|
||||
enum pin_config_param param = pinconf_to_config_param(*config);
|
||||
unsigned long flags;
|
||||
u32 value, pull;
|
||||
u16 arg = 0;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
value = ioread32(conf2);
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
pull = value & GPIWP_MASK;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
if (pull)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (pull != GPIWP_DOWN)
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
if (pull != GPIWP_UP)
|
||||
return -EINVAL;
|
||||
|
||||
arg = 1;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
*config = pinconf_to_config_packed(param, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
|
||||
unsigned long *configs, unsigned int num_configs)
|
||||
{
|
||||
struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev);
|
||||
void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2);
|
||||
enum pin_config_param param;
|
||||
unsigned long flags;
|
||||
int i, ret = 0;
|
||||
u32 value;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
value = ioread32(conf2);
|
||||
|
||||
for (i = 0; i < num_configs; i++) {
|
||||
param = pinconf_to_config_param(configs[i]);
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
value &= ~GPIWP_MASK;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
value &= ~GPIWP_MASK;
|
||||
value |= GPIWP_DOWN;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
value &= ~GPIWP_MASK;
|
||||
value |= GPIWP_UP;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
iowrite32(value, conf2);
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pinconf_ops lptlp_pinconf_ops = {
|
||||
.is_generic = true,
|
||||
.pin_config_get = lp_pin_config_get,
|
||||
.pin_config_set = lp_pin_config_set,
|
||||
};
|
||||
|
||||
static const struct pinctrl_desc lptlp_pinctrl_desc = {
|
||||
.pctlops = &lptlp_pinctrl_ops,
|
||||
.pmxops = &lptlp_pinmux_ops,
|
||||
.confops = &lptlp_pinconf_ops,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
return !!(ioread32(reg) & IN_LVL_BIT);
|
||||
}
|
||||
|
||||
static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
|
||||
{
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(chip);
|
||||
void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
|
||||
if (value)
|
||||
iowrite32(ioread32(reg) | OUT_LVL_BIT, reg);
|
||||
else
|
||||
iowrite32(ioread32(reg) & ~OUT_LVL_BIT, reg);
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
return pinctrl_gpio_direction_input(chip->base + offset);
|
||||
}
|
||||
|
||||
static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
lp_gpio_set(chip, offset, value);
|
||||
|
||||
return pinctrl_gpio_direction_output(chip->base + offset);
|
||||
}
|
||||
|
||||
static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1);
|
||||
|
||||
if (ioread32(reg) & DIR_BIT)
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
}
|
||||
|
||||
static void lp_gpio_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct irq_data *data = irq_desc_get_irq_data(desc);
|
||||
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(gc);
|
||||
struct irq_chip *chip = irq_data_get_irq_chip(data);
|
||||
void __iomem *reg, *ena;
|
||||
unsigned long pending;
|
||||
u32 base, pin;
|
||||
|
||||
/* check from GPIO controller which pin triggered the interrupt */
|
||||
for (base = 0; base < lg->chip.ngpio; base += 32) {
|
||||
reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
|
||||
ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
|
||||
|
||||
/* Only interrupts that are enabled */
|
||||
pending = ioread32(reg) & ioread32(ena);
|
||||
|
||||
for_each_set_bit(pin, &pending, 32) {
|
||||
unsigned int irq;
|
||||
|
||||
irq = irq_find_mapping(lg->chip.irq.domain, base + pin);
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
}
|
||||
chip->irq_eoi(data);
|
||||
}
|
||||
|
||||
static void lp_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
iowrite32(BIT(hwirq % 32), reg);
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static void lp_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static void lp_irq_mask(struct irq_data *d)
|
||||
{
|
||||
}
|
||||
|
||||
static void lp_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
iowrite32(ioread32(reg) | BIT(hwirq % 32), reg);
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static void lp_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
iowrite32(ioread32(reg) & ~BIT(hwirq % 32), reg);
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
}
|
||||
|
||||
static int lp_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(gc);
|
||||
u32 hwirq = irqd_to_hwirq(d);
|
||||
void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1);
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
|
||||
if (hwirq >= lg->chip.ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
/* Fail if BIOS reserved pin for ACPI use */
|
||||
if (lp_gpio_acpi_use(lg, hwirq)) {
|
||||
dev_err(lg->dev, "pin %u can't be used as IRQ\n", hwirq);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
raw_spin_lock_irqsave(&lg->lock, flags);
|
||||
value = ioread32(reg);
|
||||
|
||||
/* set both TRIG_SEL and INV bits to 0 for rising edge */
|
||||
if (type & IRQ_TYPE_EDGE_RISING)
|
||||
value &= ~(TRIG_SEL_BIT | INT_INV_BIT);
|
||||
|
||||
/* TRIG_SEL bit 0, INV bit 1 for falling edge */
|
||||
if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT;
|
||||
|
||||
/* TRIG_SEL bit 1, INV bit 0 for level low */
|
||||
if (type & IRQ_TYPE_LEVEL_LOW)
|
||||
value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT;
|
||||
|
||||
/* TRIG_SEL bit 1, INV bit 1 for level high */
|
||||
if (type & IRQ_TYPE_LEVEL_HIGH)
|
||||
value |= TRIG_SEL_BIT | INT_INV_BIT;
|
||||
|
||||
iowrite32(value, reg);
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_BOTH)
|
||||
irq_set_handler_locked(d, handle_edge_irq);
|
||||
else if (type & IRQ_TYPE_LEVEL_MASK)
|
||||
irq_set_handler_locked(d, handle_level_irq);
|
||||
|
||||
raw_spin_unlock_irqrestore(&lg->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip lp_irqchip = {
|
||||
.name = "LP-GPIO",
|
||||
.irq_ack = lp_irq_ack,
|
||||
.irq_mask = lp_irq_mask,
|
||||
.irq_unmask = lp_irq_unmask,
|
||||
.irq_enable = lp_irq_enable,
|
||||
.irq_disable = lp_irq_disable,
|
||||
.irq_set_type = lp_irq_set_type,
|
||||
.flags = IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int lp_gpio_irq_init_hw(struct gpio_chip *chip)
|
||||
{
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
unsigned int base;
|
||||
|
||||
for (base = 0; base < lg->chip.ngpio; base += 32) {
|
||||
/* disable gpio pin interrupts */
|
||||
reg = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
|
||||
iowrite32(0, reg);
|
||||
/* Clear interrupt status register */
|
||||
reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
|
||||
iowrite32(0xffffffff, reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_add_pin_ranges(struct gpio_chip *chip)
|
||||
{
|
||||
struct intel_pinctrl *lg = gpiochip_get_data(chip);
|
||||
struct device *dev = lg->dev;
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins);
|
||||
if (ret)
|
||||
dev_err(dev, "failed to add GPIO pin range\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lp_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct intel_pinctrl_soc_data *soc;
|
||||
struct intel_pinctrl *lg;
|
||||
struct gpio_chip *gc;
|
||||
struct resource *io_rc, *irq_rc;
|
||||
struct device *dev = &pdev->dev;
|
||||
void __iomem *regs;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev);
|
||||
if (!soc)
|
||||
return -ENODEV;
|
||||
|
||||
lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL);
|
||||
if (!lg)
|
||||
return -ENOMEM;
|
||||
|
||||
lg->dev = dev;
|
||||
lg->soc = soc;
|
||||
|
||||
lg->ncommunities = lg->soc->ncommunities;
|
||||
lg->communities = devm_kcalloc(dev, lg->ncommunities,
|
||||
sizeof(*lg->communities), GFP_KERNEL);
|
||||
if (!lg->communities)
|
||||
return -ENOMEM;
|
||||
|
||||
lg->pctldesc = lptlp_pinctrl_desc;
|
||||
lg->pctldesc.name = dev_name(dev);
|
||||
lg->pctldesc.pins = lg->soc->pins;
|
||||
lg->pctldesc.npins = lg->soc->npins;
|
||||
|
||||
lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg);
|
||||
if (IS_ERR(lg->pctldev)) {
|
||||
dev_err(dev, "failed to register pinctrl driver\n");
|
||||
return PTR_ERR(lg->pctldev);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, lg);
|
||||
|
||||
io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (!io_rc) {
|
||||
dev_err(dev, "missing IO resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regs = devm_ioport_map(dev, io_rc->start, resource_size(io_rc));
|
||||
if (!regs) {
|
||||
dev_err(dev, "failed mapping IO region %pR\n", &io_rc);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
for (i = 0; i < lg->soc->ncommunities; i++) {
|
||||
struct intel_community *comm = &lg->communities[i];
|
||||
|
||||
*comm = lg->soc->communities[i];
|
||||
|
||||
comm->regs = regs;
|
||||
comm->pad_regs = regs + 0x100;
|
||||
}
|
||||
|
||||
raw_spin_lock_init(&lg->lock);
|
||||
|
||||
gc = &lg->chip;
|
||||
gc->label = dev_name(dev);
|
||||
gc->owner = THIS_MODULE;
|
||||
gc->request = gpiochip_generic_request;
|
||||
gc->free = gpiochip_generic_free;
|
||||
gc->direction_input = lp_gpio_direction_input;
|
||||
gc->direction_output = lp_gpio_direction_output;
|
||||
gc->get = lp_gpio_get;
|
||||
gc->set = lp_gpio_set;
|
||||
gc->get_direction = lp_gpio_get_direction;
|
||||
gc->base = -1;
|
||||
gc->ngpio = LP_NUM_GPIO;
|
||||
gc->can_sleep = false;
|
||||
gc->add_pin_ranges = lp_gpio_add_pin_ranges;
|
||||
gc->parent = dev;
|
||||
|
||||
/* set up interrupts */
|
||||
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (irq_rc && irq_rc->start) {
|
||||
struct gpio_irq_chip *girq;
|
||||
|
||||
girq = &gc->irq;
|
||||
girq->chip = &lp_irqchip;
|
||||
girq->init_hw = lp_gpio_irq_init_hw;
|
||||
girq->parent_handler = lp_gpio_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(dev, girq->num_parents,
|
||||
sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->parents[0] = (unsigned int)irq_rc->start;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
}
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, gc, lg);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed adding lp-gpio chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_runtime_suspend(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_runtime_resume(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp_gpio_resume(struct device *dev)
|
||||
{
|
||||
struct intel_pinctrl *lg = dev_get_drvdata(dev);
|
||||
void __iomem *reg;
|
||||
int i;
|
||||
|
||||
/* on some hardware suspend clears input sensing, re-enable it here */
|
||||
for (i = 0; i < lg->chip.ngpio; i++) {
|
||||
if (gpiochip_is_requested(&lg->chip, i) != NULL) {
|
||||
reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2);
|
||||
iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops lp_gpio_pm_ops = {
|
||||
.runtime_suspend = lp_gpio_runtime_suspend,
|
||||
.runtime_resume = lp_gpio_runtime_resume,
|
||||
.resume = lp_gpio_resume,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = {
|
||||
{ "INT33C7", (kernel_ulong_t)&lptlp_soc_data },
|
||||
{ "INT3437", (kernel_ulong_t)&lptlp_soc_data },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
|
||||
|
||||
static struct platform_driver lp_gpio_driver = {
|
||||
.probe = lp_gpio_probe,
|
||||
.remove = lp_gpio_remove,
|
||||
.driver = {
|
||||
.name = "lp_gpio",
|
||||
.pm = &lp_gpio_pm_ops,
|
||||
.acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init lp_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&lp_gpio_driver);
|
||||
}
|
||||
|
||||
static void __exit lp_gpio_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&lp_gpio_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(lp_gpio_init);
|
||||
module_exit(lp_gpio_exit);
|
||||
|
||||
MODULE_AUTHOR("Mathias Nyman (Intel)");
|
||||
MODULE_AUTHOR("Andy Shevchenko (Intel)");
|
||||
MODULE_DESCRIPTION("Intel Lynxpoint pinctrl driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:lp_gpio");
|
|
@ -49,6 +49,7 @@
|
|||
.padown_offset = SPT_PAD_OWN, \
|
||||
.padcfglock_offset = SPT_PADCFGLOCK, \
|
||||
.hostown_offset = SPT_HOSTSW_OWN, \
|
||||
.is_offset = SPT_GPI_IS, \
|
||||
.ie_offset = SPT_GPI_IE, \
|
||||
.pin_base = (s), \
|
||||
.npins = ((e) - (s) + 1), \
|
||||
|
@ -588,6 +589,7 @@ static const struct intel_pinctrl_soc_data spth_soc_data = {
|
|||
|
||||
static const struct acpi_device_id spt_pinctrl_acpi_match[] = {
|
||||
{ "INT344B", (kernel_ulong_t)&sptlp_soc_data },
|
||||
{ "INT3451", (kernel_ulong_t)&spth_soc_data },
|
||||
{ "INT345D", (kernel_ulong_t)&spth_soc_data },
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Intel Tiger Lake PCH pinctrl/GPIO driver
|
||||
*
|
||||
* Copyright (C) 2019, Intel Corporation
|
||||
* Copyright (C) 2019 - 2020, Intel Corporation
|
||||
* Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
@ -21,15 +21,19 @@
|
|||
#define TGL_GPI_IS 0x100
|
||||
#define TGL_GPI_IE 0x120
|
||||
|
||||
#define TGL_GPP(r, s, e) \
|
||||
#define TGL_NO_GPIO -1
|
||||
|
||||
#define TGL_GPP(r, s, e, g) \
|
||||
{ \
|
||||
.reg_num = (r), \
|
||||
.base = (s), \
|
||||
.size = ((e) - (s) + 1), \
|
||||
.gpio_base = (g), \
|
||||
}
|
||||
|
||||
#define TGL_COMMUNITY(s, e, g) \
|
||||
#define TGL_COMMUNITY(b, s, e, g) \
|
||||
{ \
|
||||
.barno = (b), \
|
||||
.padown_offset = TGL_PAD_OWN, \
|
||||
.padcfglock_offset = TGL_PADCFGLOCK, \
|
||||
.hostown_offset = TGL_HOSTSW_OWN, \
|
||||
|
@ -42,7 +46,7 @@
|
|||
}
|
||||
|
||||
/* Tiger Lake-LP */
|
||||
static const struct pinctrl_pin_desc tgllp_community0_pins[] = {
|
||||
static const struct pinctrl_pin_desc tgllp_pins[] = {
|
||||
/* GPP_B */
|
||||
PINCTRL_PIN(0, "CORE_VID_0"),
|
||||
PINCTRL_PIN(1, "CORE_VID_1"),
|
||||
|
@ -113,324 +117,273 @@ static const struct pinctrl_pin_desc tgllp_community0_pins[] = {
|
|||
PINCTRL_PIN(64, "GPPC_A_22"),
|
||||
PINCTRL_PIN(65, "I2S1_SCLK"),
|
||||
PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"),
|
||||
/* GPP_S */
|
||||
PINCTRL_PIN(67, "SNDW0_CLK"),
|
||||
PINCTRL_PIN(68, "SNDW0_DATA"),
|
||||
PINCTRL_PIN(69, "SNDW1_CLK"),
|
||||
PINCTRL_PIN(70, "SNDW1_DATA"),
|
||||
PINCTRL_PIN(71, "SNDW2_CLK"),
|
||||
PINCTRL_PIN(72, "SNDW2_DATA"),
|
||||
PINCTRL_PIN(73, "SNDW3_CLK"),
|
||||
PINCTRL_PIN(74, "SNDW3_DATA"),
|
||||
/* GPP_H */
|
||||
PINCTRL_PIN(75, "GPPC_H_0"),
|
||||
PINCTRL_PIN(76, "GPPC_H_1"),
|
||||
PINCTRL_PIN(77, "GPPC_H_2"),
|
||||
PINCTRL_PIN(78, "SX_EXIT_HOLDOFFB"),
|
||||
PINCTRL_PIN(79, "I2C2_SDA"),
|
||||
PINCTRL_PIN(80, "I2C2_SCL"),
|
||||
PINCTRL_PIN(81, "I2C3_SDA"),
|
||||
PINCTRL_PIN(82, "I2C3_SCL"),
|
||||
PINCTRL_PIN(83, "I2C4_SDA"),
|
||||
PINCTRL_PIN(84, "I2C4_SCL"),
|
||||
PINCTRL_PIN(85, "SRCCLKREQB_4"),
|
||||
PINCTRL_PIN(86, "SRCCLKREQB_5"),
|
||||
PINCTRL_PIN(87, "M2_SKT2_CFG_0"),
|
||||
PINCTRL_PIN(88, "M2_SKT2_CFG_1"),
|
||||
PINCTRL_PIN(89, "M2_SKT2_CFG_2"),
|
||||
PINCTRL_PIN(90, "M2_SKT2_CFG_3"),
|
||||
PINCTRL_PIN(91, "DDPB_CTRLCLK"),
|
||||
PINCTRL_PIN(92, "DDPB_CTRLDATA"),
|
||||
PINCTRL_PIN(93, "CPU_C10_GATEB"),
|
||||
PINCTRL_PIN(94, "TIME_SYNC_0"),
|
||||
PINCTRL_PIN(95, "IMGCLKOUT_1"),
|
||||
PINCTRL_PIN(96, "IMGCLKOUT_2"),
|
||||
PINCTRL_PIN(97, "IMGCLKOUT_3"),
|
||||
PINCTRL_PIN(98, "IMGCLKOUT_4"),
|
||||
/* GPP_D */
|
||||
PINCTRL_PIN(99, "ISH_GP_0"),
|
||||
PINCTRL_PIN(100, "ISH_GP_1"),
|
||||
PINCTRL_PIN(101, "ISH_GP_2"),
|
||||
PINCTRL_PIN(102, "ISH_GP_3"),
|
||||
PINCTRL_PIN(103, "IMGCLKOUT_0"),
|
||||
PINCTRL_PIN(104, "SRCCLKREQB_0"),
|
||||
PINCTRL_PIN(105, "SRCCLKREQB_1"),
|
||||
PINCTRL_PIN(106, "SRCCLKREQB_2"),
|
||||
PINCTRL_PIN(107, "SRCCLKREQB_3"),
|
||||
PINCTRL_PIN(108, "ISH_SPI_CSB"),
|
||||
PINCTRL_PIN(109, "ISH_SPI_CLK"),
|
||||
PINCTRL_PIN(110, "ISH_SPI_MISO"),
|
||||
PINCTRL_PIN(111, "ISH_SPI_MOSI"),
|
||||
PINCTRL_PIN(112, "ISH_UART0_RXD"),
|
||||
PINCTRL_PIN(113, "ISH_UART0_TXD"),
|
||||
PINCTRL_PIN(114, "ISH_UART0_RTSB"),
|
||||
PINCTRL_PIN(115, "ISH_UART0_CTSB"),
|
||||
PINCTRL_PIN(116, "ISH_GP_4"),
|
||||
PINCTRL_PIN(117, "ISH_GP_5"),
|
||||
PINCTRL_PIN(118, "I2S_MCLK1_OUT"),
|
||||
PINCTRL_PIN(119, "GSPI2_CLK_LOOPBK"),
|
||||
/* GPP_U */
|
||||
PINCTRL_PIN(120, "UART3_RXD"),
|
||||
PINCTRL_PIN(121, "UART3_TXD"),
|
||||
PINCTRL_PIN(122, "UART3_RTSB"),
|
||||
PINCTRL_PIN(123, "UART3_CTSB"),
|
||||
PINCTRL_PIN(124, "GSPI3_CS0B"),
|
||||
PINCTRL_PIN(125, "GSPI3_CLK"),
|
||||
PINCTRL_PIN(126, "GSPI3_MISO"),
|
||||
PINCTRL_PIN(127, "GSPI3_MOSI"),
|
||||
PINCTRL_PIN(128, "GSPI4_CS0B"),
|
||||
PINCTRL_PIN(129, "GSPI4_CLK"),
|
||||
PINCTRL_PIN(130, "GSPI4_MISO"),
|
||||
PINCTRL_PIN(131, "GSPI4_MOSI"),
|
||||
PINCTRL_PIN(132, "GSPI5_CS0B"),
|
||||
PINCTRL_PIN(133, "GSPI5_CLK"),
|
||||
PINCTRL_PIN(134, "GSPI5_MISO"),
|
||||
PINCTRL_PIN(135, "GSPI5_MOSI"),
|
||||
PINCTRL_PIN(136, "GSPI6_CS0B"),
|
||||
PINCTRL_PIN(137, "GSPI6_CLK"),
|
||||
PINCTRL_PIN(138, "GSPI6_MISO"),
|
||||
PINCTRL_PIN(139, "GSPI6_MOSI"),
|
||||
PINCTRL_PIN(140, "GSPI3_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(141, "GSPI4_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(142, "GSPI5_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(143, "GSPI6_CLK_LOOPBK"),
|
||||
/* vGPIO */
|
||||
PINCTRL_PIN(144, "CNV_BTEN"),
|
||||
PINCTRL_PIN(145, "CNV_BT_HOST_WAKEB"),
|
||||
PINCTRL_PIN(146, "CNV_BT_IF_SELECT"),
|
||||
PINCTRL_PIN(147, "vCNV_BT_UART_TXD"),
|
||||
PINCTRL_PIN(148, "vCNV_BT_UART_RXD"),
|
||||
PINCTRL_PIN(149, "vCNV_BT_UART_CTS_B"),
|
||||
PINCTRL_PIN(150, "vCNV_BT_UART_RTS_B"),
|
||||
PINCTRL_PIN(151, "vCNV_MFUART1_TXD"),
|
||||
PINCTRL_PIN(152, "vCNV_MFUART1_RXD"),
|
||||
PINCTRL_PIN(153, "vCNV_MFUART1_CTS_B"),
|
||||
PINCTRL_PIN(154, "vCNV_MFUART1_RTS_B"),
|
||||
PINCTRL_PIN(155, "vUART0_TXD"),
|
||||
PINCTRL_PIN(156, "vUART0_RXD"),
|
||||
PINCTRL_PIN(157, "vUART0_CTS_B"),
|
||||
PINCTRL_PIN(158, "vUART0_RTS_B"),
|
||||
PINCTRL_PIN(159, "vISH_UART0_TXD"),
|
||||
PINCTRL_PIN(160, "vISH_UART0_RXD"),
|
||||
PINCTRL_PIN(161, "vISH_UART0_CTS_B"),
|
||||
PINCTRL_PIN(162, "vISH_UART0_RTS_B"),
|
||||
PINCTRL_PIN(163, "vCNV_BT_I2S_BCLK"),
|
||||
PINCTRL_PIN(164, "vCNV_BT_I2S_WS_SYNC"),
|
||||
PINCTRL_PIN(165, "vCNV_BT_I2S_SDO"),
|
||||
PINCTRL_PIN(166, "vCNV_BT_I2S_SDI"),
|
||||
PINCTRL_PIN(167, "vI2S2_SCLK"),
|
||||
PINCTRL_PIN(168, "vI2S2_SFRM"),
|
||||
PINCTRL_PIN(169, "vI2S2_TXD"),
|
||||
PINCTRL_PIN(170, "vI2S2_RXD"),
|
||||
/* GPP_C */
|
||||
PINCTRL_PIN(171, "SMBCLK"),
|
||||
PINCTRL_PIN(172, "SMBDATA"),
|
||||
PINCTRL_PIN(173, "SMBALERTB"),
|
||||
PINCTRL_PIN(174, "SML0CLK"),
|
||||
PINCTRL_PIN(175, "SML0DATA"),
|
||||
PINCTRL_PIN(176, "SML0ALERTB"),
|
||||
PINCTRL_PIN(177, "SML1CLK"),
|
||||
PINCTRL_PIN(178, "SML1DATA"),
|
||||
PINCTRL_PIN(179, "UART0_RXD"),
|
||||
PINCTRL_PIN(180, "UART0_TXD"),
|
||||
PINCTRL_PIN(181, "UART0_RTSB"),
|
||||
PINCTRL_PIN(182, "UART0_CTSB"),
|
||||
PINCTRL_PIN(183, "UART1_RXD"),
|
||||
PINCTRL_PIN(184, "UART1_TXD"),
|
||||
PINCTRL_PIN(185, "UART1_RTSB"),
|
||||
PINCTRL_PIN(186, "UART1_CTSB"),
|
||||
PINCTRL_PIN(187, "I2C0_SDA"),
|
||||
PINCTRL_PIN(188, "I2C0_SCL"),
|
||||
PINCTRL_PIN(189, "I2C1_SDA"),
|
||||
PINCTRL_PIN(190, "I2C1_SCL"),
|
||||
PINCTRL_PIN(191, "UART2_RXD"),
|
||||
PINCTRL_PIN(192, "UART2_TXD"),
|
||||
PINCTRL_PIN(193, "UART2_RTSB"),
|
||||
PINCTRL_PIN(194, "UART2_CTSB"),
|
||||
/* GPP_F */
|
||||
PINCTRL_PIN(195, "CNV_BRI_DT"),
|
||||
PINCTRL_PIN(196, "CNV_BRI_RSP"),
|
||||
PINCTRL_PIN(197, "CNV_RGI_DT"),
|
||||
PINCTRL_PIN(198, "CNV_RGI_RSP"),
|
||||
PINCTRL_PIN(199, "CNV_RF_RESET_B"),
|
||||
PINCTRL_PIN(200, "GPPC_F_5"),
|
||||
PINCTRL_PIN(201, "CNV_PA_BLANKING"),
|
||||
PINCTRL_PIN(202, "GPPC_F_7"),
|
||||
PINCTRL_PIN(203, "I2S_MCLK2_INOUT"),
|
||||
PINCTRL_PIN(204, "BOOTMPC"),
|
||||
PINCTRL_PIN(205, "GPPC_F_10"),
|
||||
PINCTRL_PIN(206, "GPPC_F_11"),
|
||||
PINCTRL_PIN(207, "GSXDOUT"),
|
||||
PINCTRL_PIN(208, "GSXSLOAD"),
|
||||
PINCTRL_PIN(209, "GSXDIN"),
|
||||
PINCTRL_PIN(210, "GSXSRESETB"),
|
||||
PINCTRL_PIN(211, "GSXCLK"),
|
||||
PINCTRL_PIN(212, "GMII_MDC"),
|
||||
PINCTRL_PIN(213, "GMII_MDIO"),
|
||||
PINCTRL_PIN(214, "SRCCLKREQB_6"),
|
||||
PINCTRL_PIN(215, "EXT_PWR_GATEB"),
|
||||
PINCTRL_PIN(216, "EXT_PWR_GATE2B"),
|
||||
PINCTRL_PIN(217, "VNN_CTRL"),
|
||||
PINCTRL_PIN(218, "V1P05_CTRL"),
|
||||
PINCTRL_PIN(219, "GPPF_CLK_LOOPBACK"),
|
||||
/* HVCMOS */
|
||||
PINCTRL_PIN(220, "L_BKLTEN"),
|
||||
PINCTRL_PIN(221, "L_BKLTCTL"),
|
||||
PINCTRL_PIN(222, "L_VDDEN"),
|
||||
PINCTRL_PIN(223, "SYS_PWROK"),
|
||||
PINCTRL_PIN(224, "SYS_RESETB"),
|
||||
PINCTRL_PIN(225, "MLK_RSTB"),
|
||||
/* GPP_E */
|
||||
PINCTRL_PIN(226, "SATAXPCIE_0"),
|
||||
PINCTRL_PIN(227, "SPI1_IO_2"),
|
||||
PINCTRL_PIN(228, "SPI1_IO_3"),
|
||||
PINCTRL_PIN(229, "CPU_GP_0"),
|
||||
PINCTRL_PIN(230, "SATA_DEVSLP_0"),
|
||||
PINCTRL_PIN(231, "SATA_DEVSLP_1"),
|
||||
PINCTRL_PIN(232, "GPPC_E_6"),
|
||||
PINCTRL_PIN(233, "CPU_GP_1"),
|
||||
PINCTRL_PIN(234, "SPI1_CS1B"),
|
||||
PINCTRL_PIN(235, "USB2_OCB_0"),
|
||||
PINCTRL_PIN(236, "SPI1_CSB"),
|
||||
PINCTRL_PIN(237, "SPI1_CLK"),
|
||||
PINCTRL_PIN(238, "SPI1_MISO_IO_1"),
|
||||
PINCTRL_PIN(239, "SPI1_MOSI_IO_0"),
|
||||
PINCTRL_PIN(240, "DDSP_HPD_A"),
|
||||
PINCTRL_PIN(241, "ISH_GP_6"),
|
||||
PINCTRL_PIN(242, "ISH_GP_7"),
|
||||
PINCTRL_PIN(243, "GPPC_E_17"),
|
||||
PINCTRL_PIN(244, "DDP1_CTRLCLK"),
|
||||
PINCTRL_PIN(245, "DDP1_CTRLDATA"),
|
||||
PINCTRL_PIN(246, "DDP2_CTRLCLK"),
|
||||
PINCTRL_PIN(247, "DDP2_CTRLDATA"),
|
||||
PINCTRL_PIN(248, "DDPA_CTRLCLK"),
|
||||
PINCTRL_PIN(249, "DDPA_CTRLDATA"),
|
||||
PINCTRL_PIN(250, "SPI1_CLK_LOOPBK"),
|
||||
/* JTAG */
|
||||
PINCTRL_PIN(251, "JTAG_TDO"),
|
||||
PINCTRL_PIN(252, "JTAGX"),
|
||||
PINCTRL_PIN(253, "PRDYB"),
|
||||
PINCTRL_PIN(254, "PREQB"),
|
||||
PINCTRL_PIN(255, "CPU_TRSTB"),
|
||||
PINCTRL_PIN(256, "JTAG_TDI"),
|
||||
PINCTRL_PIN(257, "JTAG_TMS"),
|
||||
PINCTRL_PIN(258, "JTAG_TCK"),
|
||||
PINCTRL_PIN(259, "DBG_PMODE"),
|
||||
/* GPP_R */
|
||||
PINCTRL_PIN(260, "HDA_BCLK"),
|
||||
PINCTRL_PIN(261, "HDA_SYNC"),
|
||||
PINCTRL_PIN(262, "HDA_SDO"),
|
||||
PINCTRL_PIN(263, "HDA_SDI_0"),
|
||||
PINCTRL_PIN(264, "HDA_RSTB"),
|
||||
PINCTRL_PIN(265, "HDA_SDI_1"),
|
||||
PINCTRL_PIN(266, "GPP_R_6"),
|
||||
PINCTRL_PIN(267, "GPP_R_7"),
|
||||
/* SPI */
|
||||
PINCTRL_PIN(268, "SPI0_IO_2"),
|
||||
PINCTRL_PIN(269, "SPI0_IO_3"),
|
||||
PINCTRL_PIN(270, "SPI0_MOSI_IO_0"),
|
||||
PINCTRL_PIN(271, "SPI0_MISO_IO_1"),
|
||||
PINCTRL_PIN(272, "SPI0_TPM_CSB"),
|
||||
PINCTRL_PIN(273, "SPI0_FLASH_0_CSB"),
|
||||
PINCTRL_PIN(274, "SPI0_FLASH_1_CSB"),
|
||||
PINCTRL_PIN(275, "SPI0_CLK"),
|
||||
PINCTRL_PIN(276, "SPI0_CLK_LOOPBK"),
|
||||
};
|
||||
|
||||
static const struct intel_padgroup tgllp_community0_gpps[] = {
|
||||
TGL_GPP(0, 0, 25), /* GPP_B */
|
||||
TGL_GPP(1, 26, 41), /* GPP_T */
|
||||
TGL_GPP(2, 42, 66), /* GPP_A */
|
||||
};
|
||||
|
||||
static const struct intel_community tgllp_community0[] = {
|
||||
TGL_COMMUNITY(0, 66, tgllp_community0_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data tgllp_community0_soc_data = {
|
||||
.uid = "0",
|
||||
.pins = tgllp_community0_pins,
|
||||
.npins = ARRAY_SIZE(tgllp_community0_pins),
|
||||
.communities = tgllp_community0,
|
||||
.ncommunities = ARRAY_SIZE(tgllp_community0),
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc tgllp_community1_pins[] = {
|
||||
/* GPP_S */
|
||||
PINCTRL_PIN(0, "SNDW0_CLK"),
|
||||
PINCTRL_PIN(1, "SNDW0_DATA"),
|
||||
PINCTRL_PIN(2, "SNDW1_CLK"),
|
||||
PINCTRL_PIN(3, "SNDW1_DATA"),
|
||||
PINCTRL_PIN(4, "SNDW2_CLK"),
|
||||
PINCTRL_PIN(5, "SNDW2_DATA"),
|
||||
PINCTRL_PIN(6, "SNDW3_CLK"),
|
||||
PINCTRL_PIN(7, "SNDW3_DATA"),
|
||||
/* GPP_H */
|
||||
PINCTRL_PIN(8, "GPPC_H_0"),
|
||||
PINCTRL_PIN(9, "GPPC_H_1"),
|
||||
PINCTRL_PIN(10, "GPPC_H_2"),
|
||||
PINCTRL_PIN(11, "SX_EXIT_HOLDOFFB"),
|
||||
PINCTRL_PIN(12, "I2C2_SDA"),
|
||||
PINCTRL_PIN(13, "I2C2_SCL"),
|
||||
PINCTRL_PIN(14, "I2C3_SDA"),
|
||||
PINCTRL_PIN(15, "I2C3_SCL"),
|
||||
PINCTRL_PIN(16, "I2C4_SDA"),
|
||||
PINCTRL_PIN(17, "I2C4_SCL"),
|
||||
PINCTRL_PIN(18, "SRCCLKREQB_4"),
|
||||
PINCTRL_PIN(19, "SRCCLKREQB_5"),
|
||||
PINCTRL_PIN(20, "M2_SKT2_CFG_0"),
|
||||
PINCTRL_PIN(21, "M2_SKT2_CFG_1"),
|
||||
PINCTRL_PIN(22, "M2_SKT2_CFG_2"),
|
||||
PINCTRL_PIN(23, "M2_SKT2_CFG_3"),
|
||||
PINCTRL_PIN(24, "DDPB_CTRLCLK"),
|
||||
PINCTRL_PIN(25, "DDPB_CTRLDATA"),
|
||||
PINCTRL_PIN(26, "CPU_C10_GATEB"),
|
||||
PINCTRL_PIN(27, "TIME_SYNC_0"),
|
||||
PINCTRL_PIN(28, "IMGCLKOUT_1"),
|
||||
PINCTRL_PIN(29, "IMGCLKOUT_2"),
|
||||
PINCTRL_PIN(30, "IMGCLKOUT_3"),
|
||||
PINCTRL_PIN(31, "IMGCLKOUT_4"),
|
||||
/* GPP_D */
|
||||
PINCTRL_PIN(32, "ISH_GP_0"),
|
||||
PINCTRL_PIN(33, "ISH_GP_1"),
|
||||
PINCTRL_PIN(34, "ISH_GP_2"),
|
||||
PINCTRL_PIN(35, "ISH_GP_3"),
|
||||
PINCTRL_PIN(36, "IMGCLKOUT_0"),
|
||||
PINCTRL_PIN(37, "SRCCLKREQB_0"),
|
||||
PINCTRL_PIN(38, "SRCCLKREQB_1"),
|
||||
PINCTRL_PIN(39, "SRCCLKREQB_2"),
|
||||
PINCTRL_PIN(40, "SRCCLKREQB_3"),
|
||||
PINCTRL_PIN(41, "ISH_SPI_CSB"),
|
||||
PINCTRL_PIN(42, "ISH_SPI_CLK"),
|
||||
PINCTRL_PIN(43, "ISH_SPI_MISO"),
|
||||
PINCTRL_PIN(44, "ISH_SPI_MOSI"),
|
||||
PINCTRL_PIN(45, "ISH_UART0_RXD"),
|
||||
PINCTRL_PIN(46, "ISH_UART0_TXD"),
|
||||
PINCTRL_PIN(47, "ISH_UART0_RTSB"),
|
||||
PINCTRL_PIN(48, "ISH_UART0_CTSB"),
|
||||
PINCTRL_PIN(49, "ISH_GP_4"),
|
||||
PINCTRL_PIN(50, "ISH_GP_5"),
|
||||
PINCTRL_PIN(51, "I2S_MCLK1_OUT"),
|
||||
PINCTRL_PIN(52, "GSPI2_CLK_LOOPBK"),
|
||||
/* GPP_U */
|
||||
PINCTRL_PIN(53, "UART3_RXD"),
|
||||
PINCTRL_PIN(54, "UART3_TXD"),
|
||||
PINCTRL_PIN(55, "UART3_RTSB"),
|
||||
PINCTRL_PIN(56, "UART3_CTSB"),
|
||||
PINCTRL_PIN(57, "GSPI3_CS0B"),
|
||||
PINCTRL_PIN(58, "GSPI3_CLK"),
|
||||
PINCTRL_PIN(59, "GSPI3_MISO"),
|
||||
PINCTRL_PIN(60, "GSPI3_MOSI"),
|
||||
PINCTRL_PIN(61, "GSPI4_CS0B"),
|
||||
PINCTRL_PIN(62, "GSPI4_CLK"),
|
||||
PINCTRL_PIN(63, "GSPI4_MISO"),
|
||||
PINCTRL_PIN(64, "GSPI4_MOSI"),
|
||||
PINCTRL_PIN(65, "GSPI5_CS0B"),
|
||||
PINCTRL_PIN(66, "GSPI5_CLK"),
|
||||
PINCTRL_PIN(67, "GSPI5_MISO"),
|
||||
PINCTRL_PIN(68, "GSPI5_MOSI"),
|
||||
PINCTRL_PIN(69, "GSPI6_CS0B"),
|
||||
PINCTRL_PIN(70, "GSPI6_CLK"),
|
||||
PINCTRL_PIN(71, "GSPI6_MISO"),
|
||||
PINCTRL_PIN(72, "GSPI6_MOSI"),
|
||||
PINCTRL_PIN(73, "GSPI3_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(74, "GSPI4_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(75, "GSPI5_CLK_LOOPBK"),
|
||||
PINCTRL_PIN(76, "GSPI6_CLK_LOOPBK"),
|
||||
/* vGPIO */
|
||||
PINCTRL_PIN(77, "CNV_BTEN"),
|
||||
PINCTRL_PIN(78, "CNV_BT_HOST_WAKEB"),
|
||||
PINCTRL_PIN(79, "CNV_BT_IF_SELECT"),
|
||||
PINCTRL_PIN(80, "vCNV_BT_UART_TXD"),
|
||||
PINCTRL_PIN(81, "vCNV_BT_UART_RXD"),
|
||||
PINCTRL_PIN(82, "vCNV_BT_UART_CTS_B"),
|
||||
PINCTRL_PIN(83, "vCNV_BT_UART_RTS_B"),
|
||||
PINCTRL_PIN(84, "vCNV_MFUART1_TXD"),
|
||||
PINCTRL_PIN(85, "vCNV_MFUART1_RXD"),
|
||||
PINCTRL_PIN(86, "vCNV_MFUART1_CTS_B"),
|
||||
PINCTRL_PIN(87, "vCNV_MFUART1_RTS_B"),
|
||||
PINCTRL_PIN(88, "vUART0_TXD"),
|
||||
PINCTRL_PIN(89, "vUART0_RXD"),
|
||||
PINCTRL_PIN(90, "vUART0_CTS_B"),
|
||||
PINCTRL_PIN(91, "vUART0_RTS_B"),
|
||||
PINCTRL_PIN(92, "vISH_UART0_TXD"),
|
||||
PINCTRL_PIN(93, "vISH_UART0_RXD"),
|
||||
PINCTRL_PIN(94, "vISH_UART0_CTS_B"),
|
||||
PINCTRL_PIN(95, "vISH_UART0_RTS_B"),
|
||||
PINCTRL_PIN(96, "vCNV_BT_I2S_BCLK"),
|
||||
PINCTRL_PIN(97, "vCNV_BT_I2S_WS_SYNC"),
|
||||
PINCTRL_PIN(98, "vCNV_BT_I2S_SDO"),
|
||||
PINCTRL_PIN(99, "vCNV_BT_I2S_SDI"),
|
||||
PINCTRL_PIN(100, "vI2S2_SCLK"),
|
||||
PINCTRL_PIN(101, "vI2S2_SFRM"),
|
||||
PINCTRL_PIN(102, "vI2S2_TXD"),
|
||||
PINCTRL_PIN(103, "vI2S2_RXD"),
|
||||
TGL_GPP(0, 0, 25, 0), /* GPP_B */
|
||||
TGL_GPP(1, 26, 41, 32), /* GPP_T */
|
||||
TGL_GPP(2, 42, 66, 64), /* GPP_A */
|
||||
};
|
||||
|
||||
static const struct intel_padgroup tgllp_community1_gpps[] = {
|
||||
TGL_GPP(0, 0, 7), /* GPP_S */
|
||||
TGL_GPP(1, 8, 31), /* GPP_H */
|
||||
TGL_GPP(2, 32, 52), /* GPP_D */
|
||||
TGL_GPP(3, 53, 76), /* GPP_U */
|
||||
TGL_GPP(4, 77, 103), /* vGPIO */
|
||||
};
|
||||
|
||||
static const struct intel_community tgllp_community1[] = {
|
||||
TGL_COMMUNITY(0, 103, tgllp_community1_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data tgllp_community1_soc_data = {
|
||||
.uid = "1",
|
||||
.pins = tgllp_community1_pins,
|
||||
.npins = ARRAY_SIZE(tgllp_community1_pins),
|
||||
.communities = tgllp_community1,
|
||||
.ncommunities = ARRAY_SIZE(tgllp_community1),
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc tgllp_community4_pins[] = {
|
||||
/* GPP_C */
|
||||
PINCTRL_PIN(0, "SMBCLK"),
|
||||
PINCTRL_PIN(1, "SMBDATA"),
|
||||
PINCTRL_PIN(2, "SMBALERTB"),
|
||||
PINCTRL_PIN(3, "SML0CLK"),
|
||||
PINCTRL_PIN(4, "SML0DATA"),
|
||||
PINCTRL_PIN(5, "SML0ALERTB"),
|
||||
PINCTRL_PIN(6, "SML1CLK"),
|
||||
PINCTRL_PIN(7, "SML1DATA"),
|
||||
PINCTRL_PIN(8, "UART0_RXD"),
|
||||
PINCTRL_PIN(9, "UART0_TXD"),
|
||||
PINCTRL_PIN(10, "UART0_RTSB"),
|
||||
PINCTRL_PIN(11, "UART0_CTSB"),
|
||||
PINCTRL_PIN(12, "UART1_RXD"),
|
||||
PINCTRL_PIN(13, "UART1_TXD"),
|
||||
PINCTRL_PIN(14, "UART1_RTSB"),
|
||||
PINCTRL_PIN(15, "UART1_CTSB"),
|
||||
PINCTRL_PIN(16, "I2C0_SDA"),
|
||||
PINCTRL_PIN(17, "I2C0_SCL"),
|
||||
PINCTRL_PIN(18, "I2C1_SDA"),
|
||||
PINCTRL_PIN(19, "I2C1_SCL"),
|
||||
PINCTRL_PIN(20, "UART2_RXD"),
|
||||
PINCTRL_PIN(21, "UART2_TXD"),
|
||||
PINCTRL_PIN(22, "UART2_RTSB"),
|
||||
PINCTRL_PIN(23, "UART2_CTSB"),
|
||||
/* GPP_F */
|
||||
PINCTRL_PIN(24, "CNV_BRI_DT"),
|
||||
PINCTRL_PIN(25, "CNV_BRI_RSP"),
|
||||
PINCTRL_PIN(26, "CNV_RGI_DT"),
|
||||
PINCTRL_PIN(27, "CNV_RGI_RSP"),
|
||||
PINCTRL_PIN(28, "CNV_RF_RESET_B"),
|
||||
PINCTRL_PIN(29, "GPPC_F_5"),
|
||||
PINCTRL_PIN(30, "CNV_PA_BLANKING"),
|
||||
PINCTRL_PIN(31, "GPPC_F_7"),
|
||||
PINCTRL_PIN(32, "I2S_MCLK2_INOUT"),
|
||||
PINCTRL_PIN(33, "BOOTMPC"),
|
||||
PINCTRL_PIN(34, "GPPC_F_10"),
|
||||
PINCTRL_PIN(35, "GPPC_F_11"),
|
||||
PINCTRL_PIN(36, "GSXDOUT"),
|
||||
PINCTRL_PIN(37, "GSXSLOAD"),
|
||||
PINCTRL_PIN(38, "GSXDIN"),
|
||||
PINCTRL_PIN(39, "GSXSRESETB"),
|
||||
PINCTRL_PIN(40, "GSXCLK"),
|
||||
PINCTRL_PIN(41, "GMII_MDC"),
|
||||
PINCTRL_PIN(42, "GMII_MDIO"),
|
||||
PINCTRL_PIN(43, "SRCCLKREQB_6"),
|
||||
PINCTRL_PIN(44, "EXT_PWR_GATEB"),
|
||||
PINCTRL_PIN(45, "EXT_PWR_GATE2B"),
|
||||
PINCTRL_PIN(46, "VNN_CTRL"),
|
||||
PINCTRL_PIN(47, "V1P05_CTRL"),
|
||||
PINCTRL_PIN(48, "GPPF_CLK_LOOPBACK"),
|
||||
/* HVCMOS */
|
||||
PINCTRL_PIN(49, "L_BKLTEN"),
|
||||
PINCTRL_PIN(50, "L_BKLTCTL"),
|
||||
PINCTRL_PIN(51, "L_VDDEN"),
|
||||
PINCTRL_PIN(52, "SYS_PWROK"),
|
||||
PINCTRL_PIN(53, "SYS_RESETB"),
|
||||
PINCTRL_PIN(54, "MLK_RSTB"),
|
||||
/* GPP_E */
|
||||
PINCTRL_PIN(55, "SATAXPCIE_0"),
|
||||
PINCTRL_PIN(56, "SPI1_IO_2"),
|
||||
PINCTRL_PIN(57, "SPI1_IO_3"),
|
||||
PINCTRL_PIN(58, "CPU_GP_0"),
|
||||
PINCTRL_PIN(59, "SATA_DEVSLP_0"),
|
||||
PINCTRL_PIN(60, "SATA_DEVSLP_1"),
|
||||
PINCTRL_PIN(61, "GPPC_E_6"),
|
||||
PINCTRL_PIN(62, "CPU_GP_1"),
|
||||
PINCTRL_PIN(63, "SPI1_CS1B"),
|
||||
PINCTRL_PIN(64, "USB2_OCB_0"),
|
||||
PINCTRL_PIN(65, "SPI1_CSB"),
|
||||
PINCTRL_PIN(66, "SPI1_CLK"),
|
||||
PINCTRL_PIN(67, "SPI1_MISO_IO_1"),
|
||||
PINCTRL_PIN(68, "SPI1_MOSI_IO_0"),
|
||||
PINCTRL_PIN(69, "DDSP_HPD_A"),
|
||||
PINCTRL_PIN(70, "ISH_GP_6"),
|
||||
PINCTRL_PIN(71, "ISH_GP_7"),
|
||||
PINCTRL_PIN(72, "GPPC_E_17"),
|
||||
PINCTRL_PIN(73, "DDP1_CTRLCLK"),
|
||||
PINCTRL_PIN(74, "DDP1_CTRLDATA"),
|
||||
PINCTRL_PIN(75, "DDP2_CTRLCLK"),
|
||||
PINCTRL_PIN(76, "DDP2_CTRLDATA"),
|
||||
PINCTRL_PIN(77, "DDPA_CTRLCLK"),
|
||||
PINCTRL_PIN(78, "DDPA_CTRLDATA"),
|
||||
PINCTRL_PIN(79, "SPI1_CLK_LOOPBK"),
|
||||
/* JTAG */
|
||||
PINCTRL_PIN(80, "JTAG_TDO"),
|
||||
PINCTRL_PIN(81, "JTAGX"),
|
||||
PINCTRL_PIN(82, "PRDYB"),
|
||||
PINCTRL_PIN(83, "PREQB"),
|
||||
PINCTRL_PIN(84, "CPU_TRSTB"),
|
||||
PINCTRL_PIN(85, "JTAG_TDI"),
|
||||
PINCTRL_PIN(86, "JTAG_TMS"),
|
||||
PINCTRL_PIN(87, "JTAG_TCK"),
|
||||
PINCTRL_PIN(88, "DBG_PMODE"),
|
||||
TGL_GPP(0, 67, 74, 96), /* GPP_S */
|
||||
TGL_GPP(1, 75, 98, 128), /* GPP_H */
|
||||
TGL_GPP(2, 99, 119, 160), /* GPP_D */
|
||||
TGL_GPP(3, 120, 143, 192), /* GPP_U */
|
||||
TGL_GPP(4, 144, 170, 224), /* vGPIO */
|
||||
};
|
||||
|
||||
static const struct intel_padgroup tgllp_community4_gpps[] = {
|
||||
TGL_GPP(0, 0, 23), /* GPP_C */
|
||||
TGL_GPP(1, 24, 48), /* GPP_F */
|
||||
TGL_GPP(2, 49, 54), /* HVCMOS */
|
||||
TGL_GPP(3, 55, 79), /* GPP_E */
|
||||
TGL_GPP(4, 80, 88), /* JTAG */
|
||||
};
|
||||
|
||||
static const struct intel_community tgllp_community4[] = {
|
||||
TGL_COMMUNITY(0, 88, tgllp_community4_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data tgllp_community4_soc_data = {
|
||||
.uid = "4",
|
||||
.pins = tgllp_community4_pins,
|
||||
.npins = ARRAY_SIZE(tgllp_community4_pins),
|
||||
.communities = tgllp_community4,
|
||||
.ncommunities = ARRAY_SIZE(tgllp_community4),
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc tgllp_community5_pins[] = {
|
||||
/* GPP_R */
|
||||
PINCTRL_PIN(0, "HDA_BCLK"),
|
||||
PINCTRL_PIN(1, "HDA_SYNC"),
|
||||
PINCTRL_PIN(2, "HDA_SDO"),
|
||||
PINCTRL_PIN(3, "HDA_SDI_0"),
|
||||
PINCTRL_PIN(4, "HDA_RSTB"),
|
||||
PINCTRL_PIN(5, "HDA_SDI_1"),
|
||||
PINCTRL_PIN(6, "GPP_R_6"),
|
||||
PINCTRL_PIN(7, "GPP_R_7"),
|
||||
/* SPI */
|
||||
PINCTRL_PIN(8, "SPI0_IO_2"),
|
||||
PINCTRL_PIN(9, "SPI0_IO_3"),
|
||||
PINCTRL_PIN(10, "SPI0_MOSI_IO_0"),
|
||||
PINCTRL_PIN(11, "SPI0_MISO_IO_1"),
|
||||
PINCTRL_PIN(12, "SPI0_TPM_CSB"),
|
||||
PINCTRL_PIN(13, "SPI0_FLASH_0_CSB"),
|
||||
PINCTRL_PIN(14, "SPI0_FLASH_1_CSB"),
|
||||
PINCTRL_PIN(15, "SPI0_CLK"),
|
||||
PINCTRL_PIN(16, "SPI0_CLK_LOOPBK"),
|
||||
TGL_GPP(0, 171, 194, 256), /* GPP_C */
|
||||
TGL_GPP(1, 195, 219, 288), /* GPP_F */
|
||||
TGL_GPP(2, 220, 225, TGL_NO_GPIO), /* HVCMOS */
|
||||
TGL_GPP(3, 226, 250, 320), /* GPP_E */
|
||||
TGL_GPP(4, 251, 259, TGL_NO_GPIO), /* JTAG */
|
||||
};
|
||||
|
||||
static const struct intel_padgroup tgllp_community5_gpps[] = {
|
||||
TGL_GPP(0, 0, 7), /* GPP_R */
|
||||
TGL_GPP(1, 8, 16), /* SPI */
|
||||
TGL_GPP(0, 260, 267, 352), /* GPP_R */
|
||||
TGL_GPP(1, 268, 276, TGL_NO_GPIO), /* SPI */
|
||||
};
|
||||
|
||||
static const struct intel_community tgllp_community5[] = {
|
||||
TGL_COMMUNITY(0, 16, tgllp_community5_gpps),
|
||||
static const struct intel_community tgllp_communities[] = {
|
||||
TGL_COMMUNITY(0, 0, 66, tgllp_community0_gpps),
|
||||
TGL_COMMUNITY(1, 67, 170, tgllp_community1_gpps),
|
||||
TGL_COMMUNITY(2, 171, 259, tgllp_community4_gpps),
|
||||
TGL_COMMUNITY(3, 260, 276, tgllp_community5_gpps),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data tgllp_community5_soc_data = {
|
||||
.uid = "5",
|
||||
.pins = tgllp_community5_pins,
|
||||
.npins = ARRAY_SIZE(tgllp_community5_pins),
|
||||
.communities = tgllp_community5,
|
||||
.ncommunities = ARRAY_SIZE(tgllp_community5),
|
||||
};
|
||||
|
||||
static const struct intel_pinctrl_soc_data *tgllp_soc_data_array[] = {
|
||||
&tgllp_community0_soc_data,
|
||||
&tgllp_community1_soc_data,
|
||||
&tgllp_community4_soc_data,
|
||||
&tgllp_community5_soc_data,
|
||||
NULL
|
||||
static const struct intel_pinctrl_soc_data tgllp_soc_data = {
|
||||
.pins = tgllp_pins,
|
||||
.npins = ARRAY_SIZE(tgllp_pins),
|
||||
.communities = tgllp_communities,
|
||||
.ncommunities = ARRAY_SIZE(tgllp_communities),
|
||||
};
|
||||
|
||||
static const struct acpi_device_id tgl_pinctrl_acpi_match[] = {
|
||||
{ "INT34C5", (kernel_ulong_t)tgllp_soc_data_array },
|
||||
{ "INT34C5", (kernel_ulong_t)&tgllp_soc_data },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match);
|
||||
|
@ -438,7 +391,7 @@ MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match);
|
|||
static INTEL_PINCTRL_PM_OPS(tgl_pinctrl_pm_ops);
|
||||
|
||||
static struct platform_driver tgl_pinctrl_driver = {
|
||||
.probe = intel_pinctrl_probe_by_uid,
|
||||
.probe = intel_pinctrl_probe_by_hid,
|
||||
.driver = {
|
||||
.name = "tigerlake-pinctrl",
|
||||
.acpi_match_table = tgl_pinctrl_acpi_match,
|
||||
|
|
Loading…
Reference in a new issue