sh_pfc.h 6.9 KB
Newer Older
M
Magnus Damm 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * SuperH Pin Function Controller Support
 *
 * Copyright (c) 2008 Magnus Damm
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#ifndef __SH_PFC_H
#define __SH_PFC_H

P
Paul Mundt 已提交
14
#include <linux/stringify.h>
M
Magnus Damm 已提交
15 16 17 18
#include <asm-generic/gpio.h>

typedef unsigned short pinmux_enum_t;

19 20
#define SH_PFC_MARK_INVALID	((pinmux_enum_t)-1)

21 22
enum {
	PINMUX_TYPE_NONE,
M
Magnus Damm 已提交
23

24 25 26 27 28 29 30 31 32
	PINMUX_TYPE_FUNCTION,
	PINMUX_TYPE_GPIO,
	PINMUX_TYPE_OUTPUT,
	PINMUX_TYPE_INPUT,
	PINMUX_TYPE_INPUT_PULLUP,
	PINMUX_TYPE_INPUT_PULLDOWN,

	PINMUX_FLAG_TYPE,	/* must be last */
};
M
Magnus Damm 已提交
33 34 35 36 37 38

#define PINMUX_FLAG_DBIT_SHIFT      5
#define PINMUX_FLAG_DBIT            (0x1f << PINMUX_FLAG_DBIT_SHIFT)
#define PINMUX_FLAG_DREG_SHIFT      10
#define PINMUX_FLAG_DREG            (0x3f << PINMUX_FLAG_DREG_SHIFT)

39
struct sh_pfc_pin {
40
	const pinmux_enum_t enum_id;
41
	unsigned short flags;
P
Paul Mundt 已提交
42
	const char *name;
M
Magnus Damm 已提交
43 44
};

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#define SH_PFC_PIN_GROUP(n)				\
	{						\
		.name = #n,				\
		.pins = n##_pins,			\
		.mux = n##_mux,				\
		.nr_pins = ARRAY_SIZE(n##_pins),	\
	}

struct sh_pfc_pin_group {
	const char *name;
	const unsigned int *pins;
	const unsigned int *mux;
	unsigned int nr_pins;
};

#define SH_PFC_FUNCTION(n)				\
	{						\
		.name = #n,				\
		.groups = n##_groups,			\
		.nr_groups = ARRAY_SIZE(n##_groups),	\
	}

struct sh_pfc_function {
	const char *name;
	const char * const *groups;
	unsigned int nr_groups;
};

73 74 75 76 77
struct pinmux_func {
	const pinmux_enum_t enum_id;
	const char *name;
};

78 79 80 81 82 83
#define PINMUX_GPIO(gpio, data_or_mark)			\
	[gpio] = {					\
		.name = __stringify(gpio),		\
		.enum_id = data_or_mark,		\
		.flags = PINMUX_TYPE_GPIO		\
	}
84 85
#define PINMUX_GPIO_FN(gpio, base, data_or_mark)	\
	[gpio - (base)] = {				\
86 87 88
		.name = __stringify(gpio),		\
		.enum_id = data_or_mark,		\
	}
89

M
Magnus Damm 已提交
90 91 92 93 94 95
#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0

struct pinmux_cfg_reg {
	unsigned long reg, reg_width, field_width;
	unsigned long *cnt;
	pinmux_enum_t *enum_ids;
96
	unsigned long *var_field_width;
M
Magnus Damm 已提交
97 98 99 100 101
};

#define PINMUX_CFG_REG(name, r, r_width, f_width) \
	.reg = r, .reg_width = r_width, .field_width = f_width,		\
	.cnt = (unsigned long [r_width / f_width]) {}, \
102 103 104 105 106 107 108
	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)])

#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
	.reg = r, .reg_width = r_width,	\
	.cnt = (unsigned long [r_width]) {}, \
	.var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
	.enum_ids = (pinmux_enum_t [])
M
Magnus Damm 已提交
109 110 111 112 113 114 115 116 117 118

struct pinmux_data_reg {
	unsigned long reg, reg_width, reg_shadow;
	pinmux_enum_t *enum_ids;
};

#define PINMUX_DATA_REG(name, r, r_width) \
	.reg = r, .reg_width = r_width,	\
	.enum_ids = (pinmux_enum_t [r_width]) \

M
Magnus Damm 已提交
119 120
struct pinmux_irq {
	int irq;
121
	unsigned short *gpios;
M
Magnus Damm 已提交
122 123 124
};

#define PINMUX_IRQ(irq_nr, ids...)			   \
125
	{ .irq = irq_nr, .gpios = (unsigned short []) { ids, 0 } }	\
M
Magnus Damm 已提交
126

M
Magnus Damm 已提交
127 128 129 130 131 132
struct pinmux_range {
	pinmux_enum_t begin;
	pinmux_enum_t end;
	pinmux_enum_t force;
};

