1/* 2 * linux/arch/arm/mach-omap2/mux.c 3 * 4 * OMAP2 and OMAP3 pin multiplexing configurations 5 * 6 * Copyright (C) 2004 - 2008 Texas Instruments Inc. 7 * Copyright (C) 2003 - 2008 Nokia Corporation 8 * 9 * Written by Tony Lindgren 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * 25 */ 26#include <linux/module.h> 27#include <linux/init.h> 28#include <linux/io.h> 29#include <linux/slab.h> 30#include <linux/spinlock.h> 31#include <linux/list.h> 32#include <linux/ctype.h> 33#include <linux/debugfs.h> 34#include <linux/seq_file.h> 35#include <linux/uaccess.h> 36 37#include <asm/system.h> 38 39#include <plat/control.h> 40 41#include "mux.h" 42 43#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ 44#define OMAP_MUX_BASE_SZ 0x5ca 45#define MUXABLE_GPIO_MODE3 BIT(0) 46 47struct omap_mux_entry { 48 struct omap_mux mux; 49 struct list_head node; 50}; 51 52static unsigned long mux_phys; 53static void __iomem *mux_base; 54static u8 omap_mux_flags; 55 56u16 omap_mux_read(u16 reg) 57{ 58 if (cpu_is_omap24xx()) 59 return __raw_readb(mux_base + reg); 60 else 61 return __raw_readw(mux_base + reg); 62} 63 64void omap_mux_write(u16 val, u16 reg) 65{ 66 if (cpu_is_omap24xx()) 67 __raw_writeb(val, mux_base + reg); 68 else 69 __raw_writew(val, mux_base + reg); 70} 71 72void omap_mux_write_array(struct omap_board_mux *board_mux) 73{ 74 while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { 75 omap_mux_write(board_mux->value, board_mux->reg_offset); 76 board_mux++; 77 } 78} 79 80static LIST_HEAD(muxmodes); 81static DEFINE_MUTEX(muxmode_mutex); 82 83#ifdef CONFIG_OMAP_MUX 84 85static char *omap_mux_options; 86 87int __init omap_mux_init_gpio(int gpio, int val) 88{ 89 struct omap_mux_entry *e; 90 struct omap_mux *gpio_mux; 91 u16 old_mode; 92 u16 mux_mode; 93 int found = 0; 94 95 if (!gpio) 96 return -EINVAL; 97 98 list_for_each_entry(e, &muxmodes, node) { 99 struct omap_mux *m = &e->mux; 100 if (gpio == m->gpio) { 101 gpio_mux = m; 102 found++; 103 } 104 } 105 106 if (found == 0) { 107 printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); 108 return -ENODEV; 109 } 110 111 if (found > 1) { 112 printk(KERN_INFO "mux: Multiple gpio paths (%d) for gpio%i\n", 113 found, gpio); 114 return -EINVAL; 115 } 116 117 old_mode = omap_mux_read(gpio_mux->reg_offset); 118 mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); 119 if (omap_mux_flags & MUXABLE_GPIO_MODE3) 120 mux_mode |= OMAP_MUX_MODE3; 121 else 122 mux_mode |= OMAP_MUX_MODE4; 123 printk(KERN_DEBUG "mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", 124 gpio_mux->muxnames[0], gpio, old_mode, mux_mode); 125 omap_mux_write(mux_mode, gpio_mux->reg_offset); 126 127 return 0; 128} 129 130int __init omap_mux_init_signal(char *muxname, int val) 131{ 132 struct omap_mux_entry *e; 133 char *m0_name = NULL, *mode_name = NULL; 134 int found = 0; 135 136 mode_name = strchr(muxname, '.'); 137 if (mode_name) { 138 *mode_name = '\0'; 139 mode_name++; 140 m0_name = muxname; 141 } else { 142 mode_name = muxname; 143 } 144 145 list_for_each_entry(e, &muxmodes, node) { 146 struct omap_mux *m = &e->mux; 147 char *m0_entry = m->muxnames[0]; 148 int i; 149 150 if (m0_name && strcmp(m0_name, m0_entry)) 151 continue; 152 153 for (i = 0; i < OMAP_MUX_NR_MODES; i++) { 154 char *mode_cur = m->muxnames[i]; 155 156 if (!mode_cur) 157 continue; 158 159 if (!strcmp(mode_name, mode_cur)) { 160 u16 old_mode; 161 u16 mux_mode; 162 163 old_mode = omap_mux_read(m->reg_offset); 164 mux_mode = val | i; 165 printk(KERN_DEBUG "mux: Setting signal " 166 "%s.%s 0x%04x -> 0x%04x\n", 167 m0_entry, muxname, old_mode, mux_mode); 168 omap_mux_write(mux_mode, m->reg_offset); 169 found++; 170 } 171 } 172 } 173 174 if (found == 1) 175 return 0; 176 177 if (found > 1) { 178 printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n", 179 found, muxname); 180 return -EINVAL; 181 } 182 183 printk(KERN_ERR "mux: Could not set signal %s\n", muxname); 184 185 return -ENODEV; 186} 187 188#ifdef CONFIG_DEBUG_FS 189 190#define OMAP_MUX_MAX_NR_FLAGS 10 191#define OMAP_MUX_TEST_FLAG(val, mask) \ 192 if (((val) & (mask)) == (mask)) { \ 193 i++; \ 194 flags[i] = #mask; \ 195 } 196 197/* REVISIT: Add checking for non-optimal mux settings */ 198static inline void omap_mux_decode(struct seq_file *s, u16 val) 199{ 200 char *flags[OMAP_MUX_MAX_NR_FLAGS]; 201 char mode[sizeof("OMAP_MUX_MODE") + 1]; 202 int i = -1; 203 204 sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7); 205 i++; 206 flags[i] = mode; 207 208 OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE); 209 if (val & OMAP_OFF_EN) { 210 if (!(val & OMAP_OFFOUT_EN)) { 211 if (!(val & OMAP_OFF_PULL_UP)) { 212 OMAP_MUX_TEST_FLAG(val, 213 OMAP_PIN_OFF_INPUT_PULLDOWN); 214 } else { 215 OMAP_MUX_TEST_FLAG(val, 216 OMAP_PIN_OFF_INPUT_PULLUP); 217 } 218 } else { 219 if (!(val & OMAP_OFFOUT_VAL)) { 220 OMAP_MUX_TEST_FLAG(val, 221 OMAP_PIN_OFF_OUTPUT_LOW); 222 } else { 223 OMAP_MUX_TEST_FLAG(val, 224 OMAP_PIN_OFF_OUTPUT_HIGH); 225 } 226 } 227 } 228 229 if (val & OMAP_INPUT_EN) { 230 if (val & OMAP_PULL_ENA) { 231 if (!(val & OMAP_PULL_UP)) { 232 OMAP_MUX_TEST_FLAG(val, 233 OMAP_PIN_INPUT_PULLDOWN); 234 } else { 235 OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP); 236 } 237 } else { 238 OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT); 239 } 240 } else { 241 i++; 242 flags[i] = "OMAP_PIN_OUTPUT"; 243 } 244 245 do { 246 seq_printf(s, "%s", flags[i]); 247 if (i > 0) 248 seq_printf(s, " | "); 249 } while (i-- > 0); 250} 251 252#define OMAP_MUX_DEFNAME_LEN 16 253 254static int omap_mux_dbg_board_show(struct seq_file *s, void *unused) 255{ 256 struct omap_mux_entry *e; 257 258 list_for_each_entry(e, &muxmodes, node) { 259 struct omap_mux *m = &e->mux; 260 char m0_def[OMAP_MUX_DEFNAME_LEN]; 261 char *m0_name = m->muxnames[0]; 262 u16 val; 263 int i, mode; 264 265 if (!m0_name) 266 continue; 267 268 /* REVISIT: Needs to be updated if mode0 names get longer */ 269 for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) { 270 if (m0_name[i] == '\0') { 271 m0_def[i] = m0_name[i]; 272 break; 273 } 274 m0_def[i] = toupper(m0_name[i]); 275 } 276 val = omap_mux_read(m->reg_offset); 277 mode = val & OMAP_MUX_MODE7; 278 279 seq_printf(s, "OMAP%i_MUX(%s, ", 280 cpu_is_omap34xx() ? 3 : 0, m0_def); 281 omap_mux_decode(s, val); 282 seq_printf(s, "),\n"); 283 } 284 285 return 0; 286} 287 288static int omap_mux_dbg_board_open(struct inode *inode, struct file *file) 289{ 290 return single_open(file, omap_mux_dbg_board_show, &inode->i_private); 291} 292 293static const struct file_operations omap_mux_dbg_board_fops = { 294 .open = omap_mux_dbg_board_open, 295 .read = seq_read, 296 .llseek = seq_lseek, 297 .release = single_release, 298}; 299 300static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused) 301{ 302 struct omap_mux *m = s->private; 303 const char *none = "NA"; 304 u16 val; 305 int mode; 306 307 val = omap_mux_read(m->reg_offset); 308 mode = val & OMAP_MUX_MODE7; 309 310 seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n", 311 m->muxnames[0], m->muxnames[mode], 312 mux_phys + m->reg_offset, m->reg_offset, val, 313 m->balls[0] ? m->balls[0] : none, 314 m->balls[1] ? m->balls[1] : none); 315 seq_printf(s, "mode: "); 316 omap_mux_decode(s, val); 317 seq_printf(s, "\n"); 318 seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n", 319 m->muxnames[0] ? m->muxnames[0] : none, 320 m->muxnames[1] ? m->muxnames[1] : none, 321 m->muxnames[2] ? m->muxnames[2] : none, 322 m->muxnames[3] ? m->muxnames[3] : none, 323 m->muxnames[4] ? m->muxnames[4] : none, 324 m->muxnames[5] ? m->muxnames[5] : none, 325 m->muxnames[6] ? m->muxnames[6] : none, 326 m->muxnames[7] ? m->muxnames[7] : none); 327 328 return 0; 329} 330 331#define OMAP_MUX_MAX_ARG_CHAR 7 332 333static ssize_t omap_mux_dbg_signal_write(struct file *file, 334 const char __user *user_buf, 335 size_t count, loff_t *ppos) 336{ 337 char buf[OMAP_MUX_MAX_ARG_CHAR]; 338 struct seq_file *seqf; 339 struct omap_mux *m; 340 unsigned long val; 341 int buf_size, ret; 342 343 if (count > OMAP_MUX_MAX_ARG_CHAR) 344 return -EINVAL; 345 346 memset(buf, 0, sizeof(buf)); 347 buf_size = min(count, sizeof(buf) - 1); 348 349 if (copy_from_user(buf, user_buf, buf_size)) 350 return -EFAULT; 351 352 ret = strict_strtoul(buf, 0x10, &val); 353 if (ret < 0) 354 return ret; 355 356 if (val > 0xffff) 357 return -EINVAL; 358 359 seqf = file->private_data; 360 m = seqf->private; 361 362 omap_mux_write((u16)val, m->reg_offset); 363 *ppos += count; 364 365 return count; 366} 367 368static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file) 369{ 370 return single_open(file, omap_mux_dbg_signal_show, inode->i_private); 371} 372 373static const struct file_operations omap_mux_dbg_signal_fops = { 374 .open = omap_mux_dbg_signal_open, 375 .read = seq_read, 376 .write = omap_mux_dbg_signal_write, 377 .llseek = seq_lseek, 378 .release = single_release, 379}; 380 381static struct dentry *mux_dbg_dir; 382 383static void __init omap_mux_dbg_init(void) 384{ 385 struct omap_mux_entry *e; 386 387 mux_dbg_dir = debugfs_create_dir("omap_mux", NULL); 388 if (!mux_dbg_dir) 389 return; 390 391 (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir, 392 NULL, &omap_mux_dbg_board_fops); 393 394 list_for_each_entry(e, &muxmodes, node) { 395 struct omap_mux *m = &e->mux; 396 397 (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir, 398 m, &omap_mux_dbg_signal_fops); 399 } 400} 401 402#else 403static inline void omap_mux_dbg_init(void) 404{ 405} 406#endif /* CONFIG_DEBUG_FS */ 407 408static void __init omap_mux_free_names(struct omap_mux *m) 409{ 410 int i; 411 412 for (i = 0; i < OMAP_MUX_NR_MODES; i++) 413 kfree(m->muxnames[i]); 414 415#ifdef CONFIG_DEBUG_FS 416 for (i = 0; i < OMAP_MUX_NR_SIDES; i++) 417 kfree(m->balls[i]); 418#endif 419 420} 421 422/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ 423static int __init omap_mux_late_init(void) 424{ 425 struct omap_mux_entry *e, *tmp; 426 427 list_for_each_entry_safe(e, tmp, &muxmodes, node) { 428 struct omap_mux *m = &e->mux; 429 u16 mode = omap_mux_read(m->reg_offset); 430 431 if (OMAP_MODE_GPIO(mode)) 432 continue; 433 434#ifndef CONFIG_DEBUG_FS 435 mutex_lock(&muxmode_mutex); 436 list_del(&e->node); 437 mutex_unlock(&muxmode_mutex); 438 omap_mux_free_names(m); 439 kfree(m); 440#endif 441 442 } 443 444 omap_mux_dbg_init(); 445 446 return 0; 447} 448late_initcall(omap_mux_late_init); 449 450static void __init omap_mux_package_fixup(struct omap_mux *p, 451 struct omap_mux *superset) 452{ 453 while (p->reg_offset != OMAP_MUX_TERMINATOR) { 454 struct omap_mux *s = superset; 455 int found = 0; 456 457 while (s->reg_offset != OMAP_MUX_TERMINATOR) { 458 if (s->reg_offset == p->reg_offset) { 459 *s = *p; 460 found++; 461 break; 462 } 463 s++; 464 } 465 if (!found) 466 printk(KERN_ERR "mux: Unknown entry offset 0x%x\n", 467 p->reg_offset); 468 p++; 469 } 470} 471 472#ifdef CONFIG_DEBUG_FS 473 474static void __init omap_mux_package_init_balls(struct omap_ball *b, 475 struct omap_mux *superset) 476{ 477 while (b->reg_offset != OMAP_MUX_TERMINATOR) { 478 struct omap_mux *s = superset; 479 int found = 0; 480 481 while (s->reg_offset != OMAP_MUX_TERMINATOR) { 482 if (s->reg_offset == b->reg_offset) { 483 s->balls[0] = b->balls[0]; 484 s->balls[1] = b->balls[1]; 485 found++; 486 break; 487 } 488 s++; 489 } 490 if (!found) 491 printk(KERN_ERR "mux: Unknown ball offset 0x%x\n", 492 b->reg_offset); 493 b++; 494 } 495} 496 497#else /* CONFIG_DEBUG_FS */ 498 499static inline void omap_mux_package_init_balls(struct omap_ball *b, 500 struct omap_mux *superset) 501{ 502} 503 504#endif /* CONFIG_DEBUG_FS */ 505 506static int __init omap_mux_setup(char *options) 507{ 508 if (!options) 509 return 0; 510 511 omap_mux_options = options; 512 513 return 1; 514} 515__setup("omap_mux=", omap_mux_setup); 516 517/* 518 * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234 519 * cmdline options only override the bootloader values. 520 * During development, please enable CONFIG_DEBUG_FS, and use the 521 * signal specific entries under debugfs. 522 */ 523static void __init omap_mux_set_cmdline_signals(void) 524{ 525 char *options, *next_opt, *token; 526 527 if (!omap_mux_options) 528 return; 529 530 options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL); 531 if (!options) 532 return; 533 534 strcpy(options, omap_mux_options); 535 next_opt = options; 536 537 while ((token = strsep(&next_opt, ",")) != NULL) { 538 char *keyval, *name; 539 unsigned long val; 540 541 keyval = token; 542 name = strsep(&keyval, "="); 543 if (name) { 544 int res; 545 546 res = strict_strtoul(keyval, 0x10, &val); 547 if (res < 0) 548 continue; 549 550 omap_mux_init_signal(name, (u16)val); 551 } 552 } 553 554 kfree(options); 555} 556 557static int __init omap_mux_copy_names(struct omap_mux *src, 558 struct omap_mux *dst) 559{ 560 int i; 561 562 for (i = 0; i < OMAP_MUX_NR_MODES; i++) { 563 if (src->muxnames[i]) { 564 dst->muxnames[i] = 565 kmalloc(strlen(src->muxnames[i]) + 1, 566 GFP_KERNEL); 567 if (!dst->muxnames[i]) 568 goto free; 569 strcpy(dst->muxnames[i], src->muxnames[i]); 570 } 571 } 572 573#ifdef CONFIG_DEBUG_FS 574 for (i = 0; i < OMAP_MUX_NR_SIDES; i++) { 575 if (src->balls[i]) { 576 dst->balls[i] = 577 kmalloc(strlen(src->balls[i]) + 1, 578 GFP_KERNEL); 579 if (!dst->balls[i]) 580 goto free; 581 strcpy(dst->balls[i], src->balls[i]); 582 } 583 } 584#endif 585 586 return 0; 587 588free: 589 omap_mux_free_names(dst); 590 return -ENOMEM; 591 592} 593 594#endif /* CONFIG_OMAP_MUX */ 595 596static u16 omap_mux_get_by_gpio(int gpio) 597{ 598 struct omap_mux_entry *e; 599 u16 offset = OMAP_MUX_TERMINATOR; 600 601 list_for_each_entry(e, &muxmodes, node) { 602 struct omap_mux *m = &e->mux; 603 if (m->gpio == gpio) { 604 offset = m->reg_offset; 605 break; 606 } 607 } 608 609 return offset; 610} 611 612/* Needed for dynamic muxing of GPIO pins for off-idle */ 613u16 omap_mux_get_gpio(int gpio) 614{ 615 u16 offset; 616 617 offset = omap_mux_get_by_gpio(gpio); 618 if (offset == OMAP_MUX_TERMINATOR) { 619 printk(KERN_ERR "mux: Could not get gpio%i\n", gpio); 620 return offset; 621 } 622 623 return omap_mux_read(offset); 624} 625 626/* Needed for dynamic muxing of GPIO pins for off-idle */ 627void omap_mux_set_gpio(u16 val, int gpio) 628{ 629 u16 offset; 630 631 offset = omap_mux_get_by_gpio(gpio); 632 if (offset == OMAP_MUX_TERMINATOR) { 633 printk(KERN_ERR "mux: Could not set gpio%i\n", gpio); 634 return; 635 } 636 637 omap_mux_write(val, offset); 638} 639 640static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src) 641{ 642 struct omap_mux_entry *entry; 643 struct omap_mux *m; 644 645 entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL); 646 if (!entry) 647 return NULL; 648 649 m = &entry->mux; 650 memcpy(m, src, sizeof(struct omap_mux_entry)); 651 652#ifdef CONFIG_OMAP_MUX 653 if (omap_mux_copy_names(src, m)) { 654 kfree(entry); 655 return NULL; 656 } 657#endif 658 659 mutex_lock(&muxmode_mutex); 660 list_add_tail(&entry->node, &muxmodes); 661 mutex_unlock(&muxmode_mutex); 662 663 return m; 664} 665 666/* 667 * Note if CONFIG_OMAP_MUX is not selected, we will only initialize 668 * the GPIO to mux offset mapping that is needed for dynamic muxing 669 * of GPIO pins for off-idle. 670 */ 671static void __init omap_mux_init_list(struct omap_mux *superset) 672{ 673 while (superset->reg_offset != OMAP_MUX_TERMINATOR) { 674 struct omap_mux *entry; 675 676#ifdef CONFIG_OMAP_MUX 677 if (!superset->muxnames || !superset->muxnames[0]) { 678 superset++; 679 continue; 680 } 681#else 682 /* Skip pins that are not muxed as GPIO by bootloader */ 683 if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) { 684 superset++; 685 continue; 686 } 687#endif 688 689 entry = omap_mux_list_add(superset); 690 if (!entry) { 691 printk(KERN_ERR "mux: Could not add entry\n"); 692 return; 693 } 694 superset++; 695 } 696} 697 698#ifdef CONFIG_OMAP_MUX 699 700static void omap_mux_init_package(struct omap_mux *superset, 701 struct omap_mux *package_subset, 702 struct omap_ball *package_balls) 703{ 704 if (package_subset) 705 omap_mux_package_fixup(package_subset, superset); 706 if (package_balls) 707 omap_mux_package_init_balls(package_balls, superset); 708} 709 710static void omap_mux_init_signals(struct omap_board_mux *board_mux) 711{ 712 omap_mux_set_cmdline_signals(); 713 omap_mux_write_array(board_mux); 714} 715 716#else 717 718static void omap_mux_init_package(struct omap_mux *superset, 719 struct omap_mux *package_subset, 720 struct omap_ball *package_balls) 721{ 722} 723 724static void omap_mux_init_signals(struct omap_board_mux *board_mux) 725{ 726} 727 728#endif 729 730int __init omap_mux_init(u32 mux_pbase, u32 mux_size, 731 struct omap_mux *superset, 732 struct omap_mux *package_subset, 733 struct omap_board_mux *board_mux, 734 struct omap_ball *package_balls) 735{ 736 if (mux_base) 737 return -EBUSY; 738 739 mux_phys = mux_pbase; 740 mux_base = ioremap(mux_pbase, mux_size); 741 if (!mux_base) { 742 printk(KERN_ERR "mux: Could not ioremap\n"); 743 return -ENODEV; 744 } 745 746 if (cpu_is_omap24xx()) 747 omap_mux_flags = MUXABLE_GPIO_MODE3; 748 749 omap_mux_init_package(superset, package_subset, package_balls); 750 omap_mux_init_list(superset); 751 omap_mux_init_signals(board_mux); 752 753 return 0; 754} 755