123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- /*
- * Copyright (C) 2015 MediaTek Inc.
- * Copyright (C) 2021 XiaoMi, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include <linux/hqsysfs.h>
- #include "hqsys_misc.h"
- #include "hqsys_pcba.h"
- #define HQ_SYS_FS_VER "2016-03-11 V0.2"
- static HW_INFO(HWID_VER, ver);
- static HW_INFO(HWID_SUMMARY, hw_summary);
- static HW_INFO(HWID_DDR, ram);
- static HW_INFO(HWID_EMMC, emmc);
- static HW_INFO(HWID_LCM, lcm);
- //static HW_INFO(HWID_BIAS_IC,lcm_bias_ic);
- static HW_INFO(HWID_CTP, ctp);
- static HW_INFO(HWID_SUB_CAM, sub_cam); //sub
- static HW_INFO(HWID_SUB_CAM_2, main0_cam); //main0
- static HW_INFO(HWID_MAIN_CAM, main1_cam); //main1
- static HW_INFO(HWID_MAIN_CAM_2, main2_cam); //main2
- static HW_INFO(HWID_MAIN_CAM_3, main3_cam); //main3
- static HW_INFO(HWID_MAIN_LENS, main_cam_len);
- static HW_INFO(HWID_FLASHLIGHT, flashlight);
- static HW_INFO(HWID_GSENSOR, gsensor);
- static HW_INFO(HWID_ALSPS, alsps);
- static HW_INFO(HWID_MSENSOR, msensor);
- static HW_INFO(HWID_GYRO, gyro);
- static HW_INFO(HWID_IRDA, irda);
- static HW_INFO(HWID_FUEL_GAUGE_IC, fuel_gauge_ic);
- static HW_INFO(HWID_NFC, nfc);
- static HW_INFO(HWID_FP, fingerprint);
- //static HW_INFO(HWID_TEE,tee);
- static HW_INFO(HWID_PCBA, pcba_config);
- #if defined(TARGET_PRODUCT_LANCELOT) || defined(TARGET_PRODUCT_SHIVA)
- struct pcba_info pcba[] = {
- {PCBA_J19_P0_1_CN, "PCBA_J19_P0-1_CN"},
- {PCBA_J19_P0_1_INDIA, "PCBA_J19_P0-1_INDIA"},
- {PCBA_J19_P0_1_GLOBAL, "PCBA_J19_P0-1_GLOBAL"},
- {PCBA_J19_P1_CN, "PCBA_J19_P1_CN"},
- {PCBA_J19_P1_INDIA, "PCBA_J19_P1_INDIA"},
- {PCBA_J19_P1_GLOBAL, "PCBA_J19_P1_GLOBAL"},
- {PCBA_J19_P2_CN, "PCBA_J19_P2_CN"},
- {PCBA_J19_P2_INDIA, "PCBA_J19_P2_INDIA"},
- {PCBA_J19_P2_GLOBAL, "PCBA_J19_P2_GLOBAL"},
- {PCBA_J19_MP_CN, "PCBA_J19_MP_CN"},
- {PCBA_J19_MP_CN_SP01T, "PCBA_J19_MP_CN_SP01T"},
- {PCBA_J19_MP_INDIA, "PCBA_J19_MP_INDIA"},
- {PCBA_J19_MP_GLOBAL, "PCBA_J19_MP_GLOBAL"},
- {PCBA_J19A_P0_1_GLOBAL, "PCBA_J19A_P0-1_GLOBAL"},
- {PCBA_J19A_P1_GLOBAL, "PCBA_J19A_P1_GLOBAL"},
- {PCBA_J19A_P2_GLOBAL, "PCBA_J19A_P2_GLOBAL"},
- {PCBA_J19A_MP_GLOBAL, "PCBA_J19A_MP_GLOBAL"},
- {PCBA_J19P_P2_INDIA, "PCBA_J19P_P2_INDIA"},
- {PCBA_J19P_MP_INDIA, "PCBA_J19P_MP_INDIA"},
- {PCBA_J19P_POCO_MP_INDIA, "PCBA_J19P_POCO_MP_INDIA"},
- };
- #else
- struct pcba_info pcba[] = {
- {PCBA_UNKNOW, "PCBA_UNKNOW"},
- {PCBA_J15S_P0_CN, "PCBA_J15S_P0_CN"},
- {PCBA_J15S_P0_INDIA, "PCBA_J15S_P0_INDIA"},
- {PCBA_J15S_P0_GLOBAL, "PCBA_J15S_P0_GLOBAL"},
- {PCBA_J15S_P1_CN, "PCBA_J15S_P1_CN"},
- {PCBA_J15S_P1_INDIA, "PCBA_J15S_P1_INDIA"},
- {PCBA_J15S_P1_1_CN, "PCBA_J15S_P1-1_CN"},
- {PCBA_J15S_P1_1_INDIA, "PCBA_J15S_P1-1_INDIA"},
- {PCBA_J15N_P1_1_GLOBAL_NFC, "PCBA_J15N_P1-1_GLOBAL_NFC"},
- {PCBA_J15S_P2_CN, "PCBA_J15S_P2_CN"},
- {PCBA_J15S_P2_INDIA, "PCBA_J15S_P2_INDIA"},
- {PCBA_J15S_P2_GLOBAL, "PCBA_J15S_P2_GLOBAL"},
- {PCBA_J15N_P2_GLOBAL_NFC, "PCBA_J15N_P2_GLOBAL_NFC"},
- {PCBA_J15S_P2_1_GLOBAL, "PCBA_J15S_P2-1_GLOBAL"},
- {PCBA_J15N_P2_1_GLOBAL_NFC, "PCBA_J15N_P2-1_GLOBAL_NFC"},
- {PCBA_J15S_MP_CN, "PCBA_J15S_MP_CN"},
- {PCBA_J15S_MP_INDIA, "PCBA_J15S_MP_INDIA"},
- {PCBA_J15S_MP_GLOBAL, "PCBA_J15S_MP_GLOBAL"},
- {PCBA_J15N_MP_GLOBAL_NFC, "PCBA_J15N_MP_GLOBAL_NFC"},
- {PCBA_J15S_CN_NEW_PA, "PCBA_J15S_MP_CN_NEW_PA"},
- };
- #endif
- static struct attribute *huaqin_attrs[] = {
- &hw_info_ver.attr,
- &hw_info_hw_summary.attr,
- &hw_info_ram.attr,
- &hw_info_emmc.attr,
- &hw_info_lcm.attr,
- // &hw_info_lcm_bias_ic.attr,
- &hw_info_ctp.attr,
- &hw_info_sub_cam.attr,
- &hw_info_main0_cam.attr,
- &hw_info_main1_cam.attr,
- &hw_info_main2_cam.attr,
- &hw_info_main3_cam.attr,
- &hw_info_main_cam_len.attr,
- &hw_info_flashlight.attr,
- &hw_info_gsensor.attr,
- &hw_info_alsps.attr,
- &hw_info_msensor.attr,
- &hw_info_gyro.attr,
- &hw_info_irda.attr,
- &hw_info_fuel_gauge_ic.attr,
- &hw_info_nfc.attr,
- &hw_info_fingerprint.attr,
- &hw_info_pcba_config.attr,
- // &hw_info_tee.attr,
- NULL
- };
- static ssize_t huaqin_show(struct kobject *kobj, struct attribute *a, char *buf)
- {
- ssize_t count = 0;
- int i = 0;
- struct hw_info *hw = container_of(a, struct hw_info, attr);
- if (NULL == hw) {
- return sprintf(buf, "Data error\n");
- }
- if (HWID_VER == hw->hw_id) {
- count = sprintf(buf, "%s\n", HQ_SYS_FS_VER);
- } else if (HWID_SUMMARY == hw->hw_id) {
- //iterate all device and output the detail
- int iterator = 0;
- struct hw_info *curent_hw = NULL;
- struct attribute *attr = huaqin_attrs[iterator];
- while (attr) {
- curent_hw = container_of(attr, struct hw_info, attr);
- iterator += 1;
- attr = huaqin_attrs[iterator];
- if (curent_hw->hw_exist && (NULL != curent_hw->hw_device_name)) {
- count += sprintf(buf+count, "%s: %s\n", curent_hw->attr.name, curent_hw->hw_device_name);
- }
- }
- } else if (HWID_PCBA == hw->hw_id) {
- if (get_huaqin_pcba_config() >= PCBA_UNKNOW && get_huaqin_pcba_config() < PCBA_END) {
- huaqin_pcba_config = get_huaqin_pcba_config();
- } else {
- huaqin_pcba_config = PCBA_UNKNOW;
- }
- for (i = 0; i < sizeof(pcba)/sizeof(struct pcba_info); i++) {
- if (huaqin_pcba_config == pcba[i].pcba_config) {
- count = sprintf(buf, "%s\n", pcba[i].pcba_name);
- return count;
- }
- }
- count = sprintf(buf, "%s\n", "PCBA_UNKONW");
- } else{
- if (0 == hw->hw_exist) {
- count = sprintf(buf, "Not support\n");
- } else if (NULL == hw->hw_device_name) {
- count = sprintf(buf, "Installed with no device Name\n");
- } else {
- count = sprintf(buf, "%s\n", hw->hw_device_name);
- }
- }
- return count;
- }
- static ssize_t huaqin_store(struct kobject *kobj, struct attribute *a, const char *buf, size_t count)
- {
- return count;
- }
- /* huaqin object */
- static struct kobject huaqin_kobj;
- static const struct sysfs_ops huaqin_sysfs_ops = {
- .show = huaqin_show,
- .store = huaqin_store,
- };
- /* huaqin type */
- static struct kobj_type huaqin_ktype = {
- .sysfs_ops = &huaqin_sysfs_ops,
- .default_attrs = huaqin_attrs
- };
- /* huaqin device class */
- static struct class *huaqin_class;
- static struct device *huaqin_hw_device;
- int register_kboj_under_hqsysfs(struct kobject *kobj, struct kobj_type *ktype, const char *fmt, ...)
- {
- return kobject_init_and_add(kobj, ktype, &(huaqin_hw_device->kobj), fmt);
- }
- static int __init create_sysfs(void)
- {
- int ret;
- /* create class (device model) */
- huaqin_class = class_create(THIS_MODULE, HUAQIN_CLASS_NAME);
- if (IS_ERR(huaqin_class)) {
- pr_err("%s fail to create class\n", __func__);
- return -1;
- }
- huaqin_hw_device = device_create(huaqin_class, NULL, MKDEV(0, 0), NULL, HUAIN_INTERFACE_NAME);
- if (IS_ERR(huaqin_hw_device)) {
- pr_warn("fail to create device\n");
- return -1;
- }
- /* add kobject */
- ret = kobject_init_and_add(&huaqin_kobj, &huaqin_ktype, &(huaqin_hw_device->kobj), HUAQIN_HWID_NAME);
- if (ret < 0) {
- pr_err("%s fail to add kobject\n", __func__);
- return ret;
- }
- return 0;
- }
- int hq_deregister_hw_info(enum hardware_id id, char *device_name)
- {
- int ret = 0;
- int find_hw_id = 0;
- int iterator = 0;
- struct hw_info *hw = NULL;
- struct attribute *attr = huaqin_attrs[iterator];
- if (NULL == device_name) {
- pr_err("[%s]: device_name does not allow empty\n", __func__);
- ret = -2;
- goto err;
- }
- while (attr) {
- hw = container_of(attr, struct hw_info, attr);
- iterator += 1;
- attr = huaqin_attrs[iterator];
- if (NULL == hw) {
- continue;
- }
- if (id == hw->hw_id) {
- find_hw_id = 1;
- if (0 == hw->hw_exist) {
- pr_err("[%s]: device has not registed hw->id:0x%x . Cant be deregistered\n"
- , __func__
- , hw->hw_id);
- ret = -4;
- goto err;
- } else if (NULL == hw->hw_device_name) {
- pr_err("[%s]:hw_id is 0x%x Device name cant be NULL\n"
- , __func__
- , hw->hw_id);
- ret = -5;
- goto err;
- } else {
- if (0 == strncmp(hw->hw_device_name, device_name, strlen(hw->hw_device_name))) {
- hw->hw_device_name = NULL;
- hw->hw_exist = 0;
- } else{
- pr_err("[%s]: hw_id is 0x%x Registered device name %s, want to deregister: %s\n"
- , __func__
- , hw->hw_id
- , hw->hw_device_name
- , device_name);
- ret = -6;
- goto err;
- }
- }
- goto err;
- } else
- continue;
- }
- if (0 == find_hw_id) {
- pr_err("[%s]: Cant find correct hardware_id: 0x%x\n", __func__, id);
- ret = -3;
- }
- err:
- return ret;
- }
- int hq_regiser_hw_info(enum hardware_id id, char *device_name)
- {
- int ret = 0;
- int find_hw_id = 0;
- int iterator = 0;
- struct hw_info *hw = NULL;
- struct attribute *attr = huaqin_attrs[iterator];
- if (NULL == device_name) {
- pr_err("[%s]: device_name does not allow empty\n", __func__);
- ret = -2;
- goto err;
- }
- while (attr) {
- hw = container_of(attr, struct hw_info, attr);
- iterator += 1;
- attr = huaqin_attrs[iterator];
- if (NULL == hw) {
- continue;
- }
- if (id == hw->hw_id) {
- find_hw_id = 1;
- if (hw->hw_exist) {
- pr_err("[%s]: device has already registed hw->id:0x%x hw_device_name:%s\n"
- , __func__
- , hw->hw_id
- , hw->hw_device_name);
- ret = -4;
- goto err;
- }
- switch (hw->hw_id) {
- /*
- if(map_cam_drv_to_vendor(device_name))
- hw->hw_device_name = map_cam_drv_to_vendor(device_name);
- else
- hw->hw_device_name = "Can't find Camera Vendor";
- break;
- */
- default:
- hw->hw_device_name = device_name;
- break;
- }
- hw->hw_exist = 1;
- goto err;
- } else
- continue;
- }
- if (0 == find_hw_id) {
- pr_err("[%s]: Cant find correct hardware_id: 0x%x\n", __func__, id);
- ret = -3;
- }
- err:
- return ret;
- }
- #include <linux/proc_fs.h>
- #include <linux/of_gpio.h>
- #include <linux/gpio.h>
- #define PROC_BOOT_REASON_FILE "boot_status"
- #define SDC_DETECT_STATUS "sdc_det_gpio_status"
- #define SDC_DETECT_GPIO 343
- static struct proc_dir_entry *boot_reason_proc;
- static struct proc_dir_entry *sdc_detect_status;
- static unsigned int boot_into_factory;
- static int boot_reason_proc_show(struct seq_file *file, void *data)
- {
- char temp[40] = {0};
- sprintf(temp, "%d\n", boot_into_factory);
- seq_printf(file, "%s\n", temp);
- return 0;
- }
- static int boot_reason_proc_open (struct inode *inode, struct file *file)
- {
- return single_open(file, boot_reason_proc_show, inode->i_private);
- }
- static const struct file_operations boot_reason_proc_fops = {
- .open = boot_reason_proc_open,
- .read = seq_read,
- };
- static int __init get_boot_rease(char *str)
- {
- if (strcmp("boot_with_factory", str) == 0) {
- boot_into_factory = 1;
- }
- return 0;
- }
- __setup("androidboot.boot_reason=", get_boot_rease);
- static int sdc_detect_proc_show(struct seq_file *file, void *data)
- {
- int gpio_value = -1;
- gpio_value = gpio_get_value(SDC_DETECT_GPIO);
- seq_printf(file, "%d\n", gpio_value ? 1 : 0);
- return 0;
- }
- static int sdc_detect_proc_open (struct inode *inode, struct file *file)
- {
- return single_open(file, sdc_detect_proc_show, inode->i_private);
- }
- static const struct file_operations sdc_detect_proc_fops = {
- .open = sdc_detect_proc_open,
- .read = seq_read,
- };
- static int sdc_detect_init(void)
- {
- int ret = -1;
- sdc_detect_status = proc_create(SDC_DETECT_STATUS, 0644, NULL, &sdc_detect_proc_fops);
- if (sdc_detect_status == NULL) {
- pr_err("[%s]: create_proc_entry sdc_detect_status failed\n", __func__);
- return -1;
- }
- return 0;
- }
- static int __init hq_harware_init(void)
- {
- /* create sysfs entry at /sys/class/huaqin/interface/hw_info */
- create_sysfs();
- boot_reason_proc = proc_create(PROC_BOOT_REASON_FILE, 0644, NULL, &boot_reason_proc_fops);
- if (boot_reason_proc == NULL) {
- pr_err("[%s]: create_proc_entry boot_reason_proc failed\n", __func__);
- }
- if (sdc_detect_init() < 0)
- pr_err("[%s]: create_proc_entry sdc_detect_proc failed\n", __func__);
- return 0;
- }
- core_initcall(hq_harware_init);
- MODULE_AUTHOR("KaKa Ni <nigang@huaqin.com>");
- MODULE_DESCRIPTION("Huaqin Hardware Info Driver");
- MODULE_LICENSE("GPL");
|