• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Pinmuxed GPIO support for SuperH.
3  *
4  * Copyright (C) 2008 Magnus Damm
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10 
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/irq.h>
19 #include <linux/bitops.h>
20 #include <linux/gpio.h>
21 
22 static struct pinmux_info *registered_gpio;
23 
gpio_controller(unsigned gpio)24 static struct pinmux_info *gpio_controller(unsigned gpio)
25 {
26 	if (!registered_gpio)
27 		return NULL;
28 
29 	if (gpio < registered_gpio->first_gpio)
30 		return NULL;
31 
32 	if (gpio > registered_gpio->last_gpio)
33 		return NULL;
34 
35 	return registered_gpio;
36 }
37 
enum_in_range(pinmux_enum_t enum_id,struct pinmux_range * r)38 static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
39 {
40 	if (enum_id < r->begin)
41 		return 0;
42 
43 	if (enum_id > r->end)
44 		return 0;
45 
46 	return 1;
47 }
48 
read_write_reg(unsigned long reg,unsigned long reg_width,unsigned long field_width,unsigned long in_pos,unsigned long value,int do_write)49 static int read_write_reg(unsigned long reg, unsigned long reg_width,
50 			  unsigned long field_width, unsigned long in_pos,
51 			  unsigned long value, int do_write)
52 {
53 	unsigned long data, mask, pos;
54 
55 	data = 0;
56 	mask = (1 << field_width) - 1;
57 	pos = reg_width - ((in_pos + 1) * field_width);
58 
59 #ifdef DEBUG
60 	pr_info("%s, addr = %lx, value = %ld, pos = %ld, "
61 		"r_width = %ld, f_width = %ld\n",
62 		do_write ? "write" : "read", reg, value, pos,
63 		reg_width, field_width);
64 #endif
65 
66 	switch (reg_width) {
67 	case 8:
68 		data = ctrl_inb(reg);
69 		break;
70 	case 16:
71 		data = ctrl_inw(reg);
72 		break;
73 	case 32:
74 		data = ctrl_inl(reg);
75 		break;
76 	}
77 
78 	if (!do_write)
79 		return (data >> pos) & mask;
80 
81 	data &= ~(mask << pos);
82 	data |= value << pos;
83 
84 	switch (reg_width) {
85 	case 8:
86 		ctrl_outb(data, reg);
87 		break;
88 	case 16:
89 		ctrl_outw(data, reg);
90 		break;
91 	case 32:
92 		ctrl_outl(data, reg);
93 		break;
94 	}
95 	return 0;
96 }
97 
get_data_reg(struct pinmux_info * gpioc,unsigned gpio,struct pinmux_data_reg ** drp,int * bitp)98 static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
99 			struct pinmux_data_reg **drp, int *bitp)
100 {
101 	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
102 	struct pinmux_data_reg *data_reg;
103 	int k, n;
104 
105 	if (!enum_in_range(enum_id, &gpioc->data))
106 		return -1;
107 
108 	k = 0;
109 	while (1) {
110 		data_reg = gpioc->data_regs + k;
111 
112 		if (!data_reg->reg_width)
113 			break;
114 
115 		for (n = 0; n < data_reg->reg_width; n++) {
116 			if (data_reg->enum_ids[n] == enum_id) {
117 				*drp = data_reg;
118 				*bitp = n;
119 				return 0;
120 
121 			}
122 		}
123 		k++;
124 	}
125 
126 	return -1;
127 }
128 
get_config_reg(struct pinmux_info * gpioc,pinmux_enum_t enum_id,struct pinmux_cfg_reg ** crp,int * indexp,unsigned long ** cntp)129 static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
130 			  struct pinmux_cfg_reg **crp, int *indexp,
131 			  unsigned long **cntp)
132 {
133 	struct pinmux_cfg_reg *config_reg;
134 	unsigned long r_width, f_width;
135 	int k, n;
136 
137 	k = 0;
138 	while (1) {
139 		config_reg = gpioc->cfg_regs + k;
140 
141 		r_width = config_reg->reg_width;
142 		f_width = config_reg->field_width;
143 
144 		if (!r_width)
145 			break;
146 		for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
147 			if (config_reg->enum_ids[n] == enum_id) {
148 				*crp = config_reg;
149 				*indexp = n;
150 				*cntp = &config_reg->cnt[n / (1 << f_width)];
151 				return 0;
152 			}
153 		}
154 		k++;
155 	}
156 
157 	return -1;
158 }
159 
get_gpio_enum_id(struct pinmux_info * gpioc,unsigned gpio,int pos,pinmux_enum_t * enum_idp)160 static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
161 			    int pos, pinmux_enum_t *enum_idp)
162 {
163 	pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
164 	pinmux_enum_t *data = gpioc->gpio_data;
165 	int k;
166 
167 	if (!enum_in_range(enum_id, &gpioc->data)) {
168 		if (!enum_in_range(enum_id, &gpioc->mark)) {
169 			pr_err("non data/mark enum_id for gpio %d\n", gpio);
170 			return -1;
171 		}
172 	}
173 
174 	if (pos) {
175 		*enum_idp = data[pos + 1];
176 		return pos + 1;
177 	}
178 
179 	for (k = 0; k < gpioc->gpio_data_size; k++) {
180 		if (data[k] == enum_id) {
181 			*enum_idp = data[k + 1];
182 			return k + 1;
183 		}
184 	}
185 
186 	pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
187 	return -1;
188 }
189 
write_config_reg(struct pinmux_info * gpioc,struct pinmux_cfg_reg * crp,int index)190 static int write_config_reg(struct pinmux_info *gpioc,
191 			    struct pinmux_cfg_reg *crp,
192 			    int index)
193 {
194 	unsigned long ncomb, pos, value;
195 
196 	ncomb = 1 << crp->field_width;
197 	pos = index / ncomb;
198 	value = index % ncomb;
199 
200 	return read_write_reg(crp->reg, crp->reg_width,
201 			      crp->field_width, pos, value, 1);
202 }
203 
check_config_reg(struct pinmux_info * gpioc,struct pinmux_cfg_reg * crp,int index)204 static int check_config_reg(struct pinmux_info *gpioc,
205 			    struct pinmux_cfg_reg *crp,
206 			    int index)
207 {
208 	unsigned long ncomb, pos, value;
209 
210 	ncomb = 1 << crp->field_width;
211 	pos = index / ncomb;
212 	value = index % ncomb;
213 
214 	if (read_write_reg(crp->reg, crp->reg_width,
215 			   crp->field_width, pos, 0, 0) == value)
216 		return 0;
217 
218 	return -1;
219 }
220 
221 enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
222 
pinmux_config_gpio(struct pinmux_info * gpioc,unsigned gpio,int pinmux_type,int cfg_mode)223 int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
224 		       int pinmux_type, int cfg_mode)
225 {
226 	struct pinmux_cfg_reg *cr = NULL;
227 	pinmux_enum_t enum_id;
228 	struct pinmux_range *range;
229 	int in_range, pos, index;
230 	unsigned long *cntp;
231 
232 	switch (pinmux_type) {
233 
234 	case PINMUX_TYPE_FUNCTION:
235 		range = NULL;
236 		break;
237 
238 	case PINMUX_TYPE_OUTPUT:
239 		range = &gpioc->output;
240 		break;
241 
242 	case PINMUX_TYPE_INPUT:
243 		range = &gpioc->input;
244 		break;
245 
246 	case PINMUX_TYPE_INPUT_PULLUP:
247 		range = &gpioc->input_pu;
248 		break;
249 
250 	case PINMUX_TYPE_INPUT_PULLDOWN:
251 		range = &gpioc->input_pd;
252 		break;
253 
254 	default:
255 		goto out_err;
256 	}
257 
258 	pos = 0;
259 	enum_id = 0;
260 	index = 0;
261 	while (1) {
262 		pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
263 		if (pos <= 0)
264 			goto out_err;
265 
266 		if (!enum_id)
267 			break;
268 
269 		in_range = enum_in_range(enum_id, &gpioc->function);
270 		if (!in_range && range) {
271 			in_range = enum_in_range(enum_id, range);
272 
273 			if (in_range && enum_id == range->force)
274 				continue;
275 		}
276 
277 		if (!in_range)
278 			continue;
279 
280 		if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
281 			goto out_err;
282 
283 		switch (cfg_mode) {
284 		case GPIO_CFG_DRYRUN:
285 			if (!*cntp || !check_config_reg(gpioc, cr, index))
286 				continue;
287 			break;
288 
289 		case GPIO_CFG_REQ:
290 			if (write_config_reg(gpioc, cr, index) != 0)
291 				goto out_err;
292 			*cntp = *cntp + 1;
293 			break;
294 
295 		case GPIO_CFG_FREE:
296 			*cntp = *cntp - 1;
297 			break;
298 		}
299 	}
300 
301 	return 0;
302  out_err:
303 	return -1;
304 }
305 
306 static DEFINE_SPINLOCK(gpio_lock);
307 
__gpio_request(unsigned gpio)308 int __gpio_request(unsigned gpio)
309 {
310 	struct pinmux_info *gpioc = gpio_controller(gpio);
311 	struct pinmux_data_reg *dummy;
312 	unsigned long flags;
313 	int i, ret, pinmux_type;
314 
315 	ret = -EINVAL;
316 
317 	if (!gpioc)
318 		goto err_out;
319 
320 	spin_lock_irqsave(&gpio_lock, flags);
321 
322 	if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
323 		goto err_unlock;
324 
325 	/* setup pin function here if no data is associated with pin */
326 
327 	if (get_data_reg(gpioc, gpio, &dummy, &i) != 0)
328 		pinmux_type = PINMUX_TYPE_FUNCTION;
329 	else
330 		pinmux_type = PINMUX_TYPE_GPIO;
331 
332 	if (pinmux_type == PINMUX_TYPE_FUNCTION) {
333 		if (pinmux_config_gpio(gpioc, gpio,
334 				       pinmux_type,
335 				       GPIO_CFG_DRYRUN) != 0)
336 			goto err_unlock;
337 
338 		if (pinmux_config_gpio(gpioc, gpio,
339 				       pinmux_type,
340 				       GPIO_CFG_REQ) != 0)
341 			BUG();
342 	}
343 
344 	gpioc->gpios[gpio].flags = pinmux_type;
345 
346 	ret = 0;
347  err_unlock:
348 	spin_unlock_irqrestore(&gpio_lock, flags);
349  err_out:
350 	return ret;
351 }
352 EXPORT_SYMBOL(__gpio_request);
353 
gpio_free(unsigned gpio)354 void gpio_free(unsigned gpio)
355 {
356 	struct pinmux_info *gpioc = gpio_controller(gpio);
357 	unsigned long flags;
358 	int pinmux_type;
359 
360 	if (!gpioc)
361 		return;
362 
363 	spin_lock_irqsave(&gpio_lock, flags);
364 
365 	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
366 	pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
367 	gpioc->gpios[gpio].flags = PINMUX_TYPE_NONE;
368 
369 	spin_unlock_irqrestore(&gpio_lock, flags);
370 }
371 EXPORT_SYMBOL(gpio_free);
372 
pinmux_direction(struct pinmux_info * gpioc,unsigned gpio,int new_pinmux_type)373 static int pinmux_direction(struct pinmux_info *gpioc,
374 			    unsigned gpio, int new_pinmux_type)
375 {
376 	int ret, pinmux_type;
377 
378 	ret = -EINVAL;
379 	pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
380 
381 	switch (pinmux_type) {
382 	case PINMUX_TYPE_GPIO:
383 		break;
384 	case PINMUX_TYPE_OUTPUT:
385 	case PINMUX_TYPE_INPUT:
386 	case PINMUX_TYPE_INPUT_PULLUP:
387 	case PINMUX_TYPE_INPUT_PULLDOWN:
388 		pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
389 		break;
390 	default:
391 		goto err_out;
392 	}
393 
394 	if (pinmux_config_gpio(gpioc, gpio,
395 			       new_pinmux_type,
396 			       GPIO_CFG_DRYRUN) != 0)
397 		goto err_out;
398 
399 	if (pinmux_config_gpio(gpioc, gpio,
400 			       new_pinmux_type,
401 			       GPIO_CFG_REQ) != 0)
402 		BUG();
403 
404 	gpioc->gpios[gpio].flags = new_pinmux_type;
405 
406 	ret = 0;
407  err_out:
408 	return ret;
409 }
410 
gpio_direction_input(unsigned gpio)411 int gpio_direction_input(unsigned gpio)
412 {
413 	struct pinmux_info *gpioc = gpio_controller(gpio);
414 	unsigned long flags;
415 	int ret = -EINVAL;
416 
417 	if (!gpioc)
418 		goto err_out;
419 
420 	spin_lock_irqsave(&gpio_lock, flags);
421 	ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
422 	spin_unlock_irqrestore(&gpio_lock, flags);
423  err_out:
424 	return ret;
425 }
426 EXPORT_SYMBOL(gpio_direction_input);
427 
__gpio_get_set_value(struct pinmux_info * gpioc,unsigned gpio,int value,int do_write)428 static int __gpio_get_set_value(struct pinmux_info *gpioc,
429 				unsigned gpio, int value,
430 				int do_write)
431 {
432 	struct pinmux_data_reg *dr = NULL;
433 	int bit = 0;
434 
435 	if (get_data_reg(gpioc, gpio, &dr, &bit) != 0)
436 		BUG();
437 	else
438 		value = read_write_reg(dr->reg, dr->reg_width,
439 				       1, bit, !!value, do_write);
440 
441 	return value;
442 }
443 
gpio_direction_output(unsigned gpio,int value)444 int gpio_direction_output(unsigned gpio, int value)
445 {
446 	struct pinmux_info *gpioc = gpio_controller(gpio);
447 	unsigned long flags;
448 	int ret = -EINVAL;
449 
450 	if (!gpioc)
451 		goto err_out;
452 
453 	spin_lock_irqsave(&gpio_lock, flags);
454 	__gpio_get_set_value(gpioc, gpio, value, 1);
455 	ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
456 	spin_unlock_irqrestore(&gpio_lock, flags);
457  err_out:
458 	return ret;
459 }
460 EXPORT_SYMBOL(gpio_direction_output);
461 
gpio_get_value(unsigned gpio)462 int gpio_get_value(unsigned gpio)
463 {
464 	struct pinmux_info *gpioc = gpio_controller(gpio);
465 	unsigned long flags;
466 	int value = 0;
467 
468 	if (!gpioc)
469 		BUG();
470 	else {
471 		spin_lock_irqsave(&gpio_lock, flags);
472 		value = __gpio_get_set_value(gpioc, gpio, 0, 0);
473 		spin_unlock_irqrestore(&gpio_lock, flags);
474 	}
475 
476 	return value;
477 }
478 EXPORT_SYMBOL(gpio_get_value);
479 
gpio_set_value(unsigned gpio,int value)480 void gpio_set_value(unsigned gpio, int value)
481 {
482 	struct pinmux_info *gpioc = gpio_controller(gpio);
483 	unsigned long flags;
484 
485 	if (!gpioc)
486 		BUG();
487 	else {
488 		spin_lock_irqsave(&gpio_lock, flags);
489 		__gpio_get_set_value(gpioc, gpio, value, 1);
490 		spin_unlock_irqrestore(&gpio_lock, flags);
491 	}
492 }
493 EXPORT_SYMBOL(gpio_set_value);
494 
register_pinmux(struct pinmux_info * pip)495 int register_pinmux(struct pinmux_info *pip)
496 {
497 	registered_gpio = pip;
498 	pr_info("pinmux: %s handling gpio %d -> %d\n",
499 		pip->name, pip->first_gpio, pip->last_gpio);
500 
501 	return 0;
502 }
503