sh_pfc.h 5.5 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 19
#include <asm-generic/gpio.h>

typedef unsigned short pinmux_enum_t;
typedef unsigned short pinmux_flag_t;

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

23 24 25 26 27 28 29 30 31
	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 已提交
32 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)

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

44 45 46 47 48 49 50 51 52 53 54 55
#define PINMUX_GPIO(gpio, data_or_mark)			\
	[gpio] = {					\
		.name = __stringify(gpio),		\
		.enum_id = data_or_mark,		\
		.flags = PINMUX_TYPE_GPIO		\
	}
#define PINMUX_GPIO_FN(gpio, data_or_mark)		\
	[gpio] = {					\
		.name = __stringify(gpio),		\
		.enum_id = data_or_mark,		\
		.flags = PINMUX_TYPE_FUNCTION		\
	}
56

M
Magnus Damm 已提交
57 58 59 60 61 62
#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;
63
	unsigned long *var_field_width;
M
Magnus Damm 已提交
64 65 66 67 68
};

#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]) {}, \
69 70 71 72 73 74 75
	.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 已提交
76 77 78 79

struct pinmux_data_reg {
	unsigned long reg, reg_width, reg_shadow;
	pinmux_enum_t *enum_ids;
M
Magnus Damm 已提交
80
	void __iomem *mapped_reg;
M
Magnus Damm 已提交
81 82 83 84 85 86
};

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

M
Magnus Damm 已提交
87 88 89 90 91 92 93 94
struct pinmux_irq {
	int irq;
	pinmux_enum_t *enum_ids;
};

#define PINMUX_IRQ(irq_nr, ids...)			   \
	{ .irq = irq_nr, .enum_ids = (pinmux_enum_t []) { ids, 0 } }	\

M
Magnus Damm 已提交
95 96 97 98 99 100
struct pinmux_range {
	pinmux_enum_t begin;
	pinmux_enum_t end;
	pinmux_enum_t force;
};

101
struct sh_pfc_soc_info {
M
Magnus Damm 已提交
102 103 104 105 106 107 108 109
	char *name;
	struct pinmux_range input;
	struct pinmux_range input_pd;
	struct pinmux_range input_pu;
	struct pinmux_range output;
	struct pinmux_range function;

	struct pinmux_gpio *gpios;
110
	unsigned int nr_pins;
111 112
	unsigned int nr_gpios;

M
Magnus Damm 已提交
113 114 115 116 117 118
	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 已提交
119 120 121
	struct pinmux_irq *gpio_irq;
	unsigned int gpio_irq_size;

M
Magnus Damm 已提交
122
	unsigned long unlock_reg;
M
Magnus Damm 已提交
123 124
};

125
enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
M
Magnus Damm 已提交
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
/* 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)

#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)
148
#define GPIO_FN(str) PINMUX_GPIO_FN(GPIO_FN_##str, str##_MARK)
149

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
/* 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)

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
/* 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 }	\
	}
202

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