diff options
author | 2023-02-21 18:24:12 -0800 | |
---|---|---|
committer | 2023-02-21 18:24:12 -0800 | |
commit | 5b7c4cabbb65f5c469464da6c5f614cbd7f730f2 (patch) | |
tree | cc5c2d0a898769fd59549594fedb3ee6f84e59a0 /drivers/pinctrl/visconti | |
download | linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.tar.gz linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.zip |
Merge tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-nextgrafted
Pull networking updates from Jakub Kicinski:
"Core:
- Add dedicated kmem_cache for typical/small skb->head, avoid having
to access struct page at kfree time, and improve memory use.
- Introduce sysctl to set default RPS configuration for new netdevs.
- Define Netlink protocol specification format which can be used to
describe messages used by each family and auto-generate parsers.
Add tools for generating kernel data structures and uAPI headers.
- Expose all net/core sysctls inside netns.
- Remove 4s sleep in netpoll if carrier is instantly detected on
boot.
- Add configurable limit of MDB entries per port, and port-vlan.
- Continue populating drop reasons throughout the stack.
- Retire a handful of legacy Qdiscs and classifiers.
Protocols:
- Support IPv4 big TCP (TSO frames larger than 64kB).
- Add IP_LOCAL_PORT_RANGE socket option, to control local port range
on socket by socket basis.
- Track and report in procfs number of MPTCP sockets used.
- Support mixing IPv4 and IPv6 flows in the in-kernel MPTCP path
manager.
- IPv6: don't check net.ipv6.route.max_size and rely on garbage
collection to free memory (similarly to IPv4).
- Support Penultimate Segment Pop (PSP) flavor in SRv6 (RFC8986).
- ICMP: add per-rate limit counters.
- Add support for user scanning requests in ieee802154.
- Remove static WEP support.
- Support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate
reporting.
- WiFi 7 EHT channel puncturing support (client & AP).
BPF:
- Add a rbtree data structure following the "next-gen data structure"
precedent set by recently added linked list, that is, by using
kfunc + kptr instead of adding a new BPF map type.
- Expose XDP hints via kfuncs with initial support for RX hash and
timestamp metadata.
- Add BPF_F_NO_TUNNEL_KEY extension to bpf_skb_set_tunnel_key to
better support decap on GRE tunnel devices not operating in collect
metadata.
- Improve x86 JIT's codegen for PROBE_MEM runtime error checks.
- Remove the need for trace_printk_lock for bpf_trace_printk and
bpf_trace_vprintk helpers.
- Extend libbpf's bpf_tracing.h support for tracing arguments of
kprobes/uprobes and syscall as a special case.
- Significantly reduce the search time for module symbols by
livepatch and BPF.
- Enable cpumasks to be used as kptrs, which is useful for tracing
programs tracking which tasks end up running on which CPUs in
different time intervals.
- Add support for BPF trampoline on s390x and riscv64.
- Add capability to export the XDP features supported by the NIC.
- Add __bpf_kfunc tag for marking kernel functions as kfuncs.
- Add cgroup.memory=nobpf kernel parameter option to disable BPF
memory accounting for container environments.
Netfilter:
- Remove the CLUSTERIP target. It has been marked as obsolete for
years, and we still have WARN splats wrt races of the out-of-band
/proc interface installed by this target.
- Add 'destroy' commands to nf_tables. They are identical to the
existing 'delete' commands, but do not return an error if the
referenced object (set, chain, rule...) did not exist.
Driver API:
- Improve cpumask_local_spread() locality to help NICs set the right
IRQ affinity on AMD platforms.
- Separate C22 and C45 MDIO bus transactions more clearly.
- Introduce new DCB table to control DSCP rewrite on egress.
- Support configuration of Physical Layer Collision Avoidance (PLCA)
Reconciliation Sublayer (RS) (802.3cg-2019). Modern version of
shared medium Ethernet.
- Support for MAC Merge layer (IEEE 802.3-2018 clause 99). Allowing
preemption of low priority frames by high priority frames.
- Add support for controlling MACSec offload using netlink SET.
- Rework devlink instance refcounts to allow registration and
de-registration under the instance lock. Split the code into
multiple files, drop some of the unnecessarily granular locks and
factor out common parts of netlink operation handling.
- Add TX frame aggregation parameters (for USB drivers).
- Add a new attr TCA_EXT_WARN_MSG to report TC (offload) warning
messages with notifications for debug.
- Allow offloading of UDP NEW connections via act_ct.
- Add support for per action HW stats in TC.
- Support hardware miss to TC action (continue processing in SW from
a specific point in the action chain).
- Warn if old Wireless Extension user space interface is used with
modern cfg80211/mac80211 drivers. Do not support Wireless
Extensions for Wi-Fi 7 devices at all. Everyone should switch to
using nl80211 interface instead.
- Improve the CAN bit timing configuration. Use extack to return
error messages directly to user space, update the SJW handling,
including the definition of a new default value that will benefit
CAN-FD controllers, by increasing their oscillator tolerance.
New hardware / drivers:
- Ethernet:
- nVidia BlueField-3 support (control traffic driver)
- Ethernet support for imx93 SoCs
- Motorcomm yt8531 gigabit Ethernet PHY
- onsemi NCN26000 10BASE-T1S PHY (with support for PLCA)
- Microchip LAN8841 PHY (incl. cable diagnostics and PTP)
- Amlogic gxl MDIO mux
- WiFi:
- RealTek RTL8188EU (rtl8xxxu)
- Qualcomm Wi-Fi 7 devices (ath12k)
- CAN:
- Renesas R-Car V4H
Drivers:
- Bluetooth:
- Set Per Platform Antenna Gain (PPAG) for Intel controllers.
- Ethernet NICs:
- Intel (1G, igc):
- support TSN / Qbv / packet scheduling features of i226 model
- Intel (100G, ice):
- use GNSS subsystem instead of TTY
- multi-buffer XDP support
- extend support for GPIO pins to E823 devices
- nVidia/Mellanox:
- update the shared buffer configuration on PFC commands
- implement PTP adjphase function for HW offset control
- TC support for Geneve and GRE with VF tunnel offload
- more efficient crypto key management method
- multi-port eswitch support
- Netronome/Corigine:
- add DCB IEEE support
- support IPsec offloading for NFP3800
- Freescale/NXP (enetc):
- support XDP_REDIRECT for XDP non-linear buffers
- improve reconfig, avoid link flap and waiting for idle
- support MAC Merge layer
- Other NICs:
- sfc/ef100: add basic devlink support for ef100
- ionic: rx_push mode operation (writing descriptors via MMIO)
- bnxt: use the auxiliary bus abstraction for RDMA
- r8169: disable ASPM and reset bus in case of tx timeout
- cpsw: support QSGMII mode for J721e CPSW9G
- cpts: support pulse-per-second output
- ngbe: add an mdio bus driver
- usbnet: optimize usbnet_bh() by avoiding unnecessary queuing
- r8152: handle devices with FW with NCM support
- amd-xgbe: support 10Mbps, 2.5GbE speeds and rx-adaptation
- virtio-net: support multi buffer XDP
- virtio/vsock: replace virtio_vsock_pkt with sk_buff
- tsnep: XDP support
- Ethernet high-speed switches:
- nVidia/Mellanox (mlxsw):
- add support for latency TLV (in FW control messages)
- Microchip (sparx5):
- separate explicit and implicit traffic forwarding rules, make
the implicit rules always active
- add support for egress DSCP rewrite
- IS0 VCAP support (Ingress Classification)
- IS2 VCAP filters (protos, L3 addrs, L4 ports, flags, ToS
etc.)
- ES2 VCAP support (Egress Access Control)
- support for Per-Stream Filtering and Policing (802.1Q,
8.6.5.1)
- Ethernet embedded switches:
- Marvell (mv88e6xxx):
- add MAB (port auth) offload support
- enable PTP receive for mv88e6390
- NXP (ocelot):
- support MAC Merge layer
- support for the the vsc7512 internal copper phys
- Microchip:
- lan9303: convert to PHYLINK
- lan966x: support TC flower filter statistics
- lan937x: PTP support for KSZ9563/KSZ8563 and LAN937x
- lan937x: support Credit Based Shaper configuration
- ksz9477: support Energy Efficient Ethernet
- other:
- qca8k: convert to regmap read/write API, use bulk operations
- rswitch: Improve TX timestamp accuracy
- Intel WiFi (iwlwifi):
- EHT (Wi-Fi 7) rate reporting
- STEP equalizer support: transfer some STEP (connection to radio
on platforms with integrated wifi) related parameters from the
BIOS to the firmware.
- Qualcomm 802.11ax WiFi (ath11k):
- IPQ5018 support
- Fine Timing Measurement (FTM) responder role support
- channel 177 support
- MediaTek WiFi (mt76):
- per-PHY LED support
- mt7996: EHT (Wi-Fi 7) support
- Wireless Ethernet Dispatch (WED) reset support
- switch to using page pool allocator
- RealTek WiFi (rtw89):
- support new version of Bluetooth co-existance
- Mobile:
- rmnet: support TX aggregation"
* tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1872 commits)
page_pool: add a comment explaining the fragment counter usage
net: ethtool: fix __ethtool_dev_mm_supported() implementation
ethtool: pse-pd: Fix double word in comments
xsk: add linux/vmalloc.h to xsk.c
sefltests: netdevsim: wait for devlink instance after netns removal
selftest: fib_tests: Always cleanup before exit
net/mlx5e: Align IPsec ASO result memory to be as required by hardware
net/mlx5e: TC, Set CT miss to the specific ct action instance
net/mlx5e: Rename CHAIN_TO_REG to MAPPED_OBJ_TO_REG
net/mlx5: Refactor tc miss handling to a single function
net/mlx5: Kconfig: Make tc offload depend on tc skb extension
net/sched: flower: Support hardware miss to tc action
net/sched: flower: Move filter handle initialization earlier
net/sched: cls_api: Support hardware miss to tc action
net/sched: Rename user cookie and act cookie
sfc: fix builds without CONFIG_RTC_LIB
sfc: clean up some inconsistent indentings
net/mlx4_en: Introduce flexible array to silence overflow warning
net: lan966x: Fix possible deadlock inside PTP
net/ulp: Remove redundant ->clone() test in inet_clone_ulp().
...
Diffstat (limited to '')
-rw-r--r-- | drivers/pinctrl/visconti/Kconfig | 14 | ||||
-rw-r--r-- | drivers/pinctrl/visconti/Makefile | 3 | ||||
-rw-r--r-- | drivers/pinctrl/visconti/pinctrl-common.c | 328 | ||||
-rw-r--r-- | drivers/pinctrl/visconti/pinctrl-common.h | 96 | ||||
-rw-r--r-- | drivers/pinctrl/visconti/pinctrl-tmpv7700.c | 355 |
5 files changed, 796 insertions, 0 deletions
diff --git a/drivers/pinctrl/visconti/Kconfig b/drivers/pinctrl/visconti/Kconfig new file mode 100644 index 000000000..42653fc60 --- /dev/null +++ b/drivers/pinctrl/visconti/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-only +config PINCTRL_VISCONTI + bool + select PINMUX + select GENERIC_PINCONF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + +config PINCTRL_TMPV7700 + bool "Toshiba Visconti TMPV7700 series pinctrl driver" + depends on OF + depends on ARCH_VISCONTI || COMPILE_TEST + select PINCTRL_VISCONTI + default ARCH_VISCONTI diff --git a/drivers/pinctrl/visconti/Makefile b/drivers/pinctrl/visconti/Makefile new file mode 100644 index 000000000..43b2eb663 --- /dev/null +++ b/drivers/pinctrl/visconti/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PINCTRL_VISCONTI) += pinctrl-common.o +obj-$(CONFIG_PINCTRL_TMPV7700) += pinctrl-tmpv7700.o diff --git a/drivers/pinctrl/visconti/pinctrl-common.c b/drivers/pinctrl/visconti/pinctrl-common.c new file mode 100644 index 000000000..21c7e0d18 --- /dev/null +++ b/drivers/pinctrl/visconti/pinctrl-common.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 TOSHIBA CORPORATION + * Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation + * Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> + */ + +#include <linux/init.h> +#include <linux/of.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include "pinctrl-common.h" +#include "../core.h" +#include "../pinconf.h" +#include "../pinctrl-utils.h" + +#define DSEL_MASK GENMASK(3, 0) + +/* private data */ +struct visconti_pinctrl { + void __iomem *base; + struct device *dev; + struct pinctrl_dev *pctl; + struct pinctrl_desc pctl_desc; + + const struct visconti_pinctrl_devdata *devdata; + + spinlock_t lock; /* protect pinctrl register */ +}; + +/* pinconf */ +static int visconti_pin_config_set(struct pinctrl_dev *pctldev, + unsigned int _pin, + unsigned long *configs, + unsigned int num_configs) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + const struct visconti_desc_pin *pin = &priv->devdata->pins[_pin]; + enum pin_config_param param; + unsigned int arg; + int i, ret = 0; + unsigned int val, set_val, pude_val; + unsigned long flags; + + dev_dbg(priv->dev, "%s: pin = %d (%s)\n", __func__, _pin, pin->pin.name); + + spin_lock_irqsave(&priv->lock, flags); + + for (i = 0; i < num_configs; i++) { + set_val = 0; + pude_val = 0; + + param = pinconf_to_config_param(configs[i]); + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + set_val = 1; + fallthrough; + case PIN_CONFIG_BIAS_PULL_DOWN: + /* update pudsel setting */ + val = readl(priv->base + pin->pudsel_offset); + val &= ~BIT(pin->pud_shift); + val |= set_val << pin->pud_shift; + writel(val, priv->base + pin->pudsel_offset); + pude_val = 1; + fallthrough; + case PIN_CONFIG_BIAS_DISABLE: + /* update pude setting */ + val = readl(priv->base + pin->pude_offset); + val &= ~BIT(pin->pud_shift); + val |= pude_val << pin->pud_shift; + writel(val, priv->base + pin->pude_offset); + dev_dbg(priv->dev, "BIAS(%d): off = 0x%x val = 0x%x\n", + param, pin->pude_offset, val); + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + arg = pinconf_to_config_argument(configs[i]); + dev_dbg(priv->dev, "DRV_STR arg = %d\n", arg); + switch (arg) { + case 2: + case 4: + case 8: + case 16: + case 24: + case 32: + /* + * I/O drive capacity setting: + * 2mA: 0 + * 4mA: 1 + * 8mA: 3 + * 16mA: 7 + * 24mA: 11 + * 32mA: 15 + */ + set_val = DIV_ROUND_CLOSEST(arg, 2) - 1; + break; + default: + ret = -EINVAL; + goto err; + } + /* update drive setting */ + val = readl(priv->base + pin->dsel_offset); + val &= ~(DSEL_MASK << pin->dsel_shift); + val |= set_val << pin->dsel_shift; + writel(val, priv->base + pin->dsel_offset); + break; + + default: + ret = -EOPNOTSUPP; + goto err; + } + } +err: + spin_unlock_irqrestore(&priv->lock, flags); + return ret; +} + +static int visconti_pin_config_group_set(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *configs, + unsigned int num_configs) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + const unsigned int *pins; + unsigned int num_pins; + int i, ret; + + pins = priv->devdata->groups[selector].pins; + num_pins = priv->devdata->groups[selector].nr_pins; + + dev_dbg(priv->dev, "%s: select = %d, n_pin = %d, n_config = %d\n", + __func__, selector, num_pins, num_configs); + + for (i = 0; i < num_pins; i++) { + ret = visconti_pin_config_set(pctldev, pins[i], + configs, num_configs); + if (ret) + return ret; + } + + return 0; +} +static const struct pinconf_ops visconti_pinconf_ops = { + .is_generic = true, + .pin_config_set = visconti_pin_config_set, + .pin_config_group_set = visconti_pin_config_group_set, + .pin_config_config_dbg_show = pinconf_generic_dump_config, +}; + +/* pinctrl */ +static int visconti_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + + return priv->devdata->nr_groups; +} + +static const char *visconti_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + + return priv->devdata->groups[selector].name; +} + +static int visconti_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + + *pins = priv->devdata->groups[selector].pins; + *num_pins = priv->devdata->groups[selector].nr_pins; + + return 0; +} + +static const struct pinctrl_ops visconti_pinctrl_ops = { + .get_groups_count = visconti_get_groups_count, + .get_group_name = visconti_get_group_name, + .get_group_pins = visconti_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinctrl_utils_free_map, +}; + +/* pinmux */ +static int visconti_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + + return priv->devdata->nr_functions; +} + +static const char *visconti_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + + return priv->devdata->functions[selector].name; +} + +static int visconti_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned * const num_groups) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + + *groups = priv->devdata->functions[selector].groups; + *num_groups = priv->devdata->functions[selector].nr_groups; + + return 0; +} + +static int visconti_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + const struct visconti_pin_function *func = &priv->devdata->functions[function]; + const struct visconti_pin_group *grp = &priv->devdata->groups[group]; + const struct visconti_mux *mux = &grp->mux; + unsigned int val; + unsigned long flags; + + dev_dbg(priv->dev, "%s: function = %d(%s) group = %d(%s)\n", __func__, + function, func->name, group, grp->name); + + spin_lock_irqsave(&priv->lock, flags); + + /* update mux */ + val = readl(priv->base + mux->offset); + val &= ~mux->mask; + val |= mux->val; + writel(val, priv->base + mux->offset); + + spin_unlock_irqrestore(&priv->lock, flags); + + dev_dbg(priv->dev, "[%x]: 0x%x\n", mux->offset, val); + + return 0; +} + +static int visconti_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct visconti_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev); + const struct visconti_mux *gpio_mux = &priv->devdata->gpio_mux[pin]; + unsigned long flags; + unsigned int val; + + dev_dbg(priv->dev, "%s: pin = %d\n", __func__, pin); + + /* update mux */ + spin_lock_irqsave(&priv->lock, flags); + val = readl(priv->base + gpio_mux->offset); + val &= ~gpio_mux->mask; + val |= gpio_mux->val; + writel(val, priv->base + gpio_mux->offset); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static const struct pinmux_ops visconti_pinmux_ops = { + .get_functions_count = visconti_get_functions_count, + .get_function_name = visconti_get_function_name, + .get_function_groups = visconti_get_function_groups, + .set_mux = visconti_set_mux, + .gpio_request_enable = visconti_gpio_request_enable, + .strict = true, +}; + +int visconti_pinctrl_probe(struct platform_device *pdev, + const struct visconti_pinctrl_devdata *devdata) +{ + struct device *dev = &pdev->dev; + struct visconti_pinctrl *priv; + struct pinctrl_pin_desc *pins; + int i, ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->devdata = devdata; + spin_lock_init(&priv->lock); + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) { + dev_err(dev, "unable to map I/O space\n"); + return PTR_ERR(priv->base); + } + + pins = devm_kcalloc(dev, devdata->nr_pins, + sizeof(*pins), GFP_KERNEL); + if (!pins) + return -ENOMEM; + + for (i = 0; i < devdata->nr_pins; i++) + pins[i] = devdata->pins[i].pin; + + priv->pctl_desc.name = dev_name(dev); + priv->pctl_desc.owner = THIS_MODULE; + priv->pctl_desc.pins = pins; + priv->pctl_desc.npins = devdata->nr_pins; + priv->pctl_desc.confops = &visconti_pinconf_ops; + priv->pctl_desc.pctlops = &visconti_pinctrl_ops; + priv->pctl_desc.pmxops = &visconti_pinmux_ops; + + ret = devm_pinctrl_register_and_init(dev, &priv->pctl_desc, + priv, &priv->pctl); + if (ret) { + dev_err(dev, "couldn't register pinctrl: %d\n", ret); + return ret; + } + + if (devdata->unlock) + devdata->unlock(priv->base); + + return pinctrl_enable(priv->pctl); +} diff --git a/drivers/pinctrl/visconti/pinctrl-common.h b/drivers/pinctrl/visconti/pinctrl-common.h new file mode 100644 index 000000000..56a2eb022 --- /dev/null +++ b/drivers/pinctrl/visconti/pinctrl-common.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 TOSHIBA CORPORATION + * Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation + * Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> + */ + +#ifndef __VISCONTI_PINCTRL_COMMON_H__ +#define __VISCONTI_PINCTRL_COMMON_H__ + +struct pinctrl_pin_desc; + +/* PIN */ +#define VISCONTI_PINS(pins_name, ...) \ + static const unsigned int pins_name ## _pins[] = { __VA_ARGS__ } + +struct visconti_desc_pin { + struct pinctrl_pin_desc pin; + unsigned int dsel_offset; + unsigned int dsel_shift; + unsigned int pude_offset; + unsigned int pudsel_offset; + unsigned int pud_shift; +}; + +#define VISCONTI_PIN(_pin, dsel, d_sh, pude, pudsel, p_sh) \ +{ \ + .pin = _pin, \ + .dsel_offset = dsel, \ + .dsel_shift = d_sh, \ + .pude_offset = pude, \ + .pudsel_offset = pudsel, \ + .pud_shift = p_sh, \ +} + +/* Group */ +#define VISCONTI_GROUPS(groups_name, ...) \ + static const char * const groups_name ## _grps[] = { __VA_ARGS__ } + +struct visconti_mux { + unsigned int offset; + unsigned int mask; + unsigned int val; +}; + +struct visconti_pin_group { + const char *name; + const unsigned int *pins; + unsigned int nr_pins; + struct visconti_mux mux; +}; + +#define VISCONTI_PIN_GROUP(group_name, off, msk, v) \ +{ \ + .name = __stringify(group_name) "_grp", \ + .pins = group_name ## _pins, \ + .nr_pins = ARRAY_SIZE(group_name ## _pins), \ + .mux = { \ + .offset = off, \ + .mask = msk, \ + .val = v, \ + } \ +} + +/* MUX */ +struct visconti_pin_function { + const char *name; + const char * const *groups; + unsigned int nr_groups; +}; + +#define VISCONTI_PIN_FUNCTION(func) \ +{ \ + .name = #func, \ + .groups = func ## _grps, \ + .nr_groups = ARRAY_SIZE(func ## _grps), \ +} + +/* chip dependent data */ +struct visconti_pinctrl_devdata { + const struct visconti_desc_pin *pins; + unsigned int nr_pins; + const struct visconti_pin_group *groups; + unsigned int nr_groups; + const struct visconti_pin_function *functions; + unsigned int nr_functions; + + const struct visconti_mux *gpio_mux; + + void (*unlock)(void __iomem *base); +}; + +int visconti_pinctrl_probe(struct platform_device *pdev, + const struct visconti_pinctrl_devdata *devdata); + +#endif /* __VISCONTI_PINCTRL_COMMON_H__ */ diff --git a/drivers/pinctrl/visconti/pinctrl-tmpv7700.c b/drivers/pinctrl/visconti/pinctrl-tmpv7700.c new file mode 100644 index 000000000..38a00d514 --- /dev/null +++ b/drivers/pinctrl/visconti/pinctrl-tmpv7700.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 TOSHIBA CORPORATION + * Copyright (c) 2020 Toshiba Electronic Devices & Storage Corporation + * Copyright (c) 2020 Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> + */ + +#include <linux/init.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pinctrl/pinctrl.h> +#include "pinctrl-common.h" + +#define tmpv7700_MAGIC_NUM 0x4932f70e + +/* register offset */ +#define REG_KEY_CTRL 0x0000 +#define REG_KEY_CMD 0x0004 +#define REG_PINMUX1 0x3000 +#define REG_PINMUX2 0x3004 +#define REG_PINMUX3 0x3008 +#define REG_PINMUX4 0x300c +#define REG_PINMUX5 0x3010 +#define REG_IOSET 0x3014 +#define REG_IO_VSEL 0x3018 +#define REG_IO_DSEL1 0x301c +#define REG_IO_DSEL2 0x3020 +#define REG_IO_DSEL3 0x3024 +#define REG_IO_DSEL4 0x3028 +#define REG_IO_DSEL5 0x302c +#define REG_IO_DSEL6 0x3030 +#define REG_IO_DSEL7 0x3034 +#define REG_IO_DSEL8 0x3038 +#define REG_IO_PUDE1 0x303c +#define REG_IO_PUDE2 0x3040 +#define REG_IO_PUDSEL1 0x3044 +#define REG_IO_PUDSEL2 0x3048 + +/* PIN */ +static const struct visconti_desc_pin pins_tmpv7700[] = { + VISCONTI_PIN(PINCTRL_PIN(0, "gpio0"), REG_IO_DSEL4, 24, + REG_IO_PUDE1, REG_IO_PUDSEL1, 30), + VISCONTI_PIN(PINCTRL_PIN(1, "gpio1"), REG_IO_DSEL4, 28, + REG_IO_PUDE1, REG_IO_PUDSEL1, 31), + VISCONTI_PIN(PINCTRL_PIN(2, "gpio2"), REG_IO_DSEL5, 0, + REG_IO_PUDE2, REG_IO_PUDSEL2, 0), + VISCONTI_PIN(PINCTRL_PIN(3, "gpio3"), REG_IO_DSEL5, 4, + REG_IO_PUDE2, REG_IO_PUDSEL2, 1), + VISCONTI_PIN(PINCTRL_PIN(4, "gpio4"), REG_IO_DSEL5, 8, + REG_IO_PUDE2, REG_IO_PUDSEL2, 2), + VISCONTI_PIN(PINCTRL_PIN(5, "gpio5"), REG_IO_DSEL5, 12, + REG_IO_PUDE2, REG_IO_PUDSEL2, 3), + VISCONTI_PIN(PINCTRL_PIN(6, "gpio6"), REG_IO_DSEL5, 16, + REG_IO_PUDE2, REG_IO_PUDSEL2, 4), + VISCONTI_PIN(PINCTRL_PIN(7, "gpio7"), REG_IO_DSEL5, 20, + REG_IO_PUDE2, REG_IO_PUDSEL2, 5), + VISCONTI_PIN(PINCTRL_PIN(8, "gpio8"), REG_IO_DSEL5, 24, + REG_IO_PUDE2, REG_IO_PUDSEL2, 6), + VISCONTI_PIN(PINCTRL_PIN(9, "gpio9"), REG_IO_DSEL5, 28, + REG_IO_PUDE2, REG_IO_PUDSEL2, 7), + VISCONTI_PIN(PINCTRL_PIN(10, "gpio10"), REG_IO_DSEL6, 0, + REG_IO_PUDE2, REG_IO_PUDSEL2, 8), + VISCONTI_PIN(PINCTRL_PIN(11, "gpio11"), REG_IO_DSEL6, 4, + REG_IO_PUDE2, REG_IO_PUDSEL2, 9), + VISCONTI_PIN(PINCTRL_PIN(12, "gpio12"), REG_IO_DSEL6, 8, + REG_IO_PUDE2, REG_IO_PUDSEL2, 10), + VISCONTI_PIN(PINCTRL_PIN(13, "gpio13"), REG_IO_DSEL6, 12, + REG_IO_PUDE2, REG_IO_PUDSEL2, 11), + VISCONTI_PIN(PINCTRL_PIN(14, "gpio14"), REG_IO_DSEL6, 16, + REG_IO_PUDE2, REG_IO_PUDSEL2, 12), + VISCONTI_PIN(PINCTRL_PIN(15, "gpio15"), REG_IO_DSEL6, 20, + REG_IO_PUDE2, REG_IO_PUDSEL2, 13), + VISCONTI_PIN(PINCTRL_PIN(16, "gpio16"), REG_IO_DSEL6, 24, + REG_IO_PUDE2, REG_IO_PUDSEL2, 14), + VISCONTI_PIN(PINCTRL_PIN(17, "gpio17"), REG_IO_DSEL6, 28, + REG_IO_PUDE2, REG_IO_PUDSEL2, 15), + VISCONTI_PIN(PINCTRL_PIN(18, "gpio18"), REG_IO_DSEL7, 0, + REG_IO_PUDE2, REG_IO_PUDSEL2, 16), + VISCONTI_PIN(PINCTRL_PIN(19, "gpio19"), REG_IO_DSEL7, 4, + REG_IO_PUDE2, REG_IO_PUDSEL2, 17), + VISCONTI_PIN(PINCTRL_PIN(20, "gpio20"), REG_IO_DSEL7, 8, + REG_IO_PUDE2, REG_IO_PUDSEL2, 18), + VISCONTI_PIN(PINCTRL_PIN(21, "gpio21"), REG_IO_DSEL7, 12, + REG_IO_PUDE2, REG_IO_PUDSEL2, 19), + VISCONTI_PIN(PINCTRL_PIN(22, "gpio22"), REG_IO_DSEL7, 16, + REG_IO_PUDE2, REG_IO_PUDSEL2, 20), + VISCONTI_PIN(PINCTRL_PIN(23, "gpio23"), REG_IO_DSEL7, 20, + REG_IO_PUDE2, REG_IO_PUDSEL2, 21), + VISCONTI_PIN(PINCTRL_PIN(24, "gpio24"), REG_IO_DSEL7, 24, + REG_IO_PUDE2, REG_IO_PUDSEL2, 22), + VISCONTI_PIN(PINCTRL_PIN(25, "gpio25"), REG_IO_DSEL7, 28, + REG_IO_PUDE2, REG_IO_PUDSEL2, 23), + VISCONTI_PIN(PINCTRL_PIN(26, "gpio26"), REG_IO_DSEL8, 0, + REG_IO_PUDE2, REG_IO_PUDSEL2, 24), + VISCONTI_PIN(PINCTRL_PIN(27, "gpio27"), REG_IO_DSEL8, 4, + REG_IO_PUDE2, REG_IO_PUDSEL2, 25), + VISCONTI_PIN(PINCTRL_PIN(28, "gpio28"), REG_IO_DSEL8, 8, + REG_IO_PUDE2, REG_IO_PUDSEL2, 26), + VISCONTI_PIN(PINCTRL_PIN(29, "gpio29"), REG_IO_DSEL4, 8, + REG_IO_PUDE1, REG_IO_PUDSEL1, 26), + VISCONTI_PIN(PINCTRL_PIN(30, "gpio30"), REG_IO_DSEL4, 4, + REG_IO_PUDE1, REG_IO_PUDSEL1, 25), + VISCONTI_PIN(PINCTRL_PIN(31, "gpio31"), REG_IO_DSEL4, 0, + REG_IO_PUDE1, REG_IO_PUDSEL1, 24), + VISCONTI_PIN(PINCTRL_PIN(32, "spi_sck"), REG_IO_DSEL4, 12, + REG_IO_PUDE1, REG_IO_PUDSEL1, 27), + VISCONTI_PIN(PINCTRL_PIN(33, "spi_sdo"), REG_IO_DSEL4, 16, + REG_IO_PUDE1, REG_IO_PUDSEL1, 28), + VISCONTI_PIN(PINCTRL_PIN(34, "spi_sdi"), REG_IO_DSEL4, 20, + REG_IO_PUDE1, REG_IO_PUDSEL1, 29), +}; + +/* Group */ +VISCONTI_PINS(i2c0, 0, 1); +VISCONTI_PINS(i2c1, 2, 3); +VISCONTI_PINS(i2c2, 12, 13); +VISCONTI_PINS(i2c3, 14, 15); +VISCONTI_PINS(i2c4, 16, 17); +VISCONTI_PINS(i2c5, 18, 19); +VISCONTI_PINS(i2c6, 33, 34); +VISCONTI_PINS(i2c7, 29, 32); +VISCONTI_PINS(i2c8, 30, 31); +VISCONTI_PINS(spi0_cs0, 29); +VISCONTI_PINS(spi0_cs1, 30); +VISCONTI_PINS(spi0_cs2, 31); +VISCONTI_PINS(spi1_cs, 3); +VISCONTI_PINS(spi2_cs, 7); +VISCONTI_PINS(spi3_cs, 11); +VISCONTI_PINS(spi4_cs, 15); +VISCONTI_PINS(spi5_cs, 19); +VISCONTI_PINS(spi6_cs, 27); +VISCONTI_PINS(spi0, 32, 33, 34); +VISCONTI_PINS(spi1, 0, 1, 2); +VISCONTI_PINS(spi2, 4, 5, 6); +VISCONTI_PINS(spi3, 8, 9, 10); +VISCONTI_PINS(spi4, 12, 13, 14); +VISCONTI_PINS(spi5, 16, 17, 18); +VISCONTI_PINS(spi6, 24, 25, 26); +VISCONTI_PINS(uart0, 4, 5, 6, 7); +VISCONTI_PINS(uart1, 8, 9, 10, 11); +VISCONTI_PINS(uart2, 12, 13, 14, 15); +VISCONTI_PINS(uart3, 16, 17, 18, 19); +VISCONTI_PINS(pwm0_gpio4, 4); +VISCONTI_PINS(pwm1_gpio5, 5); +VISCONTI_PINS(pwm2_gpio6, 6); +VISCONTI_PINS(pwm3_gpio7, 7); +VISCONTI_PINS(pwm0_gpio8, 8); +VISCONTI_PINS(pwm1_gpio9, 9); +VISCONTI_PINS(pwm2_gpio10, 10); +VISCONTI_PINS(pwm3_gpio11, 11); +VISCONTI_PINS(pwm0_gpio12, 12); +VISCONTI_PINS(pwm1_gpio13, 13); +VISCONTI_PINS(pwm2_gpio14, 14); +VISCONTI_PINS(pwm3_gpio15, 15); +VISCONTI_PINS(pwm0_gpio16, 16); +VISCONTI_PINS(pwm1_gpio17, 17); +VISCONTI_PINS(pwm2_gpio18, 18); +VISCONTI_PINS(pwm3_gpio19, 19); +VISCONTI_PINS(pcmif_out, 20, 21, 22); +VISCONTI_PINS(pcmif_in, 24, 25, 26); + +static const struct visconti_pin_group groups_tmpv7700[] = { + VISCONTI_PIN_GROUP(i2c0, REG_PINMUX2, GENMASK(7, 0), 0x00000022), + VISCONTI_PIN_GROUP(i2c1, REG_PINMUX2, GENMASK(15, 8), 0x00002200), + VISCONTI_PIN_GROUP(i2c2, REG_PINMUX3, GENMASK(23, 16), 0x00770000), + VISCONTI_PIN_GROUP(i2c3, REG_PINMUX3, GENMASK(31, 24), 0x77000000), + VISCONTI_PIN_GROUP(i2c4, REG_PINMUX4, GENMASK(7, 0), 0x00000077), + VISCONTI_PIN_GROUP(i2c5, REG_PINMUX4, GENMASK(15, 8), 0x00007700), + VISCONTI_PIN_GROUP(i2c6, REG_PINMUX1, GENMASK(3, 0), 0x0000002), + VISCONTI_PIN_GROUP(i2c7, REG_PINMUX5, GENMASK(23, 20), 0x00200000), + VISCONTI_PIN_GROUP(i2c8, REG_PINMUX5, GENMASK(31, 24), 0x22000000), + VISCONTI_PIN_GROUP(spi0_cs0, REG_PINMUX5, GENMASK(23, 20), 0x00100000), + VISCONTI_PIN_GROUP(spi0_cs1, REG_PINMUX5, GENMASK(27, 24), 0x01000000), + VISCONTI_PIN_GROUP(spi0_cs2, REG_PINMUX5, GENMASK(31, 28), 0x10000000), + VISCONTI_PIN_GROUP(spi1_cs, REG_PINMUX2, GENMASK(15, 12), 0x00001000), + VISCONTI_PIN_GROUP(spi2_cs, REG_PINMUX2, GENMASK(31, 28), 0x10000000), + VISCONTI_PIN_GROUP(spi3_cs, REG_PINMUX3, GENMASK(15, 12), 0x00001000), + VISCONTI_PIN_GROUP(spi4_cs, REG_PINMUX4, GENMASK(31, 28), 0x10000000), + VISCONTI_PIN_GROUP(spi5_cs, REG_PINMUX4, GENMASK(15, 12), 0x00001000), + VISCONTI_PIN_GROUP(spi6_cs, REG_PINMUX5, GENMASK(15, 12), 0x00001000), + VISCONTI_PIN_GROUP(spi0, REG_PINMUX1, GENMASK(3, 0), 0x00000001), + VISCONTI_PIN_GROUP(spi1, REG_PINMUX2, GENMASK(11, 0), 0x00000111), + VISCONTI_PIN_GROUP(spi2, REG_PINMUX2, GENMASK(27, 16), 0x01110000), + VISCONTI_PIN_GROUP(spi3, REG_PINMUX3, GENMASK(11, 0), 0x00000111), + VISCONTI_PIN_GROUP(spi4, REG_PINMUX3, GENMASK(27, 16), 0x01110000), + VISCONTI_PIN_GROUP(spi5, REG_PINMUX4, GENMASK(11, 0), 0x00000111), + VISCONTI_PIN_GROUP(spi6, REG_PINMUX5, GENMASK(11, 0), 0x00000111), + VISCONTI_PIN_GROUP(uart0, REG_PINMUX2, GENMASK(31, 16), 0x22220000), + VISCONTI_PIN_GROUP(uart1, REG_PINMUX3, GENMASK(15, 0), 0x00002222), + VISCONTI_PIN_GROUP(uart2, REG_PINMUX3, GENMASK(31, 16), 0x22220000), + VISCONTI_PIN_GROUP(uart3, REG_PINMUX4, GENMASK(15, 0), 0x00002222), + VISCONTI_PIN_GROUP(pwm0_gpio4, REG_PINMUX2, GENMASK(19, 16), 0x00050000), + VISCONTI_PIN_GROUP(pwm1_gpio5, REG_PINMUX2, GENMASK(23, 20), 0x00500000), + VISCONTI_PIN_GROUP(pwm2_gpio6, REG_PINMUX2, GENMASK(27, 24), 0x05000000), + VISCONTI_PIN_GROUP(pwm3_gpio7, REG_PINMUX2, GENMASK(31, 28), 0x50000000), + VISCONTI_PIN_GROUP(pwm0_gpio8, REG_PINMUX3, GENMASK(3, 0), 0x00000005), + VISCONTI_PIN_GROUP(pwm1_gpio9, REG_PINMUX3, GENMASK(7, 4), 0x00000050), + VISCONTI_PIN_GROUP(pwm2_gpio10, REG_PINMUX3, GENMASK(11, 8), 0x00000500), + VISCONTI_PIN_GROUP(pwm3_gpio11, REG_PINMUX3, GENMASK(15, 12), 0x00005000), + VISCONTI_PIN_GROUP(pwm0_gpio12, REG_PINMUX3, GENMASK(19, 16), 0x00050000), + VISCONTI_PIN_GROUP(pwm1_gpio13, REG_PINMUX3, GENMASK(23, 20), 0x00500000), + VISCONTI_PIN_GROUP(pwm2_gpio14, REG_PINMUX3, GENMASK(27, 24), 0x05000000), + VISCONTI_PIN_GROUP(pwm3_gpio15, REG_PINMUX3, GENMASK(31, 28), 0x50000000), + VISCONTI_PIN_GROUP(pwm0_gpio16, REG_PINMUX4, GENMASK(3, 0), 0x00000005), + VISCONTI_PIN_GROUP(pwm1_gpio17, REG_PINMUX4, GENMASK(7, 4), 0x00000050), + VISCONTI_PIN_GROUP(pwm2_gpio18, REG_PINMUX4, GENMASK(11, 8), 0x00000500), + VISCONTI_PIN_GROUP(pwm3_gpio19, REG_PINMUX4, GENMASK(15, 12), 0x00005000), + VISCONTI_PIN_GROUP(pcmif_out, REG_PINMUX4, GENMASK(27, 16), 0x01110000), + VISCONTI_PIN_GROUP(pcmif_in, REG_PINMUX5, GENMASK(11, 0), 0x00000222), +}; + +/* MUX */ +VISCONTI_GROUPS(i2c0, "i2c0_grp"); +VISCONTI_GROUPS(i2c1, "i2c1_grp"); +VISCONTI_GROUPS(i2c2, "i2c2_grp"); +VISCONTI_GROUPS(i2c3, "i2c3_grp"); +VISCONTI_GROUPS(i2c4, "i2c4_grp"); +VISCONTI_GROUPS(i2c5, "i2c5_grp"); +VISCONTI_GROUPS(i2c6, "i2c6_grp"); +VISCONTI_GROUPS(i2c7, "i2c7_grp"); +VISCONTI_GROUPS(i2c8, "i2c8_grp"); +VISCONTI_GROUPS(spi0, "spi0_grp", "spi0_cs0_grp", + "spi0_cs1_grp", "spi0_cs2_grp"); +VISCONTI_GROUPS(spi1, "spi1_grp", "spi1_cs_grp"); +VISCONTI_GROUPS(spi2, "spi2_grp", "spi2_cs_grp"); +VISCONTI_GROUPS(spi3, "spi3_grp", "spi3_cs_grp"); +VISCONTI_GROUPS(spi4, "spi4_grp", "spi4_cs_grp"); +VISCONTI_GROUPS(spi5, "spi5_grp", "spi5_cs_grp"); +VISCONTI_GROUPS(spi6, "spi6_grp", "spi6_cs_grp"); +VISCONTI_GROUPS(uart0, "uart0_grp"); +VISCONTI_GROUPS(uart1, "uart1_grp"); +VISCONTI_GROUPS(uart2, "uart2_grp"); +VISCONTI_GROUPS(uart3, "uart3_grp"); +VISCONTI_GROUPS(pwm, "pwm0_gpio4_grp", "pwm0_gpio8_grp", + "pwm0_gpio12_grp", "pwm0_gpio16_grp", + "pwm1_gpio5_grp", "pwm1_gpio9_grp", + "pwm1_gpio13_grp", "pwm1_gpio17_grp", + "pwm2_gpio6_grp", "pwm2_gpio10_grp", + "pwm2_gpio14_grp", "pwm2_gpio18_grp", + "pwm3_gpio7_grp", "pwm3_gpio11_grp", + "pwm3_gpio15_grp", "pwm3_gpio19_grp"); +VISCONTI_GROUPS(pcmif_out, "pcmif_out_grp"); +VISCONTI_GROUPS(pcmif_in, "pcmif_in_grp"); + +static const struct visconti_pin_function functions_tmpv7700[] = { + VISCONTI_PIN_FUNCTION(i2c0), + VISCONTI_PIN_FUNCTION(i2c1), + VISCONTI_PIN_FUNCTION(i2c2), + VISCONTI_PIN_FUNCTION(i2c3), + VISCONTI_PIN_FUNCTION(i2c4), + VISCONTI_PIN_FUNCTION(i2c5), + VISCONTI_PIN_FUNCTION(i2c6), + VISCONTI_PIN_FUNCTION(i2c7), + VISCONTI_PIN_FUNCTION(i2c8), + VISCONTI_PIN_FUNCTION(spi0), + VISCONTI_PIN_FUNCTION(spi1), + VISCONTI_PIN_FUNCTION(spi2), + VISCONTI_PIN_FUNCTION(spi3), + VISCONTI_PIN_FUNCTION(spi4), + VISCONTI_PIN_FUNCTION(spi5), + VISCONTI_PIN_FUNCTION(spi6), + VISCONTI_PIN_FUNCTION(uart0), + VISCONTI_PIN_FUNCTION(uart1), + VISCONTI_PIN_FUNCTION(uart2), + VISCONTI_PIN_FUNCTION(uart3), + VISCONTI_PIN_FUNCTION(pwm), + VISCONTI_PIN_FUNCTION(pcmif_in), + VISCONTI_PIN_FUNCTION(pcmif_out), +}; + +/* GPIO MUX */ +#define tmpv7700_GPIO_MUX(off, msk) \ +{ \ + .offset = off, \ + .mask = msk, \ + .val = 0, \ +} + +static const struct visconti_mux gpio_mux_tmpv7700[] = { + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(3, 0)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(7, 4)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(11, 8)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(15, 12)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(19, 16)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(23, 20)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(27, 24)), + tmpv7700_GPIO_MUX(REG_PINMUX2, GENMASK(31, 28)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(3, 0)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(7, 4)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(11, 8)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(15, 12)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(19, 16)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(23, 20)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(27, 24)), + tmpv7700_GPIO_MUX(REG_PINMUX3, GENMASK(31, 28)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(3, 0)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(7, 4)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(11, 8)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(15, 12)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(19, 16)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(23, 20)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(27, 24)), + tmpv7700_GPIO_MUX(REG_PINMUX4, GENMASK(31, 28)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(3, 0)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(7, 4)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(11, 8)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(15, 12)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(19, 16)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(23, 20)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(27, 24)), + tmpv7700_GPIO_MUX(REG_PINMUX5, GENMASK(31, 28)), +}; + +static void tmpv7700_pinctrl_unlock(void __iomem *base) +{ + writel(1, base + REG_KEY_CTRL); + writel(tmpv7700_MAGIC_NUM, base + REG_KEY_CMD); +} + +/* chip dependent data */ +static const struct visconti_pinctrl_devdata tmpv7700_pinctrl_data = { + .pins = pins_tmpv7700, + .nr_pins = ARRAY_SIZE(pins_tmpv7700), + .groups = groups_tmpv7700, + .nr_groups = ARRAY_SIZE(groups_tmpv7700), + .functions = functions_tmpv7700, + .nr_functions = ARRAY_SIZE(functions_tmpv7700), + .gpio_mux = gpio_mux_tmpv7700, + .unlock = tmpv7700_pinctrl_unlock, +}; + +static int tmpv7700_pinctrl_probe(struct platform_device *pdev) +{ + return visconti_pinctrl_probe(pdev, &tmpv7700_pinctrl_data); +} + +static const struct of_device_id tmpv7700_pctrl_of_match[] = { + { .compatible = "toshiba,tmpv7708-pinctrl", }, + {}, +}; + +static struct platform_driver tmpv7700_pinctrl_driver = { + .probe = tmpv7700_pinctrl_probe, + .driver = { + .name = "tmpv7700-pinctrl", + .of_match_table = tmpv7700_pctrl_of_match, + }, +}; + +static int __init tmpv7700_pinctrl_init(void) +{ + return platform_driver_register(&tmpv7700_pinctrl_driver); +} +arch_initcall(tmpv7700_pinctrl_init); |