1 /* 2 * Copyright (C) 2017 Sanechips Technology Co., Ltd. 3 * Copyright 2017 Linaro Ltd. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10 #ifndef __PINCTRL_ZX_H 11 #define __PINCTRL_ZX_H 12 13 /** 14 * struct zx_mux_desc - hardware mux descriptor 15 * @name: mux function name 16 * @muxval: mux register bit value 17 */ 18 struct zx_mux_desc { 19 const char *name; 20 u8 muxval; 21 }; 22 23 /** 24 * struct zx_pin_data - hardware per-pin data 25 * @aon_pin: whether it's an AON pin 26 * @offset: register offset within TOP pinmux controller 27 * @bitpos: bit position within TOP pinmux register 28 * @width: bit width within TOP pinmux register 29 * @coffset: pinconf register offset within AON controller 30 * @cbitpos: pinconf bit position within AON register 31 * @muxes: available mux function names and corresponding register values 32 * 33 * Unlike TOP pinmux and AON pinconf registers which are arranged pretty 34 * arbitrarily, AON pinmux register bits are well organized per pin id, and 35 * each pin occupies two bits, so that we can calculate the AON register offset 36 * and bit position from pin id. Thus, we only need to define TOP pinmux and 37 * AON pinconf register data for the pin. 38 */ 39 struct zx_pin_data { 40 bool aon_pin; 41 u16 offset; 42 u16 bitpos; 43 u16 width; 44 u16 coffset; 45 u16 cbitpos; 46 struct zx_mux_desc *muxes; 47 }; 48 49 struct zx_pinctrl_soc_info { 50 const struct pinctrl_pin_desc *pins; 51 unsigned int npins; 52 }; 53 54 #define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) { \ 55 .number = pin, \ 56 .name = #pin, \ 57 .drv_data = &(struct zx_pin_data) { \ 58 .aon_pin = false, \ 59 .offset = off, \ 60 .bitpos = bp, \ 61 .width = wd, \ 62 .coffset = coff, \ 63 .cbitpos = cbp, \ 64 .muxes = (struct zx_mux_desc[]) { \ 65 __VA_ARGS__, { } }, \ 66 }, \ 67 } 68 69 #define AON_PIN(pin, off, bp, wd, coff, cbp, ...) { \ 70 .number = pin, \ 71 .name = #pin, \ 72 .drv_data = &(struct zx_pin_data) { \ 73 .aon_pin = true, \ 74 .offset = off, \ 75 .bitpos = bp, \ 76 .width = wd, \ 77 .coffset = coff, \ 78 .cbitpos = cbp, \ 79 .muxes = (struct zx_mux_desc[]) { \ 80 __VA_ARGS__, { } }, \ 81 }, \ 82 } 83 84 #define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin) 85 86 #define TOP_MUX(_val, _name) { \ 87 .name = _name, \ 88 .muxval = _val, \ 89 } 90 91 /* 92 * When the flag is set, it's a mux configuration for an AON pin that sits in 93 * AON register. Otherwise, it's one for AON pin but sitting in TOP register. 94 */ 95 #define AON_MUX_FLAG BIT(7) 96 97 #define AON_MUX(_val, _name) { \ 98 .name = _name, \ 99 .muxval = _val | AON_MUX_FLAG, \ 100 } 101 102 int zx_pinctrl_init(struct platform_device *pdev, 103 struct zx_pinctrl_soc_info *info); 104 105 #endif /* __PINCTRL_ZX_H */ 106