sh_pfc.h 7.0 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 SH_PFC_PIN_CFG_INPUT		(1 << 0)
#define SH_PFC_PIN_CFG_OUTPUT		(1 << 1)
#define SH_PFC_PIN_CFG_PULL_UP		(1 << 2)
#define SH_PFC_PIN_CFG_PULL_DOWN	(1 << 3)

39
struct sh_pfc_pin {
40
	const pinmux_enum_t enum_id;
P
Paul Mundt 已提交
41
	const char *name;
42
	unsigned int configs;
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
#define PINMUX_GPIO(gpio, data_or_mark)			\
	[gpio] = {					\
		.name = __stringify(gpio),		\
		.enum_id = data_or_mark,		\
	}
83 84
#define PINMUX_GPIO_FN(gpio, base, data_or_mark)	\
	[gpio - (base)] = {				\
85 86 87
		.name = __stringify(gpio),		\
		.enum_id = data_or_mark,		\
	}
88

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

struct pinmux_cfg_reg {
	unsigned long reg, reg_width, field_width;
L
Laurent Pinchart 已提交
93 94
	const pinmux_enum_t *enum_ids;
	const unsigned long *var_field_width;
M
Magnus Damm 已提交
95 96 97 98
};

#define PINMUX_CFG_REG(name, r, r_width, f_width) \
	.reg = r, .reg_width = r_width, .field_width = f_width,		\
99 100 101 102 103 104
	.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,	\
	.var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
	.enum_ids = (pinmux_enum_t [])
M
Magnus Damm 已提交
105 106

struct pinmux_data_reg {
107
	unsigned long reg, reg_width;
L
Laurent Pinchart 已提交
108
	const pinmux_enum_t *enum_ids;
M
Magnus Damm 已提交
109 110 111 112 113 114
};

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

M
Magnus Damm 已提交
115 116
struct pinmux_irq {
	int irq;
117
	unsigned short *gpios;
M
Magnus Damm 已提交
118 119 120
};

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

M
Magnus Damm 已提交
123 124 125 126 127 128
struct pinmux_range {
	pinmux_enum_t begin;
	pinmux_enum_t end;
	pinmux_enum_t force;
};

129 130 131 132 133 134 135 136
struct sh_pfc;

struct sh_pfc_soc_operations {
	unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
	void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
			 unsigned int bias);
};

137
struct sh_pfc_soc_info {
L
Laurent Pinchart 已提交
138
	const char *name;
139 140
	const struct sh_pfc_soc_operations *ops;

M
Magnus Damm 已提交
141 142 143 144 145 146
	struct pinmux_range input;
	struct pinmux_range input_pd;
	struct pinmux_range input_pu;
	struct pinmux_range output;
	struct pinmux_range function;

L
Laurent Pinchart 已提交
147
	const struct sh_pfc_pin *pins;
148
	unsigned int nr_pins;
149 150
	const struct pinmux_range *ranges;
	unsigned int nr_ranges;
151 152 153 154 155
	const struct sh_pfc_pin_group *groups;
	unsigned int nr_groups;
	const struct sh_pfc_function *functions;
	unsigned int nr_functions;

L
Laurent Pinchart 已提交
156
	const struct pinmux_func *func_gpios;
157
	unsigned int nr_func_gpios;
158

L
Laurent Pinchart 已提交
159 160
	const struct pinmux_cfg_reg *cfg_regs;
	const struct pinmux_data_reg *data_regs;
M
Magnus Damm 已提交
161

L
Laurent Pinchart 已提交
162
	const pinmux_enum_t *gpio_data;
M
Magnus Damm 已提交
163 164
	unsigned int gpio_data_size;

L
Laurent Pinchart 已提交
165
	const struct pinmux_irq *gpio_irq;
M
Magnus Damm 已提交
166 167
	unsigned int gpio_irq_size;

M
Magnus Damm 已提交
168
	unsigned long unlock_reg;
M
Magnus Damm 已提交
169 170
};

171
enum { GPIO_CFG_REQ, GPIO_CFG_FREE };
M
Magnus Damm 已提交
172

173 174 175 176 177 178 179 180 181 182
/* 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)

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
#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)

200 201 202 203 204 205 206 207 208 209 210
#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)
211
#define GPIO_FN(str) PINMUX_GPIO_FN(GPIO_FN_##str, PINMUX_FN_BASE, str##_MARK)
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 242 243 244 245 246 247
/* 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)

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
/* 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 }	\
	}
265

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