18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Sanechips Technology Co., Ltd.
48c2ecf20Sopenharmony_ci * Copyright 2017 Linaro Ltd.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef __PINCTRL_ZX_H
88c2ecf20Sopenharmony_ci#define __PINCTRL_ZX_H
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/**
118c2ecf20Sopenharmony_ci * struct zx_mux_desc - hardware mux descriptor
128c2ecf20Sopenharmony_ci * @name: mux function name
138c2ecf20Sopenharmony_ci * @muxval: mux register bit value
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_cistruct zx_mux_desc {
168c2ecf20Sopenharmony_ci	const char *name;
178c2ecf20Sopenharmony_ci	u8 muxval;
188c2ecf20Sopenharmony_ci};
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/**
218c2ecf20Sopenharmony_ci * struct zx_pin_data - hardware per-pin data
228c2ecf20Sopenharmony_ci * @aon_pin: whether it's an AON pin
238c2ecf20Sopenharmony_ci * @offset: register offset within TOP pinmux controller
248c2ecf20Sopenharmony_ci * @bitpos: bit position within TOP pinmux register
258c2ecf20Sopenharmony_ci * @width: bit width within TOP pinmux register
268c2ecf20Sopenharmony_ci * @coffset: pinconf register offset within AON controller
278c2ecf20Sopenharmony_ci * @cbitpos: pinconf bit position within AON register
288c2ecf20Sopenharmony_ci * @muxes: available mux function names and corresponding register values
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci * Unlike TOP pinmux and AON pinconf registers which are arranged pretty
318c2ecf20Sopenharmony_ci * arbitrarily, AON pinmux register bits are well organized per pin id, and
328c2ecf20Sopenharmony_ci * each pin occupies two bits, so that we can calculate the AON register offset
338c2ecf20Sopenharmony_ci * and bit position from pin id.  Thus, we only need to define TOP pinmux and
348c2ecf20Sopenharmony_ci * AON pinconf register data for the pin.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_cistruct zx_pin_data {
378c2ecf20Sopenharmony_ci	bool aon_pin;
388c2ecf20Sopenharmony_ci	u16 offset;
398c2ecf20Sopenharmony_ci	u16 bitpos;
408c2ecf20Sopenharmony_ci	u16 width;
418c2ecf20Sopenharmony_ci	u16 coffset;
428c2ecf20Sopenharmony_ci	u16 cbitpos;
438c2ecf20Sopenharmony_ci	struct zx_mux_desc *muxes;
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cistruct zx_pinctrl_soc_info {
478c2ecf20Sopenharmony_ci	const struct pinctrl_pin_desc *pins;
488c2ecf20Sopenharmony_ci	unsigned int npins;
498c2ecf20Sopenharmony_ci};
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci#define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) {		\
528c2ecf20Sopenharmony_ci	.number = pin,						\
538c2ecf20Sopenharmony_ci	.name = #pin,						\
548c2ecf20Sopenharmony_ci	.drv_data = &(struct zx_pin_data) {			\
558c2ecf20Sopenharmony_ci		.aon_pin = false,				\
568c2ecf20Sopenharmony_ci		.offset = off,					\
578c2ecf20Sopenharmony_ci		.bitpos = bp,					\
588c2ecf20Sopenharmony_ci		.width = wd,					\
598c2ecf20Sopenharmony_ci		.coffset = coff,				\
608c2ecf20Sopenharmony_ci		.cbitpos = cbp,					\
618c2ecf20Sopenharmony_ci		.muxes = (struct zx_mux_desc[]) {		\
628c2ecf20Sopenharmony_ci			 __VA_ARGS__, { } },			\
638c2ecf20Sopenharmony_ci	},							\
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define AON_PIN(pin, off, bp, wd, coff, cbp, ...) {		\
678c2ecf20Sopenharmony_ci	.number = pin,						\
688c2ecf20Sopenharmony_ci	.name = #pin,						\
698c2ecf20Sopenharmony_ci	.drv_data = &(struct zx_pin_data) {			\
708c2ecf20Sopenharmony_ci		.aon_pin = true,				\
718c2ecf20Sopenharmony_ci		.offset = off,					\
728c2ecf20Sopenharmony_ci		.bitpos = bp,					\
738c2ecf20Sopenharmony_ci		.width = wd,					\
748c2ecf20Sopenharmony_ci		.coffset = coff,				\
758c2ecf20Sopenharmony_ci		.cbitpos = cbp,					\
768c2ecf20Sopenharmony_ci		.muxes = (struct zx_mux_desc[]) {		\
778c2ecf20Sopenharmony_ci			 __VA_ARGS__, { } },			\
788c2ecf20Sopenharmony_ci	},							\
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci#define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin)
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#define TOP_MUX(_val, _name) {					\
848c2ecf20Sopenharmony_ci	.name = _name,						\
858c2ecf20Sopenharmony_ci	.muxval = _val,						\
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/*
898c2ecf20Sopenharmony_ci * When the flag is set, it's a mux configuration for an AON pin that sits in
908c2ecf20Sopenharmony_ci * AON register.  Otherwise, it's one for AON pin but sitting in TOP register.
918c2ecf20Sopenharmony_ci */
928c2ecf20Sopenharmony_ci#define AON_MUX_FLAG BIT(7)
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci#define AON_MUX(_val, _name) {					\
958c2ecf20Sopenharmony_ci	.name = _name,						\
968c2ecf20Sopenharmony_ci	.muxval = _val | AON_MUX_FLAG,				\
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciint zx_pinctrl_init(struct platform_device *pdev,
1008c2ecf20Sopenharmony_ci		    struct zx_pinctrl_soc_info *info);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci#endif /* __PINCTRL_ZX_H */
103