133
struct sh_pfc_soc_info {
M
Magnus Damm 已提交
134 135 136 137 138 139 140
	char *name;
	struct pinmux_range input;
	struct pinmux_range input_pd;
	struct pinmux_range input_pu;
	struct pinmux_range output;
	struct pinmux_range function;

141
	struct sh_pfc_pin *pins;
142
	unsigned int nr_pins;
143 144
	const struct pinmux_range *ranges;
	unsigned int nr_ranges;
145 146 147 148 149
	const struct sh_pfc_pin_group *groups;
	unsigned int nr_groups;
	const struct sh_pfc_function *functions;
	unsigned int nr_functions;

150 151
	struct pinmux_func *func_gpios;
	unsigned int nr_func_gpios;
152

M
Magnus Damm 已提交
153 154 155 156 157 158
	struct pinmux_cfg_reg *cfg_regs;
	struct pinmux_data_reg *data_regs;

	pinmux_enum_t *gpio_data;
	unsigned int gpio_data_size;

M
Magnus Damm 已提交
159 160 161
	struct pinmux_irq *gpio_irq;
	unsigned int gpio_irq_size;

M
Magnus Damm 已提交
162
	unsigned long unlock_reg;
M
Magnus Damm 已提交
163 164
};

165
enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
M
Magnus Damm 已提交
166

167 168 169 170 171 172 173 174 175 176
/* helper macro for port */
#define PORT_1(fn, pfx, sfx) fn(pfx, sfx)

#define PORT_10(fn, pfx, sfx) \
	PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx),	\
	PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx),	\
	PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx),	\
	PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx),	\
	PORT_1(fn, pfx##8, sfx), PORT_1(fn, pfx##9, sfx)

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
#define PORT_10_REV(fn, pfx, sfx)	\
	PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx),	\
	PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx),	\
	PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx),	\
	PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx),	\
	PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx)

#define PORT_32(fn, pfx, sfx)					\
	PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx),	\
	PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx),	\
	PORT_1(fn, pfx##31, sfx)

#define PORT_32_REV(fn, pfx, sfx)					\
	PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx),		\
	PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx),	\
	PORT_10_REV(fn, pfx, sfx)

194 195 196 197 198 199 200 201 202 203 204
#define PORT_90(fn, pfx, sfx) \
	PORT_10(fn, pfx##1, sfx), PORT_10(fn, pfx##2, sfx),	\
	PORT_10(fn, pfx##3, sfx), PORT_10(fn, pfx##4, sfx),	\
	PORT_10(fn, pfx##5, sfx), PORT_10(fn, pfx##6, sfx),	\
	PORT_10(fn, pfx##7, sfx), PORT_10(fn, pfx##8, sfx),	\
	PORT_10(fn, pfx##9, sfx)

#define _PORT_ALL(pfx, sfx) pfx##_##sfx
#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
#define PORT_ALL(str)	CPU_ALL_PORT(_PORT_ALL, PORT, str)
#define GPIO_PORT_ALL()	CPU_ALL_PORT(_GPIO_PORT, , unused)
205
#define GPIO_FN(str) PINMUX_GPIO_FN(GPIO_FN_##str, PINMUX_FN_BASE, str##_MARK)
206

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
/* helper macro for pinmux_enum_t */
#define PORT_DATA_I(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)

#define PORT_DATA_I_PD(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
		    PORT##nr##_IN, PORT##nr##_IN_PD)

#define PORT_DATA_I_PU(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,	\
		    PORT##nr##_IN, PORT##nr##_IN_PU)

#define PORT_DATA_I_PU_PD(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0,			\
		    PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)

#define PORT_DATA_O(nr)		\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)

#define PORT_DATA_IO(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,	\
		    PORT##nr##_IN)

#define PORT_DATA_IO_PD(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,	\
		    PORT##nr##_IN, PORT##nr##_IN_PD)

#define PORT_DATA_IO_PU(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,	\
		    PORT##nr##_IN, PORT##nr##_IN_PU)

#define PORT_DATA_IO_PU_PD(nr)	\
	PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT,	\
		    PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
/* helper macro for top 4 bits in PORTnCR */
#define _PCRH(in, in_pd, in_pu, out)	\
	0, (out), (in), 0,		\
	0, 0, 0, 0,			\
	0, 0, (in_pd), 0,		\
	0, 0, (in_pu), 0

#define PORTCR(nr, reg)							\
	{								\
		PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {		\
			_PCRH(PORT##nr##_IN, PORT##nr##_IN_PD,		\
			      PORT##nr##_IN_PU, PORT##nr##_OUT),	\
				PORT##nr##_FN0, PORT##nr##_FN1,		\
				PORT##nr##_FN2, PORT##nr##_FN3,		\
				PORT##nr##_FN4, PORT##nr##_FN5,		\
				PORT##nr##_FN6, PORT##nr##_FN7 }	\
	}
259

M
Magnus Damm 已提交
260
#endif /* __SH_PFC_H */