fsl_pmic.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <config.h>
  23. #include <common.h>
  24. #include <asm/errno.h>
  25. #include <linux/types.h>
  26. #include <fsl_pmic.h>
  27. static int check_param(u32 reg, u32 write)
  28. {
  29. if (reg > 63 || write > 1) {
  30. printf("<reg num> = %d is invalid. Should be less then 63\n",
  31. reg);
  32. return -1;
  33. }
  34. return 0;
  35. }
  36. #ifdef CONFIG_FSL_PMIC_I2C
  37. #include <i2c.h>
  38. u32 pmic_reg(u32 reg, u32 val, u32 write)
  39. {
  40. unsigned char buf[4] = { 0 };
  41. u32 ret_val = 0;
  42. if (check_param(reg, write))
  43. return -1;
  44. if (write) {
  45. buf[0] = (val >> 16) & 0xff;
  46. buf[1] = (val >> 8) & 0xff;
  47. buf[2] = (val) & 0xff;
  48. if (i2c_write(CONFIG_SYS_FSL_PMIC_I2C_ADDR, reg, 1, buf, 3))
  49. return -1;
  50. } else {
  51. if (i2c_read(CONFIG_SYS_FSL_PMIC_I2C_ADDR, reg, 1, buf, 3))
  52. return -1;
  53. ret_val = buf[0] << 16 | buf[1] << 8 | buf[2];
  54. }
  55. return ret_val;
  56. }
  57. #else /* SPI interface */
  58. #include <spi.h>
  59. static struct spi_slave *slave;
  60. struct spi_slave *pmic_spi_probe(void)
  61. {
  62. return spi_setup_slave(CONFIG_FSL_PMIC_BUS,
  63. CONFIG_FSL_PMIC_CS,
  64. CONFIG_FSL_PMIC_CLK,
  65. CONFIG_FSL_PMIC_MODE);
  66. }
  67. void pmic_spi_free(struct spi_slave *slave)
  68. {
  69. if (slave)
  70. spi_free_slave(slave);
  71. }
  72. u32 pmic_reg(u32 reg, u32 val, u32 write)
  73. {
  74. u32 pmic_tx, pmic_rx;
  75. u32 tmp;
  76. if (!slave) {
  77. slave = pmic_spi_probe();
  78. if (!slave)
  79. return -1;
  80. }
  81. if (check_param(reg, write))
  82. return -1;
  83. if (spi_claim_bus(slave))
  84. return -1;
  85. pmic_tx = (write << 31) | (reg << 25) | (val & 0x00FFFFFF);
  86. tmp = cpu_to_be32(pmic_tx);
  87. if (spi_xfer(slave, 4 << 3, &tmp, &pmic_rx,
  88. SPI_XFER_BEGIN | SPI_XFER_END)) {
  89. spi_release_bus(slave);
  90. return -1;
  91. }
  92. if (write) {
  93. pmic_tx &= ~(1 << 31);
  94. tmp = cpu_to_be32(pmic_tx);
  95. if (spi_xfer(slave, 4 << 3, &tmp, &pmic_rx,
  96. SPI_XFER_BEGIN | SPI_XFER_END)) {
  97. spi_release_bus(slave);
  98. return -1;
  99. }
  100. }
  101. spi_release_bus(slave);
  102. return cpu_to_be32(pmic_rx);
  103. }
  104. #endif
  105. void pmic_reg_write(u32 reg, u32 value)
  106. {
  107. pmic_reg(reg, value, 1);
  108. }
  109. u32 pmic_reg_read(u32 reg)
  110. {
  111. return pmic_reg(reg, 0, 0);
  112. }
  113. void pmic_show_pmic_info(void)
  114. {
  115. u32 rev_id;
  116. rev_id = pmic_reg_read(REG_IDENTIFICATION);
  117. printf("PMIC ID: 0x%08x [Rev: ", rev_id);
  118. switch (rev_id & 0x1F) {
  119. case 0x1:
  120. puts("1.0");
  121. break;
  122. case 0x9:
  123. puts("1.1");
  124. break;
  125. case 0xA:
  126. puts("1.2");
  127. break;
  128. case 0x10:
  129. puts("2.0");
  130. break;
  131. case 0x11:
  132. puts("2.1");
  133. break;
  134. case 0x18:
  135. puts("3.0");
  136. break;
  137. case 0x19:
  138. puts("3.1");
  139. break;
  140. case 0x1A:
  141. puts("3.2");
  142. break;
  143. case 0x2:
  144. puts("3.2A");
  145. break;
  146. case 0x1B:
  147. puts("3.3");
  148. break;
  149. case 0x1D:
  150. puts("3.5");
  151. break;
  152. default:
  153. puts("unknown");
  154. break;
  155. }
  156. puts("]\n");
  157. }
  158. static void pmic_dump(int numregs)
  159. {
  160. u32 val;
  161. int i;
  162. pmic_show_pmic_info();
  163. for (i = 0; i < numregs; i++) {
  164. val = pmic_reg_read(i);
  165. if (!(i % 8))
  166. printf ("\n0x%02x: ", i);
  167. printf("%08x ", val);
  168. }
  169. puts("\n");
  170. }
  171. int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  172. {
  173. char *cmd;
  174. int nregs;
  175. u32 val;
  176. /* at least two arguments please */
  177. if (argc < 2)
  178. return cmd_usage(cmdtp);
  179. cmd = argv[1];
  180. if (strcmp(cmd, "dump") == 0) {
  181. if (argc < 3)
  182. return cmd_usage(cmdtp);
  183. nregs = simple_strtoul(argv[2], NULL, 16);
  184. pmic_dump(nregs);
  185. return 0;
  186. }
  187. if (strcmp(cmd, "write") == 0) {
  188. if (argc < 4)
  189. return cmd_usage(cmdtp);
  190. nregs = simple_strtoul(argv[2], NULL, 16);
  191. val = simple_strtoul(argv[3], NULL, 16);
  192. pmic_reg_write(nregs, val);
  193. return 0;
  194. }
  195. /* No subcommand found */
  196. return 1;
  197. }
  198. U_BOOT_CMD(
  199. pmic, CONFIG_SYS_MAXARGS, 1, do_pmic,
  200. "Freescale PMIC (Atlas)",
  201. "dump [numregs] dump registers\n"
  202. "pmic write <reg> <value> - write register"
  203. );