vreg.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* arch/arm/mach-msm/vreg.c
  2. *
  3. * Copyright (C) 2008 Google, Inc.
  4. * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
  5. * Author: Brian Swetland <swetland@google.com>
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/device.h>
  19. #include <linux/init.h>
  20. #include <linux/debugfs.h>
  21. #include <linux/module.h>
  22. #include <linux/string.h>
  23. #include <mach/vreg.h>
  24. #include "proc_comm.h"
  25. struct vreg {
  26. const char *name;
  27. unsigned id;
  28. int status;
  29. unsigned refcnt;
  30. };
  31. #define VREG(_name, _id, _status, _refcnt) \
  32. { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
  33. static struct vreg vregs[] = {
  34. VREG("msma", 0, 0, 0),
  35. VREG("msmp", 1, 0, 0),
  36. VREG("msme1", 2, 0, 0),
  37. VREG("msmc1", 3, 0, 0),
  38. VREG("msmc2", 4, 0, 0),
  39. VREG("gp3", 5, 0, 0),
  40. VREG("msme2", 6, 0, 0),
  41. VREG("gp4", 7, 0, 0),
  42. VREG("gp1", 8, 0, 0),
  43. VREG("tcxo", 9, 0, 0),
  44. VREG("pa", 10, 0, 0),
  45. VREG("rftx", 11, 0, 0),
  46. VREG("rfrx1", 12, 0, 0),
  47. VREG("rfrx2", 13, 0, 0),
  48. VREG("synt", 14, 0, 0),
  49. VREG("wlan", 15, 0, 0),
  50. VREG("usb", 16, 0, 0),
  51. VREG("boost", 17, 0, 0),
  52. VREG("mmc", 18, 0, 0),
  53. VREG("ruim", 19, 0, 0),
  54. VREG("msmc0", 20, 0, 0),
  55. VREG("gp2", 21, 0, 0),
  56. VREG("gp5", 22, 0, 0),
  57. VREG("gp6", 23, 0, 0),
  58. VREG("rf", 24, 0, 0),
  59. VREG("rf_vco", 26, 0, 0),
  60. VREG("mpll", 27, 0, 0),
  61. VREG("s2", 28, 0, 0),
  62. VREG("s3", 29, 0, 0),
  63. VREG("rfubm", 30, 0, 0),
  64. VREG("ncp", 31, 0, 0),
  65. VREG("gp7", 32, 0, 0),
  66. VREG("gp8", 33, 0, 0),
  67. VREG("gp9", 34, 0, 0),
  68. VREG("gp10", 35, 0, 0),
  69. VREG("gp11", 36, 0, 0),
  70. VREG("gp12", 37, 0, 0),
  71. VREG("gp13", 38, 0, 0),
  72. VREG("gp14", 39, 0, 0),
  73. VREG("gp15", 40, 0, 0),
  74. VREG("gp16", 41, 0, 0),
  75. VREG("gp17", 42, 0, 0),
  76. VREG("s4", 43, 0, 0),
  77. VREG("usb2", 44, 0, 0),
  78. VREG("wlan2", 45, 0, 0),
  79. VREG("xo_out", 46, 0, 0),
  80. VREG("lvsw0", 47, 0, 0),
  81. VREG("lvsw1", 48, 0, 0),
  82. };
  83. struct vreg *vreg_get(struct device *dev, const char *id)
  84. {
  85. int n;
  86. for (n = 0; n < ARRAY_SIZE(vregs); n++) {
  87. if (!strcmp(vregs[n].name, id))
  88. return vregs + n;
  89. }
  90. return ERR_PTR(-ENOENT);
  91. }
  92. void vreg_put(struct vreg *vreg)
  93. {
  94. }
  95. int vreg_enable(struct vreg *vreg)
  96. {
  97. unsigned id = vreg->id;
  98. unsigned enable = 1;
  99. if (vreg->refcnt == 0)
  100. vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
  101. if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
  102. vreg->refcnt++;
  103. return vreg->status;
  104. }
  105. int vreg_disable(struct vreg *vreg)
  106. {
  107. unsigned id = vreg->id;
  108. unsigned enable = 0;
  109. if (!vreg->refcnt)
  110. return 0;
  111. if (vreg->refcnt == 1)
  112. vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
  113. if (!vreg->status)
  114. vreg->refcnt--;
  115. return vreg->status;
  116. }
  117. int vreg_set_level(struct vreg *vreg, unsigned mv)
  118. {
  119. unsigned id = vreg->id;
  120. vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
  121. return vreg->status;
  122. }
  123. #if defined(CONFIG_DEBUG_FS)
  124. static int vreg_debug_set(void *data, u64 val)
  125. {
  126. struct vreg *vreg = data;
  127. switch (val) {
  128. case 0:
  129. vreg_disable(vreg);
  130. break;
  131. case 1:
  132. vreg_enable(vreg);
  133. break;
  134. default:
  135. vreg_set_level(vreg, val);
  136. break;
  137. }
  138. return 0;
  139. }
  140. static int vreg_debug_get(void *data, u64 *val)
  141. {
  142. struct vreg *vreg = data;
  143. if (!vreg->status)
  144. *val = 0;
  145. else
  146. *val = 1;
  147. return 0;
  148. }
  149. static int vreg_debug_count_set(void *data, u64 val)
  150. {
  151. struct vreg *vreg = data;
  152. if (val > UINT_MAX)
  153. val = UINT_MAX;
  154. vreg->refcnt = val;
  155. return 0;
  156. }
  157. static int vreg_debug_count_get(void *data, u64 *val)
  158. {
  159. struct vreg *vreg = data;
  160. *val = vreg->refcnt;
  161. return 0;
  162. }
  163. DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
  164. DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
  165. vreg_debug_count_set, "%llu\n");
  166. static int __init vreg_debug_init(void)
  167. {
  168. struct dentry *dent;
  169. int n;
  170. char name[32];
  171. const char *refcnt_name = "_refcnt";
  172. dent = debugfs_create_dir("vreg", 0);
  173. if (IS_ERR(dent))
  174. return 0;
  175. for (n = 0; n < ARRAY_SIZE(vregs); n++) {
  176. (void) debugfs_create_file(vregs[n].name, 0644,
  177. dent, vregs + n, &vreg_fops);
  178. strlcpy(name, vregs[n].name, sizeof(name));
  179. strlcat(name, refcnt_name, sizeof(name));
  180. (void) debugfs_create_file(name, 0644,
  181. dent, vregs + n, &vreg_count_fops);
  182. }
  183. return 0;
  184. }
  185. device_initcall(vreg_debug_init);
  186. #endif