/*
* Pinctrl driver for NXP LPC18xx/LPC43xx System Control Unit (SCU)
*
* Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
#include "pinctrl-utils.h"
/* LPC18XX SCU analog function registers */
#define LPC18XX_SCU_REG_ENAIO0 0xc88
#define LPC18XX_SCU_REG_ENAIO1 0xc8c
#define LPC18XX_SCU_REG_ENAIO2 0xc90
#define LPC18XX_SCU_REG_ENAIO2_DAC BIT(0)
/* LPC18XX SCU pin register definitions */
#define LPC18XX_SCU_PIN_MODE_MASK 0x7
#define LPC18XX_SCU_PIN_EPD BIT(3)
#define LPC18XX_SCU_PIN_EPUN BIT(4)
#define LPC18XX_SCU_PIN_EHS BIT(5)
#define LPC18XX_SCU_PIN_EZI BIT(6)
#define LPC18XX_SCU_PIN_ZIF BIT(7)
#define LPC18XX_SCU_PIN_EHD_MASK 0x300
#define LPC18XX_SCU_PIN_EHD_POS 8
#define LPC18XX_SCU_USB1_EPD BIT(2)
#define LPC18XX_SCU_USB1_EPWR BIT(4)
#define LPC18XX_SCU_I2C0_EFP BIT(0)
#define LPC18XX_SCU_I2C0_EHD BIT(2)
#define LPC18XX_SCU_I2C0_EZI BIT(3)
#define LPC18XX_SCU_I2C0_ZIF BIT(7)
#define LPC18XX_SCU_I2C0_SCL_SHIFT 0
#define LPC18XX_SCU_I2C0_SDA_SHIFT 8
#define LPC18XX_SCU_FUNC_PER_PIN 8
/* LPC18XX SCU pin interrupt select registers */
#define LPC18XX_SCU_PINTSEL0 0xe00
#define LPC18XX_SCU_PINTSEL1 0xe04
#define LPC18XX_SCU_PINTSEL_VAL_MASK 0xff
#define LPC18XX_SCU_PINTSEL_PORT_SHIFT 5
#define LPC18XX_SCU_IRQ_PER_PINTSEL 4
#define LPC18XX_GPIO_PINS_PER_PORT 32
#define LPC18XX_GPIO_PIN_INT_MAX 8
#define LPC18XX_SCU_PINTSEL_VAL(val, n) \
((val) << (((n) % LPC18XX_SCU_IRQ_PER_PINTSEL) * 8))
/* LPC18xx pin types */
enum {
TYPE_ND, /* Normal-drive */
TYPE_HD, /* High-drive */
TYPE_HS, /* High-speed */
TYPE_I2C0,
TYPE_USB1,
};
/* LPC18xx pin functions */
enum {
FUNC_R, /* Reserved */
FUNC_ADC,
FUNC_ADCTRIG,
FUNC_CAN0,
FUNC_CAN1,
FUNC_CGU_OUT,
FUNC_CLKIN,
FUNC_CLKOUT,
FUNC_CTIN,
FUNC_CTOUT,
FUNC_DAC,
FUNC_EMC,
FUNC_EMC_ALT,
FUNC_ENET,
FUNC_ENET_ALT,
FUNC_GPIO,
FUNC_I2C0,
FUNC_I2C1,
FUNC_I2S0_RX_MCLK,
FUNC_I2S0_RX_SCK,
FUNC_I2S0_RX_SDA,
FUNC_I2S0_RX_WS,
FUNC_I2S0_TX_MCLK,
FUNC_I2S0_TX_SCK,
FUNC_I2S0_TX_SDA,
FUNC_I2S0_TX_WS,
FUNC_I2S1,
FUNC_LCD,
FUNC_LCD_ALT,
FUNC_MCTRL,
FUNC_NMI,
FUNC_QEI,
FUNC_SDMMC,
FUNC_SGPIO,
FUNC_SPI,
FUNC_SPIFI,
FUNC_SSP0,
FUNC_SSP0_ALT,
FUNC_SSP1,
FUNC_TIMER0,
FUNC_TIMER1,
FUNC_TIMER2,
FUNC_TIMER3,
FUNC_TRACE,
FUNC_UART0,
FUNC_UART1,
FUNC_UART2,
FUNC_UART3,
FUNC_USB0,
FUNC_USB1,
FUNC_MAX
};
static const char *const lpc18xx_function_names[] = {
[FUNC_R] = "reserved",
[FUNC_ADC] = "adc",
[FUNC_ADCTRIG] = "adctrig",
[FUNC_CAN0