diff options
| author | Meizu OpenSource <patchwork@meizu.com> | 2016-08-15 10:19:42 +0800 |
|---|---|---|
| committer | Meizu OpenSource <patchwork@meizu.com> | 2016-08-15 10:19:42 +0800 |
| commit | d2e1446d81725c351dc73a03b397ce043fb18452 (patch) | |
| tree | 4dbc616b7f92aea39cd697a9084205ddb805e344 /drivers/misc/mediatek/chip | |
first commit
Diffstat (limited to 'drivers/misc/mediatek/chip')
| -rwxr-xr-x | drivers/misc/mediatek/chip/Makefile | 13 | ||||
| -rwxr-xr-x | drivers/misc/mediatek/chip/mt6735/Makefile | 4 | ||||
| -rw-r--r-- | drivers/misc/mediatek/chip/mt6735/mt_chip.c | 208 | ||||
| -rw-r--r-- | drivers/misc/mediatek/chip/mt_chip_common.c | 152 |
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"); + |
