aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/chip
diff options
context:
space:
mode:
authorMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
committerMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
commitd2e1446d81725c351dc73a03b397ce043fb18452 (patch)
tree4dbc616b7f92aea39cd697a9084205ddb805e344 /drivers/misc/mediatek/chip
first commit
Diffstat (limited to 'drivers/misc/mediatek/chip')
-rwxr-xr-xdrivers/misc/mediatek/chip/Makefile13
-rwxr-xr-xdrivers/misc/mediatek/chip/mt6735/Makefile4
-rw-r--r--drivers/misc/mediatek/chip/mt6735/mt_chip.c208
-rw-r--r--drivers/misc/mediatek/chip/mt_chip_common.c152
4 files changed, 377 insertions, 0 deletions
diff --git a/drivers/misc/mediatek/chip/Makefile b/drivers/misc/mediatek/chip/Makefile
new file mode 100755
index 000000000..660cb725d
--- /dev/null
+++ b/drivers/misc/mediatek/chip/Makefile
@@ -0,0 +1,13 @@
+include $(srctree)/drivers/misc/mediatek/Makefile.custom
+
+obj-y += CHIP_COMMON.o
+CHIP_COMMON-y := mt_chip_common.o
+
+#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT6752) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT6595) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT6795) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT6735) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT6735M) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT6753) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
+obj-$(CONFIG_ARCH_MT8163) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
diff --git a/drivers/misc/mediatek/chip/mt6735/Makefile b/drivers/misc/mediatek/chip/mt6735/Makefile
new file mode 100755
index 000000000..409278e5d
--- /dev/null
+++ b/drivers/misc/mediatek/chip/mt6735/Makefile
@@ -0,0 +1,4 @@
+include $(srctree)/drivers/misc/mediatek/Makefile.custom
+
+obj-y += CHIP.o
+CHIP-y := mt_chip.o
diff --git a/drivers/misc/mediatek/chip/mt6735/mt_chip.c b/drivers/misc/mediatek/chip/mt6735/mt_chip.c
new file mode 100644
index 000000000..a9471b4b9
--- /dev/null
+++ b/drivers/misc/mediatek/chip/mt6735/mt_chip.c
@@ -0,0 +1,208 @@
+#define pr_fmt(fmt) "["KBUILD_MODNAME"] " fmt
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/mm.h>
+#include <linux/kfifo.h>
+
+#include <linux/firmware.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/printk.h>
+
+#include <mach/mt_chip.h>
+#include <mach/mt_typedefs.h>
+#include <asm/setup.h>
+//#include "devinfo.h"
+extern u32 get_devinfo_with_index(u32 index);
+
+void __iomem *APHW_CODE = NULL;
+void __iomem *APHW_SUBCODE = NULL;
+void __iomem *APHW_VER = NULL;
+void __iomem *APSW_VER = NULL;
+
+typedef enum {
+ CID_UNINIT = 0,
+ CID_INITIALIZING = 1,
+ CID_INITIALIZED = 2,
+} CID_INIT_STATE;
+
+static atomic_t g_cid_init = ATOMIC_INIT(CID_UNINIT);
+
+static void init_chip_id(unsigned int line)
+{
+ if (CID_INITIALIZED == atomic_read(&g_cid_init))
+ return;
+
+ if (CID_INITIALIZING == atomic_read(&g_cid_init)) {
+ pr_warn("%s (%d) state(%d)\n", __func__, line, atomic_read(&g_cid_init));
+ return;
+ }
+
+ atomic_set(&g_cid_init, CID_INITIALIZING);
+#ifdef CONFIG_OF
+ {
+ struct device_node *node = of_find_compatible_node(NULL, NULL, "mediatek,CHIPID");
+ if (node) {
+ APHW_CODE = of_iomap(node,0);
+ WARN(!APHW_CODE, "unable to map APHW_CODE registers\n");
+ APHW_SUBCODE = of_iomap(node,1);
+ WARN(!APHW_SUBCODE, "unable to map APHW_SUBCODE registers\n");
+ APHW_VER = of_iomap(node,2);
+ WARN(!APHW_VER, "unable to map APHW_VER registers\n");
+ APSW_VER = of_iomap(node,3);
+ WARN(!APSW_VER, "unable to map APSW_VER registers\n");
+ atomic_set(&g_cid_init, CID_INITIALIZED);
+ } else {
+ atomic_set(&g_cid_init, CID_UNINIT);
+ pr_warn("node not found\n");
+ }
+ }
+#endif
+ pr_alert("0x%04X 0x%04X 0x%04X 0x%04X (%04d)\n",
+ readl(IOMEM(APHW_CODE)),readl(IOMEM(APHW_VER)),
+ readl(IOMEM(APSW_VER)),readl(IOMEM(APHW_SUBCODE)), line);
+}
+
+/* return hardware version */
+unsigned int __chip_hw_code(void)
+{
+ init_chip_id(__LINE__);
+ return (APHW_CODE) ? readl(IOMEM(APHW_CODE)) : (C_UNKNOWN_CHIP_ID);
+}
+
+unsigned int __chip_hw_ver(void)
+{
+ init_chip_id(__LINE__);
+ return (APHW_VER) ? readl(IOMEM(APHW_VER)) : (C_UNKNOWN_CHIP_ID);
+}
+
+unsigned int __chip_sw_ver(void)
+{
+ init_chip_id(__LINE__);
+ return (APSW_VER) ? readl(IOMEM(APSW_VER)) : (C_UNKNOWN_CHIP_ID);
+}
+
+unsigned int __chip_hw_subcode(void)
+{
+ init_chip_id(__LINE__);
+ return (APHW_SUBCODE) ? readl(IOMEM(APHW_SUBCODE)) : (C_UNKNOWN_CHIP_ID);
+}
+
+unsigned int __chip_func_code(void)
+{
+ unsigned int val = get_devinfo_with_index(47) & 0xFE000000; // [31:25]
+ return (val >> 25);
+}
+
+unsigned int __chip_date_code(void)
+{
+ return 0; //not support
+}
+
+unsigned int __chip_proj_code(void)
+{
+ return 0; //not support
+}
+
+unsigned int __chip_fab_code(void)
+{
+ return 0; //not support
+}
+
+unsigned int mt_get_chip_id(void)
+{
+ unsigned int chip_id = __chip_hw_code();
+ /*convert id if necessary*/
+ return chip_id;
+}
+
+unsigned int mt_get_chip_hw_code(void)
+{
+ return __chip_hw_code();
+}
+
+unsigned int mt_get_chip_hw_ver(void)
+{
+ return __chip_hw_ver();
+}
+
+unsigned int mt_get_chip_hw_subcode(void)
+{
+ return __chip_hw_subcode();
+}
+
+chip_sw_ver_t mt_get_chip_sw_ver(void)
+{
+ return (chip_sw_ver_t)__chip_sw_ver();
+}
+
+static chip_info_cb g_cbs[CHIP_INFO_MAX] =
+{
+ NULL,
+ mt_get_chip_hw_code,
+ mt_get_chip_hw_subcode,
+ mt_get_chip_hw_ver,
+ (chip_info_cb)mt_get_chip_sw_ver,
+
+ __chip_hw_code,
+ __chip_hw_subcode,
+ __chip_hw_ver,
+ __chip_sw_ver,
+
+ __chip_func_code,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+unsigned int mt_get_chip_info(chip_info_t id)
+{
+ if ((id <= CHIP_INFO_NONE) || (id >= CHIP_INFO_MAX))
+ return 0;
+ else if (NULL == g_cbs[id])
+ return 0;
+ return g_cbs[id]();
+}
+
+
+int __init chip_mod_init(void)
+{
+ struct mt_chip_drv* p_drv = get_mt_chip_drv();
+
+ pr_alert("CODE = %04x %04x %04x %04x, %04x %04x %04x %04x, %04X %04X\n",
+ __chip_hw_code(), __chip_hw_subcode(), __chip_hw_ver(),
+ __chip_sw_ver(), __chip_func_code(), __chip_proj_code(),
+ __chip_date_code(), __chip_fab_code(),
+ mt_get_chip_hw_ver(), mt_get_chip_sw_ver());
+
+ p_drv->info_bit_mask |= CHIP_INFO_BIT(CHIP_INFO_HW_CODE) |
+ CHIP_INFO_BIT(CHIP_INFO_HW_SUBCODE) |
+ CHIP_INFO_BIT(CHIP_INFO_HW_VER) |
+ CHIP_INFO_BIT(CHIP_INFO_SW_VER) |
+ CHIP_INFO_BIT(CHIP_INFO_FUNCTION_CODE);
+
+ p_drv->get_chip_info = mt_get_chip_info;
+
+ pr_alert("CODE = %08X %p", p_drv->info_bit_mask, p_drv->get_chip_info);
+
+ return 0;
+}
+
+core_initcall(chip_mod_init);
+MODULE_DESCRIPTION("MTK Chip Information");
+MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(mt_get_chip_id);
+EXPORT_SYMBOL(mt_get_chip_hw_code);
+EXPORT_SYMBOL(mt_get_chip_sw_ver);
+EXPORT_SYMBOL(mt_get_chip_info);
+
diff --git a/drivers/misc/mediatek/chip/mt_chip_common.c b/drivers/misc/mediatek/chip/mt_chip_common.c
new file mode 100644
index 000000000..eeb09576a
--- /dev/null
+++ b/drivers/misc/mediatek/chip/mt_chip_common.c
@@ -0,0 +1,152 @@
+#define pr_fmt(fmt) "["KBUILD_MODNAME"] " fmt
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/mm.h>
+#include <linux/kfifo.h>
+
+#include <linux/firmware.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/printk.h>
+
+#include <mach/mt_reg_base.h>
+#include <mach/mt_typedefs.h>
+#include <asm/setup.h>
+#include <mach/mt_chip_common.h>
+
+struct mt_chip_drv g_chip_drv = {
+ .info_bit_mask = CHIP_INFO_BIT(CHIP_INFO_ALL)
+};
+
+struct mt_chip_drv* get_mt_chip_drv(void)
+{
+ return &g_chip_drv;
+}
+
+struct chip_inf_entry
+{
+ const char* name;
+ chip_info_t id;
+ int (*to_str)(char* buf, size_t len, int val);
+};
+
+static int hex2str(char* buf, size_t len, int val)
+{
+ return snprintf(buf, len, "%04X", val);
+}
+
+static int dec2str(char* buf, size_t len, int val)
+{
+ return snprintf(buf, len, "%04d", val);
+}
+
+static int date2str(char* buf, size_t len, int val)
+{
+ unsigned int year = ((val & 0x3C0) >> 6) + 2012;
+ unsigned int week = (val & 0x03F);
+ return snprintf(buf, len, "%04d%02d", year, week);
+}
+
+#define __chip_info(id) ((g_chip_drv.get_chip_info) ? (g_chip_drv.get_chip_info(id)) : (0x0000))
+
+static struct proc_dir_entry *chip_proc = NULL;
+static struct chip_inf_entry chip_ent[] =
+{
+ {"hw_code", CHIP_INFO_HW_CODE, hex2str},
+ {"hw_subcode", CHIP_INFO_HW_SUBCODE, hex2str},
+ {"hw_ver", CHIP_INFO_HW_VER, hex2str},
+ {"sw_ver", CHIP_INFO_SW_VER, hex2str},
+ {"code_func", CHIP_INFO_FUNCTION_CODE,hex2str},
+ {"code_date", CHIP_INFO_DATE_CODE, date2str},
+ {"code_proj", CHIP_INFO_PROJECT_CODE, dec2str},
+ {"code_fab", CHIP_INFO_FAB_CODE, hex2str},
+ {"wafer_big_ver", CHIP_INFO_WAFER_BIG_VER, hex2str},
+ {"info", CHIP_INFO_ALL, NULL}
+};
+
+static int chip_proc_show(struct seq_file* s, void* v)
+{
+ struct chip_inf_entry *ent = s->private;
+ if ((ent->id > CHIP_INFO_NONE) && (ent->id < CHIP_INFO_MAX)) {
+ seq_printf(s, "%04X\n", __chip_info(ent->id));
+ } else {
+ int idx = 0;
+ char buf[16];
+
+ for (idx = 0; idx < sizeof(chip_ent)/sizeof(chip_ent[0]); idx++) {
+ struct chip_inf_entry *ent = &chip_ent[idx];
+ unsigned int val = __chip_info(ent->id);
+
+ if (!CHIP_INFO_SUP(g_chip_drv.info_bit_mask, ent->id))
+ continue;
+ else if (!ent->to_str)
+ continue;
+ else if (0 < ent->to_str(buf, sizeof(buf), val))
+ seq_printf(s, "%-16s : %s (%04x)\n", ent->name, buf, val);
+ else
+ seq_printf(s, "%-16s : %s (%04x)\n", ent->name, "NULL", val);
+ }
+ seq_printf(s, "%-16s : %04X %04X %04X %04X\n", "reg",
+ __chip_info(CHIP_INFO_REG_HW_CODE),
+ __chip_info(CHIP_INFO_REG_HW_SUBCODE),
+ __chip_info(CHIP_INFO_REG_HW_VER),
+ __chip_info(CHIP_INFO_REG_SW_VER));
+ }
+ return 0;
+}
+
+static int chip_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, chip_proc_show, PDE_DATA(file_inode(file)));
+}
+
+static const struct file_operations chip_proc_fops = {
+ .open = chip_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+extern struct proc_dir_entry proc_root;
+static void __init create_procfs(void)
+{
+ int idx;
+
+ chip_proc = proc_mkdir_data("chip", 0, &proc_root, NULL);
+ if (NULL == chip_proc) {
+ pr_err("create /proc/chip fails\n");
+ return;
+ } else {
+ pr_alert("create /proc/chip(%x)\n", g_chip_drv.info_bit_mask);
+ }
+
+ for (idx = 0; idx < sizeof(chip_ent)/sizeof(chip_ent[0]); idx++) {
+ struct chip_inf_entry *ent = &chip_ent[idx];
+ if (!CHIP_INFO_SUP(g_chip_drv.info_bit_mask, ent->id))
+ continue;
+ if (NULL == proc_create_data(ent->name, S_IRUGO, chip_proc, &chip_proc_fops, ent)) {
+ pr_err("create /proc/chip/%s fail\n", ent->name);
+ return;
+ }
+ }
+}
+
+int __init chip_common_init(void)
+{
+ create_procfs();
+ return 0;
+}
+
+arch_initcall(chip_common_init);
+MODULE_DESCRIPTION("MTK Chip Common");
+MODULE_LICENSE("GPL");
+