xref: /openbmc/u-boot/drivers/gpio/sh_pfc.c (revision be62fbf376261ab3a4ed5db3bf54d5df9e216d9f)
1d764c504SNobuhiro Iwamatsu /*
2d764c504SNobuhiro Iwamatsu  * Pinmuxed GPIO support for SuperH.
3d764c504SNobuhiro Iwamatsu  * Copy from linux kernel driver/sh/pfc.c
4d764c504SNobuhiro Iwamatsu  *
5d764c504SNobuhiro Iwamatsu  * Copyright (C) 2008 Magnus Damm
6d764c504SNobuhiro Iwamatsu  *
7d764c504SNobuhiro Iwamatsu  * This file is subject to the terms and conditions of the GNU General Public
8d764c504SNobuhiro Iwamatsu  * License.  See the file "COPYING" in the main directory of this archive
9d764c504SNobuhiro Iwamatsu  * for more details.
10d764c504SNobuhiro Iwamatsu  */
11d764c504SNobuhiro Iwamatsu 
12d764c504SNobuhiro Iwamatsu #include <common.h>
13d764c504SNobuhiro Iwamatsu #include <asm/bitops.h>
14d764c504SNobuhiro Iwamatsu #include <asm/io.h>
15d764c504SNobuhiro Iwamatsu #include <sh_pfc.h>
16d764c504SNobuhiro Iwamatsu 
17d764c504SNobuhiro Iwamatsu static struct pinmux_info *gpioc;
18d764c504SNobuhiro Iwamatsu 
19d764c504SNobuhiro Iwamatsu #define pfc_phys_to_virt(p, a) ((void *)a)
20d764c504SNobuhiro Iwamatsu 
enum_in_range(pinmux_enum_t enum_id,struct pinmux_range * r)21d764c504SNobuhiro Iwamatsu static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
22d764c504SNobuhiro Iwamatsu {
23d764c504SNobuhiro Iwamatsu 	if (enum_id < r->begin)
24d764c504SNobuhiro Iwamatsu 		return 0;
25d764c504SNobuhiro Iwamatsu 
26d764c504SNobuhiro Iwamatsu 	if (enum_id > r->end)
27d764c504SNobuhiro Iwamatsu 		return 0;
28d764c504SNobuhiro Iwamatsu 
29d764c504SNobuhiro Iwamatsu 	return 1;
30d764c504SNobuhiro Iwamatsu }
31d764c504SNobuhiro Iwamatsu 
gpio_read_raw_reg(void * mapped_reg,unsigned long reg_width)32d764c504SNobuhiro Iwamatsu static unsigned long gpio_read_raw_reg(void *mapped_reg,
33d764c504SNobuhiro Iwamatsu 				       unsigned long reg_width)
34d764c504SNobuhiro Iwamatsu {
35d764c504SNobuhiro Iwamatsu 	switch (reg_width) {
36d764c504SNobuhiro Iwamatsu 
37d764c504SNobuhiro Iwamatsu 	case 8:
38d764c504SNobuhiro Iwamatsu 		return readb(mapped_reg);
39d764c504SNobuhiro Iwamatsu 	case 16:
40d764c504SNobuhiro Iwamatsu 		return readw(mapped_reg);
41d764c504SNobuhiro Iwamatsu 	case 32:
42d764c504SNobuhiro Iwamatsu 		return readl(mapped_reg);
43d764c504SNobuhiro Iwamatsu 	}
44d764c504SNobuhiro Iwamatsu 
45d764c504SNobuhiro Iwamatsu 	BUG();
46d764c504SNobuhiro Iwamatsu 	return 0;
47d764c504SNobuhiro Iwamatsu }
48d764c504SNobuhiro Iwamatsu 
gpio_write_raw_reg(void * mapped_reg,unsigned long reg_width,unsigned long data)49d764c504SNobuhiro Iwamatsu static void gpio_write_raw_reg(void *mapped_reg,
50d764c504SNobuhiro Iwamatsu 			       unsigned long reg_width,
51d764c504SNobuhiro Iwamatsu 			       unsigned long data)
52d764c504SNobuhiro Iwamatsu {
53d764c504SNobuhiro Iwamatsu 	switch (reg_width) {
54d764c504SNobuhiro Iwamatsu 	case 8:
55d764c504SNobuhiro Iwamatsu 		writeb(data, mapped_reg);
56d764c504SNobuhiro Iwamatsu 		return;
57d764c504SNobuhiro Iwamatsu 	case 16:
58d764c504SNobuhiro Iwamatsu 		writew(data, mapped_reg);
59d764c504SNobuhiro Iwamatsu 		return;
60d764c504SNobuhiro Iwamatsu 	case 32:
61d764c504SNobuhiro Iwamatsu 		writel(data, mapped_reg);
62d764c504SNobuhiro Iwamatsu 		return;
63d764c504SNobuhiro Iwamatsu 	}
64d764c504SNobuhiro Iwamatsu 
65d764c504SNobuhiro Iwamatsu 	BUG();
66d764c504SNobuhiro Iwamatsu }
67d764c504SNobuhiro Iwamatsu 
gpio_read_bit(struct pinmux_data_reg * dr,unsigned long offset,unsigned long in_pos)68d764c504SNobuhiro Iwamatsu static int gpio_read_bit(struct pinmux_data_reg *dr,
69*1815c297SKouei Abe 			 unsigned long offset,
70d764c504SNobuhiro Iwamatsu 			 unsigned long in_pos)
71d764c504SNobuhiro Iwamatsu {
72d764c504SNobuhiro Iwamatsu 	unsigned long pos;
73d764c504SNobuhiro Iwamatsu 
74d764c504SNobuhiro Iwamatsu 	pos = dr->reg_width - (in_pos + 1);
75d764c504SNobuhiro Iwamatsu 
76*1815c297SKouei Abe 	debug("read_bit: addr = %lx, pos = %ld, r_width = %ld\n",
77*1815c297SKouei Abe 	      dr->reg + offset, pos, dr->reg_width);
78d764c504SNobuhiro Iwamatsu 
79*1815c297SKouei Abe 	return (gpio_read_raw_reg(dr->mapped_reg + offset,
80*1815c297SKouei Abe 				  dr->reg_width) >> pos) & 1;
81d764c504SNobuhiro Iwamatsu }
82d764c504SNobuhiro Iwamatsu 
gpio_write_bit(struct pinmux_data_reg * dr,unsigned long in_pos,unsigned long value)83d764c504SNobuhiro Iwamatsu static void gpio_write_bit(struct pinmux_data_reg *dr,
84d764c504SNobuhiro Iwamatsu 			   unsigned long in_pos, unsigned long value)
85d764c504SNobuhiro Iwamatsu {
86d764c504SNobuhiro Iwamatsu 	unsigned long pos;
87d764c504SNobuhiro Iwamatsu 
88d764c504SNobuhiro Iwamatsu 	pos = dr->reg_width - (in_pos + 1);
89d764c504SNobuhiro Iwamatsu 
90d764c504SNobuhiro Iwamatsu 	debug("write_bit addr = %lx, value = %d, pos = %ld, "
91d764c504SNobuhiro Iwamatsu 		 "r_width = %ld\n",
92d764c504SNobuhiro Iwamatsu 		 dr->reg, !!value, pos, dr->reg_width);
93d764c504SNobuhiro Iwamatsu 
94d764c504SNobuhiro Iwamatsu 	if (value)
95d764c504SNobuhiro Iwamatsu 		__set_bit(pos, &dr->reg_shadow);
96d764c504SNobuhiro Iwamatsu 	else
97d764c504SNobuhiro Iwamatsu 		__clear_bit(pos, &dr->reg_shadow);
98d764c504SNobuhiro Iwamatsu 
99d764c504SNobuhiro Iwamatsu 	gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
100d764c504SNobuhiro Iwamatsu }
101d764c504SNobuhiro Iwamatsu 
config_reg_helper(struct pinmux_info * gpioc,struct pinmux_cfg_reg * crp,unsigned long in_pos,void ** mapped_regp,unsigned long * maskp,unsigned long * posp)102d764c504SNobuhiro Iwamatsu static void config_reg_helper(struct pinmux_info *gpioc,
103d764c504SNobuhiro Iwamatsu 			      struct pinmux_cfg_reg *crp,
104d764c504SNobuhiro Iwamatsu 			      unsigned long in_pos,
105d764c504SNobuhiro Iwamatsu #if 0
106d764c504SNobuhiro Iwamatsu 			      void __iomem **mapped_regp,
107d764c504SNobuhiro Iwamatsu #else
108d764c504SNobuhiro Iwamatsu 			      void **mapped_regp,
109d764c504SNobuhiro Iwamatsu #endif
110d764c504SNobuhiro Iwamatsu 			      unsigned long *maskp,
111d764c504SNobuhiro Iwamatsu 			      unsigned long *posp)
112d764c504SNobuhiro Iwamatsu {
113d764c504SNobuhiro Iwamatsu 	int k;
114d764c504SNobuhiro Iwamatsu 
115d764c504SNobuhiro Iwamatsu 	*mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
116d764c504SNobuhiro Iwamatsu 
117d764c504SNobuhiro Iwamatsu 	if (crp->field_width) {
118d764c504SNobuhiro Iwamatsu 		*maskp = (1 << crp->field_width) - 1;
119d764c504SNobuhiro Iwamatsu 		*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
120d764c504SNobuhiro Iwamatsu 	} else {
121d764c504SNobuhiro Iwamatsu 		*maskp = (1 << crp->var_field_width[in_pos]) - 1;
122d764c504SNobuhiro Iwamatsu 		*posp = crp->reg_width;
123d764c504SNobuhiro Iwamatsu 		for (k = 0; k <= in_pos; k++)
124d764c504SNobuhiro Iwamatsu 			*posp -= crp->var_field_width[k];
125d764c504SNobuhiro Iwamatsu 	}
126d764c504SNobuhiro Iwamatsu }
127d764c504SNobuhiro Iwamatsu 
read_config_reg(struct pinmux_info * gpioc,struct pinmux_cfg_reg * crp,unsigned long field)128d764c504SNobuhiro Iwamatsu static int read_config_reg(struct pinmux_info *gpioc,
129d764c504SNobuhiro Iwamatsu 			   struct pinmux_cfg_reg *crp,
130d764c504SNobuhiro Iwamatsu 			   unsigned long field)
131d764c504SNobuhiro Iwamatsu {
132d764c504SNobuhiro Iwamatsu 	void *mapped_reg;
133d764c504SNobuhiro Iwamatsu 
134d764c504SNobuhiro Iwamatsu 	unsigned long mask, pos;
135d764c504SNobuhiro Iwamatsu 
136d764c504SNobuhiro Iwamatsu 	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
137d764c504SNobuhiro Iwamatsu 
138d764c504SNobuhiro Iwamatsu 	debug("read_reg: addr = %lx, field = %ld, "
139d764c504SNobuhiro Iwamatsu 		 "r_width = %ld, f_width = %ld\n",
140d764c504SNobuhiro Iwamatsu 		 crp->reg, field, crp->reg_width, crp->field_width);
141d764c504SNobuhiro Iwamatsu 
142d764c504SNobuhiro Iwamatsu 	return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
143d764c504SNobuhiro Iwamatsu }
144d764c504SNobuhiro Iwamatsu 
write_config_reg(struct pinmux_info * gpioc,struct pinmux_cfg_reg * crp,unsigned long field,unsigned long value)145d764c504SNobuhiro Iwamatsu static void write_config_reg(struct pinmux_info *gpioc,
146d764c504SNobuhiro Iwamatsu 			     struct pinmux_cfg_reg *crp,
147d764c504SNobuhiro Iwamatsu 			     unsigned long field, unsigned long value)
148d764c504SNobuhiro Iwamatsu {
149d764c504SNobuhiro Iwamatsu 	void *mapped_reg;
150d764c504SNobuhiro Iwamatsu 	unsigned long mask, pos, data;
151d764c504SNobuhiro Iwamatsu 
152d764c504SNobuhiro Iwamatsu 	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
153d764c504SNobuhiro Iwamatsu 
154d764c504SNobuhiro Iwamatsu 	debug("write_reg addr = %lx, value = %ld, field = %ld, "
155d764c504SNobuhiro Iwamatsu 		 "r_width = %ld, f_width = %ld\n",
156d764c504SNobuhiro Iwamatsu 		 crp->reg, value, field, crp->reg_width, crp->field_width);
157d764c504SNobuhiro Iwamatsu 
158d764c504SNobuhiro Iwamatsu 	mask = ~(mask << pos);
159d764c504SNobuhiro Iwamatsu 	value = value << pos;
160d764c504SNobuhiro Iwamatsu 
161d764c504SNobuhiro Iwamatsu 	data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
162d764c504SNobuhiro Iwamatsu 	data &= mask;
163d764c504SNobuhiro Iwamatsu 	data |= value;
164d764c504SNobuhiro Iwamatsu 
165d764c504SNobuhiro Iwamatsu 	if (gpioc->unlock_reg)
166d764c504SNobuhiro Iwamatsu 		gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
167d764c504SNobuhiro Iwamatsu 				   32, ~data);
168d764c504SNobuhiro Iwamatsu 
169d764c504SNobuhiro Iwamatsu 	gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
170d764c504SNobuhiro Iwamatsu }
171d764c504SNobuhiro Iwamatsu 
setup_data_reg(struct pinmux_info * gpioc,unsigned gpio)172d764c504SNobuhiro Iwamatsu static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
173d764c504SNobuhiro Iwamatsu {
174d764c504SNobuhiro Iwamatsu 	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
175d764c504SNobuhiro Iwamatsu 	struct pinmux_data_reg *data_reg;
176d764c504SNobuhiro Iwamatsu 	int k, n;
177d764c504SNobuhiro Iwamatsu 
178d764c504SNobuhiro Iwamatsu 	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
179d764c504SNobuhiro Iwamatsu 		return -1;
180d764c504SNobuhiro Iwamatsu 
181d764c504SNobuhiro Iwamatsu 	k = 0;
182d764c504SNobuhiro Iwamatsu 	while (1) {
183d764c504SNobuhiro Iwamatsu 		data_reg = gpioc->data_regs + k;
184d764c504SNobuhiro Iwamatsu 
185d764c504SNobuhiro Iwamatsu 		if (!data_reg->reg_width)
186d764c504SNobuhiro Iwamatsu 			break;
187d764c504SNobuhiro Iwamatsu 
188d764c504SNobuhiro Iwamatsu 		data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
189d764c504SNobuhiro Iwamatsu 
190d764c504SNobuhiro Iwamatsu 		for (n = 0; n < data_reg->reg_width; n++) {
191d764c504SNobuhiro Iwamatsu 			if (data_reg->enum_ids[n] == gpiop->enum_id) {
192d764c504SNobuhiro Iwamatsu 				gpiop->flags &= ~PINMUX_FLAG_DREG;
193d764c504SNobuhiro Iwamatsu 				gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
194d764c504SNobuhiro Iwamatsu 				gpiop->flags &= ~PINMUX_FLAG_DBIT;
195d764c504SNobuhiro Iwamatsu 				gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
196d764c504SNobuhiro Iwamatsu 				return 0;
197d764c504SNobuhiro Iwamatsu 			}
198d764c504SNobuhiro Iwamatsu 		}
199d764c504SNobuhiro Iwamatsu 		k++;
200d764c504SNobuhiro Iwamatsu 	}
201d764c504SNobuhiro Iwamatsu 
202d764c504SNobuhiro Iwamatsu 	BUG();
203d764c504SNobuhiro Iwamatsu 
204d764c504SNobuhiro Iwamatsu 	return -1;
205d764c504SNobuhiro Iwamatsu }
206d764c504SNobuhiro Iwamatsu 
setup_data_regs(struct pinmux_info * gpioc)207d764c504SNobuhiro Iwamatsu static void setup_data_regs(struct pinmux_info *gpioc)
208d764c504SNobuhiro Iwamatsu {
209d764c504SNobuhiro Iwamatsu 	struct pinmux_data_reg *drp;
210d764c504SNobuhiro Iwamatsu 	int k;
211d764c504SNobuhiro Iwamatsu 
212d764c504SNobuhiro Iwamatsu 	for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
213d764c504SNobuhiro Iwamatsu 		setup_data_reg(gpioc, k);
214d764c504SNobuhiro Iwamatsu 
215d764c504SNobuhiro Iwamatsu 	k = 0;
216d764c504SNobuhiro Iwamatsu 	while (1) {
217d764c504SNobuhiro Iwamatsu 		drp = gpioc->data_regs + k;
218d764c504SNobuhiro Iwamatsu 
219d764c504SNobuhiro Iwamatsu 		if (!drp->reg_width)
220d764c504SNobuhiro Iwamatsu 			break;
221d764c504SNobuhiro Iwamatsu 
222d764c504SNobuhiro Iwamatsu 		drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
223d764c504SNobuhiro Iwamatsu 						    drp->reg_width);
224d764c504SNobuhiro Iwamatsu 		k++;
225d764c504SNobuhiro Iwamatsu 	}
226d764c504SNobuhiro Iwamatsu }
227d764c504SNobuhiro Iwamatsu 
get_data_reg(struct pinmux_info * gpioc,unsigned gpio,struct pinmux_data_reg ** drp,int * bitp)228d764c504SNobuhiro Iwamatsu static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
229d764c504SNobuhiro Iwamatsu 			struct pinmux_data_reg **drp, int *bitp)
230d764c504SNobuhiro Iwamatsu {
231d764c504SNobuhiro Iwamatsu 	struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
232d764c504SNobuhiro Iwamatsu 	int k, n;
233d764c504SNobuhiro Iwamatsu 
234d764c504SNobuhiro Iwamatsu 	if (!enum_in_range(gpiop->enum_id, &gpioc->data))
235d764c504SNobuhiro Iwamatsu 		return -1;
236d764c504SNobuhiro Iwamatsu 
237d764c504SNobuhiro Iwamatsu 	k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
238d764c504SNobuhiro Iwamatsu 	n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
239d764c504SNobuhiro Iwamatsu 	*drp = gpioc->data_regs + k;
240d764c504SNobuhiro Iwamatsu 	*bitp = n;
241d764c504SNobuhiro Iwamatsu 	return 0;
242d764c504SNobuhiro Iwamatsu }
243d764c504SNobuhiro Iwamatsu 
get_config_reg(struct pinmux_info * gpioc,pinmux_enum_t enum_id,struct pinmux_cfg_reg ** crp,int * fieldp,int * valuep,unsigned long ** cntp)244d764c504SNobuhiro Iwamatsu static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
245d764c504SNobuhiro Iwamatsu 			  struct pinmux_cfg_reg **crp,
246d764c504SNobuhiro Iwamatsu 			  int *fieldp, int *valuep,
247d764c504SNobuhiro Iwamatsu 			  unsigned long **cntp)
248d764c504SNobuhiro Iwamatsu {
249d764c504SNobuhiro Iwamatsu 	struct pinmux_cfg_reg *config_reg;
250d764c504SNobuhiro Iwamatsu 	unsigned long r_width, f_width, curr_width, ncomb;
251d764c504SNobuhiro Iwamatsu 	int k, m, n, pos, bit_pos;
252d764c504SNobuhiro Iwamatsu 
253d764c504SNobuhiro Iwamatsu 	k = 0;
254d764c504SNobuhiro Iwamatsu 	while (1) {
255d764c504SNobuhiro Iwamatsu 		config_reg = gpioc->cfg_regs + k;
256d764c504SNobuhiro Iwamatsu 
257d764c504SNobuhiro Iwamatsu 		r_width = config_reg->reg_width;
258d764c504SNobuhiro Iwamatsu 		f_width = config_reg->field_width;
259d764c504SNobuhiro Iwamatsu 
260d764c504SNobuhiro Iwamatsu 		if (!r_width)
261d764c504SNobuhiro Iwamatsu 			break;
262d764c504SNobuhiro Iwamatsu 
263d764c504SNobuhiro Iwamatsu 		pos = 0;
264d764c504SNobuhiro Iwamatsu 		m = 0;
265d764c504SNobuhiro Iwamatsu 		for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
266d764c504SNobuhiro Iwamatsu 			if (f_width)
267d764c504SNobuhiro Iwamatsu 				curr_width = f_width;
268d764c504SNobuhiro Iwamatsu 			else
269d764c504SNobuhiro Iwamatsu 				curr_width = config_reg->var_field_width[m];
270d764c504SNobuhiro Iwamatsu 
271d764c504SNobuhiro Iwamatsu 			ncomb = 1 << curr_width;
272d764c504SNobuhiro Iwamatsu 			for (n = 0; n < ncomb; n++) {
273d764c504SNobuhiro Iwamatsu 				if (config_reg->enum_ids[pos + n] == enum_id) {
274d764c504SNobuhiro Iwamatsu 					*crp = config_reg;
275d764c504SNobuhiro Iwamatsu 					*fieldp = m;
276d764c504SNobuhiro Iwamatsu 					*valuep = n;
277d764c504SNobuhiro Iwamatsu 					*cntp = &config_reg->cnt[m];
278d764c504SNobuhiro Iwamatsu 					return 0;
279d764c504SNobuhiro Iwamatsu 				}
280d764c504SNobuhiro Iwamatsu 			}
281d764c504SNobuhiro Iwamatsu 			pos += ncomb;
282d764c504SNobuhiro Iwamatsu 			m++;
283d764c504SNobuhiro Iwamatsu 		}
284d764c504SNobuhiro Iwamatsu 		k++;
285d764c504SNobuhiro Iwamatsu 	}
286d764c504SNobuhiro Iwamatsu 
287d764c504SNobuhiro Iwamatsu 	return -1;
288d764c504SNobuhiro Iwamatsu }
289d764c504SNobuhiro Iwamatsu 
get_gpio_enum_id(struct pinmux_info * gpioc,unsigned gpio,int pos,pinmux_enum_t * enum_idp)290d764c504SNobuhiro Iwamatsu static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
291d764c504SNobuhiro Iwamatsu 			    int pos, pinmux_enum_t *enum_idp)
292d764c504SNobuhiro Iwamatsu {
293d764c504SNobuhiro Iwamatsu 	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
294d764c504SNobuhiro Iwamatsu 	pinmux_enum_t *data = gpioc->gpio_data;
295d764c504SNobuhiro Iwamatsu 	int k;
296d764c504SNobuhiro Iwamatsu 
297d764c504SNobuhiro Iwamatsu 	if (!enum_in_range(enum_id, &gpioc->data)) {
298d764c504SNobuhiro Iwamatsu 		if (!enum_in_range(enum_id, &gpioc->mark)) {
299d764c504SNobuhiro Iwamatsu 			debug("non data/mark enum_id for gpio %d\n", gpio);
300d764c504SNobuhiro Iwamatsu 			return -1;
301d764c504SNobuhiro Iwamatsu 		}
302d764c504SNobuhiro Iwamatsu 	}
303d764c504SNobuhiro Iwamatsu 
304d764c504SNobuhiro Iwamatsu 	if (pos) {
305d764c504SNobuhiro Iwamatsu 		*enum_idp = data[pos + 1];
306d764c504SNobuhiro Iwamatsu 		return pos + 1;
307d764c504SNobuhiro Iwamatsu 	}
308d764c504SNobuhiro Iwamatsu 
309d764c504SNobuhiro Iwamatsu 	for (k = 0; k < gpioc->gpio_data_size; k++) {
310d764c504SNobuhiro Iwamatsu 		if (data[k] == enum_id) {
311d764c504SNobuhiro Iwamatsu 			*enum_idp = data[k + 1];
312d764c504SNobuhiro Iwamatsu 			return k + 1;
313d764c504SNobuhiro Iwamatsu 		}
314d764c504SNobuhiro Iwamatsu 	}
315d764c504SNobuhiro Iwamatsu 
316d764c504SNobuhiro Iwamatsu 	debug("cannot locate data/mark enum_id for gpio %d\n", gpio);
317d764c504SNobuhiro Iwamatsu 	return -1;
318d764c504SNobuhiro Iwamatsu }
319d764c504SNobuhiro Iwamatsu 
320d764c504SNobuhiro Iwamatsu enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
321d764c504SNobuhiro Iwamatsu 
pinmux_config_gpio(struct pinmux_info * gpioc,unsigned gpio,int pinmux_type,int cfg_mode)322d764c504SNobuhiro Iwamatsu static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
323d764c504SNobuhiro Iwamatsu 			      int pinmux_type, int cfg_mode)
324d764c504SNobuhiro Iwamatsu {
325d764c504SNobuhiro Iwamatsu 	struct pinmux_cfg_reg *cr = NULL;
326d764c504SNobuhiro Iwamatsu 	pinmux_enum_t enum_id;
327d764c504SNobuhiro Iwamatsu 	struct pinmux_range *range;
328d764c504SNobuhiro Iwamatsu 	int in_range, pos, field, value;
329d764c504SNobuhiro Iwamatsu 	unsigned long *cntp;
330d764c504SNobuhiro Iwamatsu 
331d764c504SNobuhiro Iwamatsu 	switch (pinmux_type) {
332d764c504SNobuhiro Iwamatsu 
333d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_FUNCTION:
334d764c504SNobuhiro Iwamatsu 		range = NULL;
335d764c504SNobuhiro Iwamatsu 		break;
336d764c504SNobuhiro Iwamatsu 
337d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_OUTPUT:
338d764c504SNobuhiro Iwamatsu 		range = &gpioc->output;
339d764c504SNobuhiro Iwamatsu 		break;
340d764c504SNobuhiro Iwamatsu 
341d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_INPUT:
342d764c504SNobuhiro Iwamatsu 		range = &gpioc->input;
343d764c504SNobuhiro Iwamatsu 		break;
344d764c504SNobuhiro Iwamatsu 
345d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_INPUT_PULLUP:
346d764c504SNobuhiro Iwamatsu 		range = &gpioc->input_pu;
347d764c504SNobuhiro Iwamatsu 		break;
348d764c504SNobuhiro Iwamatsu 
349d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_INPUT_PULLDOWN:
350d764c504SNobuhiro Iwamatsu 		range = &gpioc->input_pd;
351d764c504SNobuhiro Iwamatsu 		break;
352d764c504SNobuhiro Iwamatsu 
353d764c504SNobuhiro Iwamatsu 	default:
354d764c504SNobuhiro Iwamatsu 		goto out_err;
355d764c504SNobuhiro Iwamatsu 	}
356d764c504SNobuhiro Iwamatsu 
357d764c504SNobuhiro Iwamatsu 	pos = 0;
358d764c504SNobuhiro Iwamatsu 	enum_id = 0;
359d764c504SNobuhiro Iwamatsu 	field = 0;
360d764c504SNobuhiro Iwamatsu 	value = 0;
361d764c504SNobuhiro Iwamatsu 	while (1) {
362d764c504SNobuhiro Iwamatsu 		pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
363d764c504SNobuhiro Iwamatsu 		if (pos <= 0)
364d764c504SNobuhiro Iwamatsu 			goto out_err;
365d764c504SNobuhiro Iwamatsu 
366d764c504SNobuhiro Iwamatsu 		if (!enum_id)
367d764c504SNobuhiro Iwamatsu 			break;
368d764c504SNobuhiro Iwamatsu 
369d764c504SNobuhiro Iwamatsu 		/* first check if this is a function enum */
370d764c504SNobuhiro Iwamatsu 		in_range = enum_in_range(enum_id, &gpioc->function);
371d764c504SNobuhiro Iwamatsu 		if (!in_range) {
372d764c504SNobuhiro Iwamatsu 			/* not a function enum */
373d764c504SNobuhiro Iwamatsu 			if (range) {
374d764c504SNobuhiro Iwamatsu 				/*
375d764c504SNobuhiro Iwamatsu 				 * other range exists, so this pin is
376d764c504SNobuhiro Iwamatsu 				 * a regular GPIO pin that now is being
377d764c504SNobuhiro Iwamatsu 				 * bound to a specific direction.
378d764c504SNobuhiro Iwamatsu 				 *
379d764c504SNobuhiro Iwamatsu 				 * for this case we only allow function enums
380d764c504SNobuhiro Iwamatsu 				 * and the enums that match the other range.
381d764c504SNobuhiro Iwamatsu 				 */
382d764c504SNobuhiro Iwamatsu 				in_range = enum_in_range(enum_id, range);
383d764c504SNobuhiro Iwamatsu 
384d764c504SNobuhiro Iwamatsu 				/*
385d764c504SNobuhiro Iwamatsu 				 * special case pass through for fixed
386d764c504SNobuhiro Iwamatsu 				 * input-only or output-only pins without
387d764c504SNobuhiro Iwamatsu 				 * function enum register association.
388d764c504SNobuhiro Iwamatsu 				 */
389d764c504SNobuhiro Iwamatsu 				if (in_range && enum_id == range->force)
390d764c504SNobuhiro Iwamatsu 					continue;
391d764c504SNobuhiro Iwamatsu 			} else {
392d764c504SNobuhiro Iwamatsu 				/*
393d764c504SNobuhiro Iwamatsu 				 * no other range exists, so this pin
394d764c504SNobuhiro Iwamatsu 				 * must then be of the function type.
395d764c504SNobuhiro Iwamatsu 				 *
396d764c504SNobuhiro Iwamatsu 				 * allow function type pins to select
397d764c504SNobuhiro Iwamatsu 				 * any combination of function/in/out
398d764c504SNobuhiro Iwamatsu 				 * in their MARK lists.
399d764c504SNobuhiro Iwamatsu 				 */
400d764c504SNobuhiro Iwamatsu 				in_range = 1;
401d764c504SNobuhiro Iwamatsu 			}
402d764c504SNobuhiro Iwamatsu 		}
403d764c504SNobuhiro Iwamatsu 
404d764c504SNobuhiro Iwamatsu 		if (!in_range)
405d764c504SNobuhiro Iwamatsu 			continue;
406d764c504SNobuhiro Iwamatsu 
407d764c504SNobuhiro Iwamatsu 		if (get_config_reg(gpioc, enum_id, &cr,
408d764c504SNobuhiro Iwamatsu 				   &field, &value, &cntp) != 0)
409d764c504SNobuhiro Iwamatsu 			goto out_err;
410d764c504SNobuhiro Iwamatsu 
411d764c504SNobuhiro Iwamatsu 		switch (cfg_mode) {
412d764c504SNobuhiro Iwamatsu 		case GPIO_CFG_DRYRUN:
413d764c504SNobuhiro Iwamatsu 			if (!*cntp ||
414d764c504SNobuhiro Iwamatsu 			    (read_config_reg(gpioc, cr, field) != value))
415d764c504SNobuhiro Iwamatsu 				continue;
416d764c504SNobuhiro Iwamatsu 			break;
417d764c504SNobuhiro Iwamatsu 
418d764c504SNobuhiro Iwamatsu 		case GPIO_CFG_REQ:
419d764c504SNobuhiro Iwamatsu 			write_config_reg(gpioc, cr, field, value);
420d764c504SNobuhiro Iwamatsu 			*cntp = *cntp + 1;
421d764c504SNobuhiro Iwamatsu 			break;
422d764c504SNobuhiro Iwamatsu 
423d764c504SNobuhiro Iwamatsu 		case GPIO_CFG_FREE:
424d764c504SNobuhiro Iwamatsu 			*cntp = *cntp - 1;
425d764c504SNobuhiro Iwamatsu 			break;
426d764c504SNobuhiro Iwamatsu 		}
427d764c504SNobuhiro Iwamatsu 	}
428d764c504SNobuhiro Iwamatsu 
429d764c504SNobuhiro Iwamatsu 	return 0;
430d764c504SNobuhiro Iwamatsu  out_err:
431d764c504SNobuhiro Iwamatsu 	return -1;
432d764c504SNobuhiro Iwamatsu }
433d764c504SNobuhiro Iwamatsu 
434d764c504SNobuhiro Iwamatsu #if 0
435d764c504SNobuhiro Iwamatsu static DEFINE_SPINLOCK(gpio_lock);
436d764c504SNobuhiro Iwamatsu static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
437d764c504SNobuhiro Iwamatsu {
438d764c504SNobuhiro Iwamatsu 	return container_of(chip, struct pinmux_info, chip);
439d764c504SNobuhiro Iwamatsu }
440d764c504SNobuhiro Iwamatsu #endif
441d764c504SNobuhiro Iwamatsu 
sh_gpio_request(unsigned offset)442d764c504SNobuhiro Iwamatsu static int sh_gpio_request(unsigned offset)
443d764c504SNobuhiro Iwamatsu {
444d764c504SNobuhiro Iwamatsu 	struct pinmux_data_reg *dummy;
445d764c504SNobuhiro Iwamatsu 	int i, ret, pinmux_type;
446d764c504SNobuhiro Iwamatsu 
447d764c504SNobuhiro Iwamatsu 	ret = -1;
448d764c504SNobuhiro Iwamatsu 
449d764c504SNobuhiro Iwamatsu 	if (!gpioc)
450d764c504SNobuhiro Iwamatsu 		goto err_out;
451d764c504SNobuhiro Iwamatsu 
452d764c504SNobuhiro Iwamatsu 	if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
453d764c504SNobuhiro Iwamatsu 		goto err_out;
454d764c504SNobuhiro Iwamatsu 
455d764c504SNobuhiro Iwamatsu 	/* setup pin function here if no data is associated with pin */
456d764c504SNobuhiro Iwamatsu 
457d764c504SNobuhiro Iwamatsu 	if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
458d764c504SNobuhiro Iwamatsu 		pinmux_type = PINMUX_TYPE_FUNCTION;
459d764c504SNobuhiro Iwamatsu 	else
460d764c504SNobuhiro Iwamatsu 		pinmux_type = PINMUX_TYPE_GPIO;
461d764c504SNobuhiro Iwamatsu 
462d764c504SNobuhiro Iwamatsu 	if (pinmux_type == PINMUX_TYPE_FUNCTION) {
463d764c504SNobuhiro Iwamatsu 		if (pinmux_config_gpio(gpioc, offset,
464d764c504SNobuhiro Iwamatsu 				       pinmux_type,
465d764c504SNobuhiro Iwamatsu 				       GPIO_CFG_DRYRUN) != 0)
466d764c504SNobuhiro Iwamatsu 			goto err_out;
467d764c504SNobuhiro Iwamatsu 
468d764c504SNobuhiro Iwamatsu 		if (pinmux_config_gpio(gpioc, offset,
469d764c504SNobuhiro Iwamatsu 				       pinmux_type,
470d764c504SNobuhiro Iwamatsu 				       GPIO_CFG_REQ) != 0)
471d764c504SNobuhiro Iwamatsu 			BUG();
472d764c504SNobuhiro Iwamatsu 	}
473d764c504SNobuhiro Iwamatsu 
474d764c504SNobuhiro Iwamatsu 	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
475d764c504SNobuhiro Iwamatsu 	gpioc->gpios[offset].flags |= pinmux_type;
476d764c504SNobuhiro Iwamatsu 
477d764c504SNobuhiro Iwamatsu 	ret = 0;
478d764c504SNobuhiro Iwamatsu err_out:
479d764c504SNobuhiro Iwamatsu 	return ret;
480d764c504SNobuhiro Iwamatsu }
481d764c504SNobuhiro Iwamatsu 
sh_gpio_free(unsigned offset)482d764c504SNobuhiro Iwamatsu static void sh_gpio_free(unsigned offset)
483d764c504SNobuhiro Iwamatsu {
484d764c504SNobuhiro Iwamatsu 	int pinmux_type;
485d764c504SNobuhiro Iwamatsu 
486d764c504SNobuhiro Iwamatsu 	if (!gpioc)
487d764c504SNobuhiro Iwamatsu 		return;
488d764c504SNobuhiro Iwamatsu 
489d764c504SNobuhiro Iwamatsu 	pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
490d764c504SNobuhiro Iwamatsu 	pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
491d764c504SNobuhiro Iwamatsu 	gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
492d764c504SNobuhiro Iwamatsu 	gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
493d764c504SNobuhiro Iwamatsu }
494d764c504SNobuhiro Iwamatsu 
pinmux_direction(struct pinmux_info * gpioc,unsigned gpio,int new_pinmux_type)495d764c504SNobuhiro Iwamatsu static int pinmux_direction(struct pinmux_info *gpioc,
496d764c504SNobuhiro Iwamatsu 			    unsigned gpio, int new_pinmux_type)
497d764c504SNobuhiro Iwamatsu {
498d764c504SNobuhiro Iwamatsu 	int pinmux_type;
499d764c504SNobuhiro Iwamatsu 	int ret = -1;
500d764c504SNobuhiro Iwamatsu 
501d764c504SNobuhiro Iwamatsu 	if (!gpioc)
502d764c504SNobuhiro Iwamatsu 		goto err_out;
503d764c504SNobuhiro Iwamatsu 
504d764c504SNobuhiro Iwamatsu 	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
505d764c504SNobuhiro Iwamatsu 
506d764c504SNobuhiro Iwamatsu 	switch (pinmux_type) {
507d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_GPIO:
508d764c504SNobuhiro Iwamatsu 		break;
509d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_OUTPUT:
510d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_INPUT:
511d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_INPUT_PULLUP:
512d764c504SNobuhiro Iwamatsu 	case PINMUX_TYPE_INPUT_PULLDOWN:
513d764c504SNobuhiro Iwamatsu 		pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
514d764c504SNobuhiro Iwamatsu 		break;
515d764c504SNobuhiro Iwamatsu 	default:
516d764c504SNobuhiro Iwamatsu 		goto err_out;
517d764c504SNobuhiro Iwamatsu 	}
518d764c504SNobuhiro Iwamatsu 
519d764c504SNobuhiro Iwamatsu 	if (pinmux_config_gpio(gpioc, gpio,
520d764c504SNobuhiro Iwamatsu 			       new_pinmux_type,
521d764c504SNobuhiro Iwamatsu 			       GPIO_CFG_DRYRUN) != 0)
522d764c504SNobuhiro Iwamatsu 		goto err_out;
523d764c504SNobuhiro Iwamatsu 
524d764c504SNobuhiro Iwamatsu 	if (pinmux_config_gpio(gpioc, gpio,
525d764c504SNobuhiro Iwamatsu 			       new_pinmux_type,
526d764c504SNobuhiro Iwamatsu 			       GPIO_CFG_REQ) != 0)
527d764c504SNobuhiro Iwamatsu 		BUG();
528d764c504SNobuhiro Iwamatsu 
529d764c504SNobuhiro Iwamatsu 	gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
530d764c504SNobuhiro Iwamatsu 	gpioc->gpios[gpio].flags |= new_pinmux_type;
531d764c504SNobuhiro Iwamatsu 
532d764c504SNobuhiro Iwamatsu 	ret = 0;
533d764c504SNobuhiro Iwamatsu  err_out:
534d764c504SNobuhiro Iwamatsu 	return ret;
535d764c504SNobuhiro Iwamatsu }
536d764c504SNobuhiro Iwamatsu 
sh_gpio_direction_input(unsigned offset)537d764c504SNobuhiro Iwamatsu static int sh_gpio_direction_input(unsigned offset)
538d764c504SNobuhiro Iwamatsu {
539d764c504SNobuhiro Iwamatsu 	return pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
540d764c504SNobuhiro Iwamatsu }
541d764c504SNobuhiro Iwamatsu 
sh_gpio_set_value(struct pinmux_info * gpioc,unsigned gpio,int value)542d764c504SNobuhiro Iwamatsu static void sh_gpio_set_value(struct pinmux_info *gpioc,
543d764c504SNobuhiro Iwamatsu 			     unsigned gpio, int value)
544d764c504SNobuhiro Iwamatsu {
545d764c504SNobuhiro Iwamatsu 	struct pinmux_data_reg *dr = NULL;
546d764c504SNobuhiro Iwamatsu 	int bit = 0;
547d764c504SNobuhiro Iwamatsu 
548d764c504SNobuhiro Iwamatsu 	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
549d764c504SNobuhiro Iwamatsu 		BUG();
550d764c504SNobuhiro Iwamatsu 	else
551d764c504SNobuhiro Iwamatsu 		gpio_write_bit(dr, bit, value);
552d764c504SNobuhiro Iwamatsu }
553d764c504SNobuhiro Iwamatsu 
sh_gpio_direction_output(unsigned offset,int value)554d764c504SNobuhiro Iwamatsu static int sh_gpio_direction_output(unsigned offset, int value)
555d764c504SNobuhiro Iwamatsu {
556d764c504SNobuhiro Iwamatsu 	sh_gpio_set_value(gpioc, offset, value);
557d764c504SNobuhiro Iwamatsu 	return pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
558d764c504SNobuhiro Iwamatsu }
559d764c504SNobuhiro Iwamatsu 
sh_gpio_get_value(struct pinmux_info * gpioc,unsigned gpio)560d764c504SNobuhiro Iwamatsu static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
561d764c504SNobuhiro Iwamatsu {
562d764c504SNobuhiro Iwamatsu 	struct pinmux_data_reg *dr = NULL;
563*1815c297SKouei Abe 	int bit = 0, offset = 0;
564d764c504SNobuhiro Iwamatsu 
565d764c504SNobuhiro Iwamatsu 	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
566d764c504SNobuhiro Iwamatsu 		return -1;
567*1815c297SKouei Abe #if defined(CONFIG_RCAR_GEN3)
568*1815c297SKouei Abe 	if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) == PINMUX_TYPE_INPUT)
569*1815c297SKouei Abe 		offset += 4;
570*1815c297SKouei Abe #endif
571d764c504SNobuhiro Iwamatsu 
572*1815c297SKouei Abe 	return gpio_read_bit(dr, offset, bit);
573d764c504SNobuhiro Iwamatsu }
574d764c504SNobuhiro Iwamatsu 
sh_gpio_get(unsigned offset)575d764c504SNobuhiro Iwamatsu static int sh_gpio_get(unsigned offset)
576d764c504SNobuhiro Iwamatsu {
577d764c504SNobuhiro Iwamatsu 	return sh_gpio_get_value(gpioc, offset);
578d764c504SNobuhiro Iwamatsu }
579d764c504SNobuhiro Iwamatsu 
sh_gpio_set(unsigned offset,int value)580d764c504SNobuhiro Iwamatsu static void sh_gpio_set(unsigned offset, int value)
581d764c504SNobuhiro Iwamatsu {
582d764c504SNobuhiro Iwamatsu 	sh_gpio_set_value(gpioc, offset, value);
583d764c504SNobuhiro Iwamatsu }
584d764c504SNobuhiro Iwamatsu 
register_pinmux(struct pinmux_info * pip)585d764c504SNobuhiro Iwamatsu int register_pinmux(struct pinmux_info *pip)
586d764c504SNobuhiro Iwamatsu {
587d764c504SNobuhiro Iwamatsu 	if (pip != NULL) {
588d764c504SNobuhiro Iwamatsu 		gpioc = pip;
589d764c504SNobuhiro Iwamatsu 		debug("%s deregistering\n", pip->name);
590d764c504SNobuhiro Iwamatsu 		setup_data_regs(gpioc);
591d764c504SNobuhiro Iwamatsu 	}
592d764c504SNobuhiro Iwamatsu 	return 0;
593d764c504SNobuhiro Iwamatsu }
594d764c504SNobuhiro Iwamatsu 
unregister_pinmux(struct pinmux_info * pip)595d764c504SNobuhiro Iwamatsu int unregister_pinmux(struct pinmux_info *pip)
596d764c504SNobuhiro Iwamatsu {
597d764c504SNobuhiro Iwamatsu 	debug("%s deregistering\n", pip->name);
598d764c504SNobuhiro Iwamatsu 	if (gpioc != pip)
599d764c504SNobuhiro Iwamatsu 		return -1;
600d764c504SNobuhiro Iwamatsu 
601d764c504SNobuhiro Iwamatsu 	gpioc = NULL;
602d764c504SNobuhiro Iwamatsu 	return 0;
603d764c504SNobuhiro Iwamatsu }
604d764c504SNobuhiro Iwamatsu 
gpio_request(unsigned gpio,const char * label)605d764c504SNobuhiro Iwamatsu int gpio_request(unsigned gpio, const char *label)
606d764c504SNobuhiro Iwamatsu {
607d764c504SNobuhiro Iwamatsu 	sh_gpio_request(gpio);
608d764c504SNobuhiro Iwamatsu 	return 0;
609d764c504SNobuhiro Iwamatsu }
610d764c504SNobuhiro Iwamatsu 
gpio_free(unsigned gpio)611d764c504SNobuhiro Iwamatsu int gpio_free(unsigned gpio)
612d764c504SNobuhiro Iwamatsu {
613d764c504SNobuhiro Iwamatsu 	sh_gpio_free(gpio);
614d764c504SNobuhiro Iwamatsu 	return 0;
615d764c504SNobuhiro Iwamatsu }
616d764c504SNobuhiro Iwamatsu 
gpio_direction_input(unsigned gpio)617d764c504SNobuhiro Iwamatsu int gpio_direction_input(unsigned gpio)
618d764c504SNobuhiro Iwamatsu {
619d764c504SNobuhiro Iwamatsu 	return sh_gpio_direction_input(gpio);
620d764c504SNobuhiro Iwamatsu }
621d764c504SNobuhiro Iwamatsu 
gpio_direction_output(unsigned gpio,int value)622d764c504SNobuhiro Iwamatsu int gpio_direction_output(unsigned gpio, int value)
623d764c504SNobuhiro Iwamatsu {
624d764c504SNobuhiro Iwamatsu 	return sh_gpio_direction_output(gpio, value);
625d764c504SNobuhiro Iwamatsu }
626d764c504SNobuhiro Iwamatsu 
gpio_set_value(unsigned gpio,int value)627d764c504SNobuhiro Iwamatsu void gpio_set_value(unsigned gpio, int value)
628d764c504SNobuhiro Iwamatsu {
629d764c504SNobuhiro Iwamatsu 	sh_gpio_set(gpio, value);
630d764c504SNobuhiro Iwamatsu }
631d764c504SNobuhiro Iwamatsu 
gpio_get_value(unsigned gpio)632d764c504SNobuhiro Iwamatsu int gpio_get_value(unsigned gpio)
633d764c504SNobuhiro Iwamatsu {
634d764c504SNobuhiro Iwamatsu 	return sh_gpio_get(gpio);
635d764c504SNobuhiro Iwamatsu }
636