smsc_sio1007.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <errno.h>
  9. #include <smsc_sio1007.h>
  10. static inline u8 sio1007_read(int port, int reg)
  11. {
  12. outb(reg, port);
  13. return inb(port + 1);
  14. }
  15. static inline void sio1007_write(int port, int reg, int val)
  16. {
  17. outb(reg, port);
  18. outb(val, port + 1);
  19. }
  20. static inline void sio1007_clrsetbits(int port, int reg, u8 clr, u8 set)
  21. {
  22. sio1007_write(port, reg, (sio1007_read(port, reg) & ~clr) | set);
  23. }
  24. void sio1007_enable_serial(int port, int num, int iobase, int irq)
  25. {
  26. if (num < 0 || num > SIO1007_UART_NUM)
  27. return;
  28. /* enter configuration state */
  29. outb(0x55, port);
  30. /* power on serial port and set up its i/o base & irq */
  31. if (!num) {
  32. sio1007_clrsetbits(port, DEV_POWER_CTRL, 0, UART1_POWER_ON);
  33. sio1007_clrsetbits(port, UART1_IOBASE, 0xfe, iobase >> 2);
  34. sio1007_clrsetbits(port, UART_IRQ, 0xf0, irq << 4);
  35. } else {
  36. sio1007_clrsetbits(port, DEV_POWER_CTRL, 0, UART2_POWER_ON);
  37. sio1007_clrsetbits(port, UART2_IOBASE, 0xfe, iobase >> 2);
  38. sio1007_clrsetbits(port, UART_IRQ, 0x0f, irq);
  39. }
  40. /* exit configuration state */
  41. outb(0xaa, port);
  42. }
  43. void sio1007_enable_runtime(int port, int iobase)
  44. {
  45. /* enter configuration state */
  46. outb(0x55, port);
  47. /* set i/o base for the runtime register block */
  48. sio1007_clrsetbits(port, RTR_IOBASE_LOW, 0, iobase >> 4);
  49. sio1007_clrsetbits(port, RTR_IOBASE_HIGH, 0, iobase >> 12);
  50. /* turn on address decoding for this block */
  51. sio1007_clrsetbits(port, DEV_ACTIVATE, 0, RTR_EN);
  52. /* exit configuration state */
  53. outb(0xaa, port);
  54. }
  55. void sio1007_gpio_config(int port, int gpio, int dir, int pol, int type)
  56. {
  57. int reg = GPIO0_DIR;
  58. if (gpio < 0 || gpio > SIO1007_GPIO_NUM)
  59. return;
  60. if (gpio >= GPIO_NUM_PER_GROUP) {
  61. reg = GPIO1_DIR;
  62. gpio -= GPIO_NUM_PER_GROUP;
  63. }
  64. /* enter configuration state */
  65. outb(0x55, port);
  66. /* set gpio pin direction, polority and type */
  67. sio1007_clrsetbits(port, reg, 1 << gpio, dir << gpio);
  68. sio1007_clrsetbits(port, reg + 1, 1 << gpio, pol << gpio);
  69. sio1007_clrsetbits(port, reg + 2, 1 << gpio, type << gpio);
  70. /* exit configuration state */
  71. outb(0xaa, port);
  72. }
  73. int sio1007_gpio_get_value(int port, int gpio)
  74. {
  75. int reg = GPIO0_DATA;
  76. int val;
  77. if (gpio < 0 || gpio > SIO1007_GPIO_NUM)
  78. return -EINVAL;
  79. if (gpio >= GPIO_NUM_PER_GROUP) {
  80. reg = GPIO1_DATA;
  81. gpio -= GPIO_NUM_PER_GROUP;
  82. }
  83. val = inb(port + reg);
  84. if (val & (1 << gpio))
  85. return 1;
  86. else
  87. return 0;
  88. }
  89. void sio1007_gpio_set_value(int port, int gpio, int val)
  90. {
  91. int reg = GPIO0_DATA;
  92. u8 data;
  93. if (gpio < 0 || gpio > SIO1007_GPIO_NUM)
  94. return;
  95. if (gpio >= GPIO_NUM_PER_GROUP) {
  96. reg = GPIO1_DATA;
  97. gpio -= GPIO_NUM_PER_GROUP;
  98. }
  99. data = inb(port + reg);
  100. data &= ~(1 << gpio);
  101. data |= (val << gpio);
  102. outb(data, port + reg);
  103. }