diff options
Diffstat (limited to 'drivers/pinctrl/zte/pinctrl-zx.h')
-rw-r--r-- | drivers/pinctrl/zte/pinctrl-zx.h | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/pinctrl/zte/pinctrl-zx.h b/drivers/pinctrl/zte/pinctrl-zx.h new file mode 100644 index 000000000000..bc67e2be0503 --- /dev/null +++ b/drivers/pinctrl/zte/pinctrl-zx.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2017 Sanechips Technology Co., Ltd. + * Copyright 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#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 */ |