padmux.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * arch/arm/plat-spear/include/plat/padmux.c
  3. *
  4. * SPEAr platform specific gpio pads muxing source file
  5. *
  6. * Copyright (C) 2009 ST Microelectronics
  7. * Viresh Kumar<viresh.kumar@st.com>
  8. *
  9. * This file is licensed under the terms of the GNU General Public
  10. * License version 2. This program is licensed "as is" without any
  11. * warranty of any kind, whether express or implied.
  12. */
  13. #include <linux/err.h>
  14. #include <linux/io.h>
  15. #include <linux/slab.h>
  16. #include <plat/padmux.h>
  17. /*
  18. * struct pmx: pmx definition structure
  19. *
  20. * base: base address of configuration registers
  21. * mode_reg: mode configurations
  22. * mux_reg: muxing configurations
  23. * active_mode: pointer to current active mode
  24. */
  25. struct pmx {
  26. u32 base;
  27. struct pmx_reg mode_reg;
  28. struct pmx_reg mux_reg;
  29. struct pmx_mode *active_mode;
  30. };
  31. static struct pmx *pmx;
  32. /**
  33. * pmx_mode_set - Enables an multiplexing mode
  34. * @mode - pointer to pmx mode
  35. *
  36. * It will set mode of operation in hardware.
  37. * Returns -ve on Err otherwise 0
  38. */
  39. static int pmx_mode_set(struct pmx_mode *mode)
  40. {
  41. u32 val;
  42. if (!mode->name)
  43. return -EFAULT;
  44. pmx->active_mode = mode;
  45. val = readl(pmx->base + pmx->mode_reg.offset);
  46. val &= ~pmx->mode_reg.mask;
  47. val |= mode->mask & pmx->mode_reg.mask;
  48. writel(val, pmx->base + pmx->mode_reg.offset);
  49. return 0;
  50. }
  51. /**
  52. * pmx_devs_enable - Enables list of devices
  53. * @devs - pointer to pmx device array
  54. * @count - number of devices to enable
  55. *
  56. * It will enable pads for all required peripherals once and only once.
  57. * If peripheral is not supported by current mode then request is rejected.
  58. * Conflicts between peripherals are not handled and peripherals will be
  59. * enabled in the order they are present in pmx_dev array.
  60. * In case of conflicts last peripheral enabled will be present.
  61. * Returns -ve on Err otherwise 0
  62. */
  63. static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
  64. {
  65. u32 val, i, mask;
  66. if (!count)
  67. return -EINVAL;
  68. val = readl(pmx->base + pmx->mux_reg.offset);
  69. for (i = 0; i < count; i++) {
  70. u8 j = 0;
  71. if (!devs[i]->name || !devs[i]->modes) {
  72. printk(KERN_ERR "padmux: dev name or modes is null\n");
  73. continue;
  74. }
  75. /* check if peripheral exists in active mode */
  76. if (pmx->active_mode) {
  77. bool found = false;
  78. for (j = 0; j < devs[i]->mode_count; j++) {
  79. if (devs[i]->modes[j].ids &
  80. pmx->active_mode->id) {
  81. found = true;
  82. break;
  83. }
  84. }
  85. if (found == false) {
  86. printk(KERN_ERR "%s device not available in %s"\
  87. "mode\n", devs[i]->name,
  88. pmx->active_mode->name);
  89. continue;
  90. }
  91. }
  92. /* enable peripheral */
  93. mask = devs[i]->modes[j].mask & pmx->mux_reg.mask;
  94. if (devs[i]->enb_on_reset)
  95. val &= ~mask;
  96. else
  97. val |= mask;
  98. devs[i]->is_active = true;
  99. }
  100. writel(val, pmx->base + pmx->mux_reg.offset);
  101. kfree(pmx);
  102. /* this will ensure that multiplexing can't be changed now */
  103. pmx = (struct pmx *)-1;
  104. return 0;
  105. }
  106. /**
  107. * pmx_register - registers a platform requesting pad mux feature
  108. * @driver - pointer to driver structure containing driver specific parameters
  109. *
  110. * Also this must be called only once. This will allocate memory for pmx
  111. * structure, will call pmx_mode_set, will call pmx_devs_enable.
  112. * Returns -ve on Err otherwise 0
  113. */
  114. int pmx_register(struct pmx_driver *driver)
  115. {
  116. int ret = 0;
  117. if (pmx)
  118. return -EPERM;
  119. if (!driver->base || !driver->devs)
  120. return -EFAULT;
  121. pmx = kzalloc(sizeof(*pmx), GFP_KERNEL);
  122. if (!pmx)
  123. return -ENOMEM;
  124. pmx->base = (u32)driver->base;
  125. pmx->mode_reg.offset = driver->mode_reg.offset;
  126. pmx->mode_reg.mask = driver->mode_reg.mask;
  127. pmx->mux_reg.offset = driver->mux_reg.offset;
  128. pmx->mux_reg.mask = driver->mux_reg.mask;
  129. /* choose mode to enable */
  130. if (driver->mode) {
  131. ret = pmx_mode_set(driver->mode);
  132. if (ret)
  133. goto pmx_fail;
  134. }
  135. ret = pmx_devs_enable(driver->devs, driver->devs_count);
  136. if (ret)
  137. goto pmx_fail;
  138. return 0;
  139. pmx_fail:
  140. return ret;
  141. }