ec_version.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/init.h>
  4. #include <linux/fs.h>
  5. #include <linux/cdev.h>
  6. #include <linux/device.h>
  7. #include <linux/uaccess.h>
  8. #include <linux/slab.h>
  9. #include <linux/pci.h>
  10. #include <linux/i2c.h>
  11. #include <linux/acpi.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/wait.h>
  14. #include <linux/sched.h>
  15. #include <linux/poll.h>
  16. #include <linux/mutex.h>
  17. #include <linux/delay.h>
  18. #include <asm/io.h>
  19. #include "gpioregs.h"
  20. extern struct kobject *vfiec_kobj;
  21. static int wait_ibf(void)
  22. {
  23. int i = 0;
  24. while (inb(EC_CMD_PORT) & EC_IBF)
  25. {
  26. if (++i > TIMEOUT_LOOPS)
  27. {
  28. return -1;
  29. }
  30. udelay(1);
  31. }
  32. return 0;
  33. }
  34. static int wait_obf(void)
  35. {
  36. int i = 0;
  37. while (!(inb(EC_CMD_PORT) & EC_OBF))
  38. {
  39. if (++i > TIMEOUT_LOOPS)
  40. {
  41. return -1;
  42. }
  43. udelay(1);
  44. }
  45. return 0;
  46. }
  47. static int oem_ec_read_ram(uint8_t page, uint8_t offset, uint8_t *data)
  48. {
  49. unsigned char WEC, REC;
  50. switch(page)
  51. {
  52. case 0:
  53. {
  54. WEC = 0x96;
  55. REC = 0x95;
  56. break;
  57. }
  58. case 1:
  59. {
  60. WEC = 0x98;
  61. REC = 0x97;
  62. break;
  63. }
  64. default:
  65. {
  66. WEC = EC_VERSION_WEC;
  67. REC = EC_VERSION_REC;
  68. break;
  69. }
  70. }
  71. if (wait_ibf() < 0)
  72. return -1;
  73. outb(REC, EC_CMD_PORT);
  74. if (wait_ibf() < 0)
  75. return -1;
  76. outb(offset, EC_DATA_PORT);
  77. if (wait_obf() < 0)
  78. return -1;
  79. *data = inb(EC_DATA_PORT);
  80. return 0;
  81. }
  82. /* ==================== mode ==================== */
  83. static ssize_t fw_version_show(struct kobject *kobj, struct kobj_attribute *attr,
  84. char *buf)
  85. {
  86. unsigned char data[4] = {0};
  87. int i = 0;
  88. for(i = 0; i < 4; i++)
  89. {
  90. oem_ec_read_ram(2, i, &data[i]);
  91. }
  92. // This needs to be completed here, obtain the real version number
  93. sprintf(buf, "%02x%02x%02x%02x", data[0], data[1], data[2], data[3]);
  94. return 8;
  95. }
  96. static ssize_t fw_version_store(struct kobject *kobj, struct kobj_attribute *attr,
  97. const char *buf, size_t count)
  98. {
  99. printk("fw_version_store kernel rev:%s\n", buf);
  100. return count;
  101. }
  102. static struct kobj_attribute ec_version_attr =
  103. __ATTR(fw_version, 0444, fw_version_show, fw_version_store);
  104. static struct attribute *ec_version_attrs[] = {
  105. &ec_version_attr.attr,
  106. NULL,
  107. };
  108. static struct attribute_group ec_version_attr_group = {
  109. .attrs = ec_version_attrs,
  110. };
  111. int ec_version_init(void)
  112. {
  113. int ret = 0;
  114. ret = sysfs_create_group(vfiec_kobj, &ec_version_attr_group);
  115. if (ret)
  116. {
  117. pr_err("Faiec_version to create sysfs group: %d\n", ret);
  118. }
  119. return ret;
  120. }
  121. void ec_version_exit(void)
  122. {
  123. sysfs_remove_group(vfiec_kobj, &ec_version_attr_group);
  124. }