/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2017 Sanechips Technology Co., Ltd. * Copyright 2017 Linaro Ltd. */ #ifndef __PINCTRL_ZX_H #define __PINCTRL_ZX_H /** * struct zx_mux_desc - hardware mux descriptor * @name: mux function name * @muxval: mux register bit value */ struct zx_mux_desc { const char *name; u8 muxval; }; /** * struct zx_pin_data - hardware per-pin data * @aon_pin: whether it's an AON pin * @offset: register offset within TOP pinmux controller * @bitpos: bit position within TOP pinmux register * @width: bit width within TOP pinmux register * @coffset: pinconf register offset within AON controller * @cbitpos: pinconf bit position within AON register * @muxes: available mux function names and corresponding register values * * Unlike TOP pinmux and AON pinconf registers which are arranged pretty * arbitrarily, AON pinmux register bits are well organized per pin id, and * each pin occupies two bits, so that we can calculate the AON register offset * and bit position from pin id. Thus, we only need to define TOP pinmux and * AON pinconf register data for the pin. */ struct zx_pin_data { bool aon_pin; u16 offset; u16 bitpos; u16 width; u16 coffset; u16 cbitpos; struct zx_mux_desc *muxes; }; struct zx_pinctrl_soc_info { const struct pinctrl_pin_desc *pins; unsigned int npins; }; #define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) { \ .number = pin, \ .name = #pin, \ .drv_data = &(struct zx_pin_data) { \ .aon_pin = false, \ .offset = off, \ .bitpos = bp, \ .width = wd, \ .coffset = coff, \ .cbitpos = cbp, \ .muxes = (struct zx_mux_desc[]) { \ __VA_ARGS__, { } }, \ }, \ } #define AON_PIN(pin, off, bp, wd, coff, cbp, ...) { \ .number = pin, \ .name = #pin, \ .drv_data = &(struct zx_pin_data) { \ .aon_pin = true, \ .offset = off, \ .bitpos = bp, \ .width = wd, \ .coffset = coff, \ .cbitpos = cbp, \ .muxes = (struct zx_mux_desc[]) { \ __VA_ARGS__, { } }, \ }, \ } #define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin) #define TOP_MUX(_val, _name) { \ .name = _name, \ .muxval = _val, \ } /* * When the flag is set, it's a mux configuration for an AON pin that sits in * AON register. Otherwise, it's one for AON pin but sitting in TOP register. */ #define AON_MUX_FLAG BIT(7) #define AON_MUX(_val, _name) { \ .name = _name, \ .muxval = _val | AON_MUX_FLAG, \ } int zx_pinctrl_init(struct platform_device *pdev, struct zx_pinctrl_soc_info *info); #endif /* __PINCTRL_ZX_H */