mt_chip_common.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #define pr_fmt(fmt) "["KBUILD_MODNAME"] " fmt
  2. #include <linux/module.h>
  3. #include <linux/device.h>
  4. #include <linux/fs.h>
  5. #include <linux/cdev.h>
  6. #include <linux/interrupt.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/mm.h>
  10. #include <linux/kfifo.h>
  11. #include <linux/firmware.h>
  12. #include <linux/syscalls.h>
  13. #include <linux/uaccess.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/proc_fs.h>
  16. #include <linux/of.h>
  17. #include <linux/of_address.h>
  18. #include <linux/printk.h>
  19. #include <asm/setup.h>
  20. #include "mt_chip_common.h"
  21. struct mt_chip_drv g_chip_drv = {
  22. .info_bit_mask = CHIP_INFO_BIT(CHIP_INFO_ALL)
  23. };
  24. struct mt_chip_drv *get_mt_chip_drv(void)
  25. {
  26. return &g_chip_drv;
  27. }
  28. struct chip_inf_entry {
  29. const char *name;
  30. unsigned int id;
  31. int (*to_str)(char *buf, size_t len, int val);
  32. };
  33. static int hex2str(char *buf, size_t len, int val)
  34. {
  35. return snprintf(buf, len, "%04X", val);
  36. }
  37. static int dec2str(char *buf, size_t len, int val)
  38. {
  39. return snprintf(buf, len, "%04d", val);
  40. }
  41. static int date2str(char *buf, size_t len, int val)
  42. {
  43. unsigned int year = ((val & 0x3C0) >> 6) + 2012;
  44. unsigned int week = (val & 0x03F);
  45. return snprintf(buf, len, "%04d%02d", year, week);
  46. }
  47. #define __chip_info(id) ((g_chip_drv.get_chip_info) ? (g_chip_drv.get_chip_info(id)) : (0x0000))
  48. static struct proc_dir_entry *chip_proc;
  49. static struct chip_inf_entry chip_ent[] = {
  50. {"hw_code", CHIP_INFO_HW_CODE, hex2str},
  51. {"hw_subcode", CHIP_INFO_HW_SUBCODE, hex2str},
  52. {"hw_ver", CHIP_INFO_HW_VER, hex2str},
  53. {"sw_ver", CHIP_INFO_SW_VER, hex2str},
  54. {"code_func", CHIP_INFO_FUNCTION_CODE, hex2str},
  55. {"code_date", CHIP_INFO_DATE_CODE, date2str},
  56. {"code_proj", CHIP_INFO_PROJECT_CODE, dec2str},
  57. {"code_fab", CHIP_INFO_FAB_CODE, hex2str},
  58. {"wafer_big_ver", CHIP_INFO_WAFER_BIG_VER, hex2str},
  59. {"info", CHIP_INFO_ALL, NULL}
  60. };
  61. static int chip_proc_show(struct seq_file *s, void *v)
  62. {
  63. struct chip_inf_entry *ent = s->private;
  64. if ((ent->id > CHIP_INFO_NONE) && (ent->id < CHIP_INFO_MAX)) {
  65. seq_printf(s, "%04X\n", __chip_info(ent->id));
  66. } else {
  67. int idx = 0;
  68. char buf[16];
  69. for (idx = 0; idx < ARRAY_SIZE(chip_ent); idx++) {
  70. struct chip_inf_entry *ent = &chip_ent[idx];
  71. unsigned int val = __chip_info(ent->id);
  72. if (!CHIP_INFO_SUP(g_chip_drv.info_bit_mask, ent->id))
  73. continue;
  74. else if (!ent->to_str)
  75. continue;
  76. else if (0 < ent->to_str(buf, sizeof(buf), val))
  77. seq_printf(s, "%-16s : %s (%04x)\n", ent->name, buf, val);
  78. else
  79. seq_printf(s, "%-16s : %s (%04x)\n", ent->name, "NULL", val);
  80. }
  81. seq_printf(s, "%-16s : %04X %04X %04X %04X\n", "reg",
  82. __chip_info(CHIP_INFO_REG_HW_CODE),
  83. __chip_info(CHIP_INFO_REG_HW_SUBCODE),
  84. __chip_info(CHIP_INFO_REG_HW_VER), __chip_info(CHIP_INFO_REG_SW_VER));
  85. }
  86. return 0;
  87. }
  88. static int chip_proc_open(struct inode *inode, struct file *file)
  89. {
  90. return single_open(file, chip_proc_show, PDE_DATA(file_inode(file)));
  91. }
  92. static const struct file_operations chip_proc_fops = {
  93. .open = chip_proc_open,
  94. .read = seq_read,
  95. .llseek = seq_lseek,
  96. .release = single_release,
  97. };
  98. static void __init create_procfs(void)
  99. {
  100. int idx;
  101. chip_proc = proc_mkdir_data("chip", 0, NULL, NULL);
  102. if (NULL == chip_proc) {
  103. pr_err("create /proc/chip fails\n");
  104. return;
  105. }
  106. pr_debug("create /proc/chip(%x)\n", g_chip_drv.info_bit_mask);
  107. for (idx = 0; idx < ARRAY_SIZE(chip_ent); idx++) {
  108. struct chip_inf_entry *ent = &chip_ent[idx];
  109. if (!CHIP_INFO_SUP(g_chip_drv.info_bit_mask, ent->id))
  110. continue;
  111. if (NULL == proc_create_data(ent->name, S_IRUGO, chip_proc, &chip_proc_fops, ent)) {
  112. pr_err("create /proc/chip/%s fail\n", ent->name);
  113. return;
  114. }
  115. }
  116. }
  117. int __init chip_common_init(void)
  118. {
  119. create_procfs();
  120. return 0;
  121. }
  122. arch_initcall(chip_common_init);
  123. MODULE_DESCRIPTION("MTK Chip Common");
  124. MODULE_LICENSE("GPL");