#include #include #include #include #include #include #include #include #include #include #include #include #include "up_devices.h" #include "Cust_Memory_type.h" #include #ifdef __CUST_URXDO_GPIO_SELECT__ #if __CUST_URXDO_GPIO_SELECT__ #include #define URXDO_SELECT_GPIO_NAME "urxdo_gpio_select" static int up_urxdo_select_gpio_num; int up_urxdo_flag = 0; int get_urxdo_select_gpio(void); static int up_parse_urxdo_dts(struct device_node *node, const char *gpio_name); #endif #endif #define UP_DEVICE "up_device" #define UP_VERSION "ALPS_S0MP1.RC" typedef int (*up_dev_print)(struct seq_file *se_f); typedef int (*up_dev_set_used)(char * module_name, int pdata); struct up_lcm_device_info { struct list_head up_list; // list in up_devices_info char lcm_module_descrip[50]; struct list_head lcm_list; // list in up_lcm_info LCM_DRIVER* pdata; compatible_type type; }; struct up_camera_device_dinfo { struct list_head up_list; char camera_module_descrip[48]; struct list_head camera_list; int camera_id; struct ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT* pdata; compatible_type type; enum CAMERA_DUAL_CAMERA_SENSOR_ENUM cam_type; }; struct up_accsensor_device_dinfo { struct list_head up_list; char sensor_descrip[20]; struct list_head sensor_list; int dev_addr; int ps_direction; // ps is throthold, als/msensor is diriction compatible_type type; struct acc_init_info * pdata; }; //MSENSOR struct up_msensor_device_dinfo { struct list_head up_list; char sensor_descrip[20]; struct list_head sensor_list; int dev_addr; int ps_direction; // ps is throthold, als/msensor is diriction compatible_type type; struct mag_init_info * pdata; }; //ALSPSSENSOR struct up_alspssensor_device_dinfo { struct list_head up_list; char sensor_descrip[20]; struct list_head sensor_list; int dev_addr; int ps_direction; // ps is throthold, als/alspssensor is diriction compatible_type type; struct alsps_init_info * pdata; }; struct up_touchpanel_device_dinfo { struct list_head up_list; // list in up_devices_info char touch_descrip[20]; struct list_head touch_list; int dev_addr; struct i2c_driver * pdata; // int ps_direction; // ps is throthold, als/msensor is diriction compatible_type type; }; struct up_type_info { struct list_head up_device; // list in up_devices_info struct list_head up_dinfo; // list in up_touch_device_dinfo up_dev_print type_print; up_dev_set_used set_used; int dev_type; void * current_used_dinfo; struct mutex info_mutex; }; struct list_head updisp_info_list; struct up_mis_disp_info { struct list_head mis_info_list; // list in up_devices_info void * current_used_dinfo; }; struct up_devices_info { struct list_head type_list; // up_type_info list struct list_head dev_list; // all_list struct mutex de_mutex; }; #ifdef __CUST_URXDO_GPIO_SELECT__ #if __CUST_URXDO_GPIO_SELECT__ static int up_parse_urxdo_dts(struct device_node *node, const char *gpio_name) { int gpio_num = 0; struct gpio_desc *desc; int ret = 0; if (node) { gpio_num = of_get_named_gpio(node, gpio_name, 0); if (gpio_num < 0) { printk("%s: of_get_named_gpio fail. \n", __func__); return -1; } else { printk("%s: of_get_named_gpio GPIO is %d.\n", __func__, gpio_num); desc = gpio_to_desc(gpio_num); if (!desc) { printk("%s: gpio_desc is null.\n", __func__); return -1; } else printk("%s: gpio_desc is not null.\n", __func__); if (gpio_is_valid(gpio_num)) printk("%s: gpio number %d is valid. \n", __func__ ,gpio_num); ret = gpio_request(gpio_num, gpio_name); if (ret) { printk("%s: gpio_request fail. \n", __func__); return -1; } else { ret = gpio_direction_input(gpio_num); if (ret) { printk("%s: gpio_direction_output failed. \n", __func__); return -1; } if(gpio_get_value(gpio_num)) { up_urxdo_flag = 0; printk("urxdo_1 %s: urxdo_gpio is <%d> status is <%d> flag = %d!\n", __func__,gpio_num,gpio_get_value(gpio_num),up_urxdo_flag); } else { up_urxdo_flag = 1; printk("urxdo_2 %s: urxdo_gpio is <%d> status is <%d> flag = %d!\n", __func__,gpio_num,gpio_get_value(gpio_num),up_urxdo_flag); } return gpio_num; } } } else { printk("%s: get gpio num fail. \n", __func__); return -1; } } int get_urxdo_select_gpio(void) { struct device_node *node; printk("%s: enter. \n", __func__); node = of_find_compatible_node(NULL, NULL, "mediatek,up_devices"); if (node) { up_urxdo_select_gpio_num = up_parse_urxdo_dts(node, URXDO_SELECT_GPIO_NAME); if (0 > up_urxdo_select_gpio_num) { printk("%s: up_parse_dts fail. \n", __func__); return -1; } } else { printk("%s: cannot get the node: 'mediatek,up_devices'.\n", __func__); return -ENODEV; } printk("%s: end. \n", __func__); return 0; } #endif #endif//URXDO struct up_devices_info * up_devices; static int up_camera_info_print(struct seq_file *se_f); static int up_touchpanel_info_print(struct seq_file *se_f); static int up_accsensor_info_print(struct seq_file *se_f); static int up_msensor_info_print(struct seq_file *se_f); static int up_alspssensor_info_print(struct seq_file *se_f); static int up_lcm_set_used(char * module_name,int pdata); static int up_camera_set_used(char * module_name, int pdata); static int up_touchpanel_set_used(char * module_name, int pdata); static int up_accsensor_set_used(char * module_name, int pdata); static int up_msensor_set_used(char * module_name, int pdata); static int up_alspssensor_set_used(char * module_name, int pdata); static int up_lcm_info_print(struct seq_file *se_f) { struct up_type_info * lcm_type_info; struct up_lcm_device_info * plcm_device; int flag = -1; seq_printf(se_f, "---------UP LCM USAGE--------\t \n"); list_for_each_entry(lcm_type_info,&up_devices->type_list,up_device){ if(lcm_type_info->dev_type == ID_LCM_TYPE) { flag =1; // this mean type is ok break; } } if(flag == 1) { list_for_each_entry(plcm_device,&lcm_type_info->up_dinfo,lcm_list){ seq_printf(se_f, " %s\t: ",plcm_device->lcm_module_descrip); if(plcm_device->type == DEVICE_SUPPORTED) seq_printf(se_f, " supported \n"); else seq_printf(se_f, " used \n"); } } else { seq_printf(se_f, " \t: NONE \n"); } return 0; } static void init_device_type_info(struct up_type_info * pdevice, void *used_info, int type) { memset(pdevice,0, sizeof(struct up_type_info)); INIT_LIST_HEAD(&pdevice->up_device); INIT_LIST_HEAD(&pdevice->up_dinfo); pdevice ->dev_type = type; if(used_info) pdevice->current_used_dinfo=used_info; if(type == ID_LCM_TYPE) { pdevice->type_print = up_lcm_info_print; pdevice->set_used= up_lcm_set_used; } else if(type == ID_CAMERA_TYPE) { pdevice->type_print = up_camera_info_print; pdevice->set_used = up_camera_set_used; } else if(type == ID_TOUCH_TYPE) { pdevice->type_print = up_touchpanel_info_print; pdevice->set_used = up_touchpanel_set_used; } else if(type == ID_ACCSENSOR_TYPE) { pdevice->type_print = up_accsensor_info_print; pdevice->set_used = up_accsensor_set_used; } else if(type == ID_MSENSOR_TYPE) { pdevice->type_print = up_msensor_info_print; pdevice->set_used = up_msensor_set_used; } else if(type == ID_ALSPSSENSOR_TYPE) { pdevice->type_print = up_alspssensor_info_print; pdevice->set_used = up_alspssensor_set_used; } mutex_init(&pdevice->info_mutex); list_add(&pdevice->up_device,&up_devices->type_list); } static void init_lcm_device(struct up_lcm_device_info *pdevice, LCM_DRIVER* nLcm) { memset(pdevice,0, sizeof(struct up_lcm_device_info)); INIT_LIST_HEAD(&pdevice->up_list); INIT_LIST_HEAD(&pdevice->lcm_list); strcpy(pdevice->lcm_module_descrip,nLcm->name); pdevice->pdata=nLcm; } int up_lcm_set_used(char * module_name, int pdata) { struct up_type_info * lcm_type_info; struct up_lcm_device_info * plcm_device; int flag = -1; int reterror=0; list_for_each_entry(lcm_type_info,&up_devices->type_list,up_device){ if(lcm_type_info->dev_type == ID_LCM_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { reterror = -1; goto error_notype; } flag =-1; list_for_each_entry(plcm_device,&lcm_type_info->up_dinfo,lcm_list){ if(!strcmp(module_name,plcm_device->lcm_module_descrip)) { plcm_device->type = DEVICE_USED; flag =1; // this mean device is ok break; } } if(flag == 1) return 0; error_notype: return reterror; } int up_lcm_device_add(LCM_DRIVER* nLcm, compatible_type isUsed) { struct up_type_info * lcm_type_info; struct up_lcm_device_info * plcm_device; int flag = -1; int reterror=0; list_for_each_entry(lcm_type_info,&up_devices->type_list,up_device){ if(lcm_type_info->dev_type == ID_LCM_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { lcm_type_info = kmalloc(sizeof(struct up_type_info), GFP_KERNEL); if(lcm_type_info == NULL) { printk("lcm_alloc type info failed ~~~~ \n"); reterror = -1; goto malloc_faid; } if(isUsed) init_device_type_info(lcm_type_info, nLcm, ID_LCM_TYPE); else init_device_type_info(lcm_type_info, NULL, ID_LCM_TYPE); } else { if(isUsed &&(lcm_type_info->current_used_dinfo!=NULL)) printk("~~~~add lcm error , duplicated current used lcm \n"); } flag =-1; list_for_each_entry(plcm_device,&lcm_type_info->up_dinfo,lcm_list){ if(!strcmp(nLcm->name,plcm_device->lcm_module_descrip)) { flag =1; // this mean device is ok break; } } if(flag ==1) { printk("error ___ lcm type is duplicated \n"); goto duplicated_faild; } else { plcm_device = kmalloc(sizeof(struct up_lcm_device_info), GFP_KERNEL); if(plcm_device == NULL) { printk("lcm_alloc type info failed ~~~~ \n"); reterror = -2; goto devicemalloc_faid; } init_lcm_device(plcm_device,nLcm); plcm_device->type=isUsed; list_add(&plcm_device->up_list, &up_devices->dev_list); list_add(&plcm_device->lcm_list,&lcm_type_info->up_dinfo); } return 0; duplicated_faild: devicemalloc_faid: kfree(plcm_device); malloc_faid: printk("%s: error return: %x: ---\n",__func__,reterror); return reterror; } static int up_camera_set_used(char * module_name, int pdata) { struct up_type_info * camera_type_info; struct up_camera_device_dinfo * pcamera_device; int flag = -1; int reterror=0; list_for_each_entry(camera_type_info,&up_devices->type_list,up_device){ if(camera_type_info->dev_type == ID_CAMERA_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { reterror = -1; goto error_notype; } flag =-1; list_for_each_entry(pcamera_device,&camera_type_info->up_dinfo,camera_list){ if(!strcmp(module_name,pcamera_device->camera_module_descrip)) { pcamera_device->type = DEVICE_USED; pcamera_device->cam_type = pdata; flag =1; // this mean device is ok break; } } if(flag == 1) return 0; error_notype: return reterror; } #if __CUST_MCAM_OTP_PDAF_STATUS__ extern char up_mcam_otp_status; extern char up_mcam_pdaf_status; #endif #if __CUST_SCAM_OTP_PDAF_STATUS__ extern char up_scam_otp_status; #endif static int up_camera_info_print(struct seq_file *se_f) { struct up_type_info * camera_type_info; struct up_camera_device_dinfo * pcamera_device; int flag = -1; seq_printf(se_f, "---------UP CAMERA USAGE-------- \n"); list_for_each_entry(camera_type_info,&up_devices->type_list,up_device){ if(camera_type_info->dev_type == ID_CAMERA_TYPE) { flag =1; // this mean type is ok break; } } if(flag == 1) { list_for_each_entry(pcamera_device,&camera_type_info->up_dinfo,camera_list){ seq_printf(se_f, " %20s\t\t: ",pcamera_device->camera_module_descrip); if(pcamera_device->type == DEVICE_SUPPORTED) seq_printf(se_f, " supported \n"); else { seq_printf(se_f, " used \t"); if(pcamera_device->cam_type ==DUAL_CAMERA_MAIN_SENSOR) { seq_printf(se_f, " main camera "); #if __CUST_MCAM_OTP_PDAF_STATUS__ if(up_mcam_otp_status) seq_printf(se_f, "\n\t\t\t\t\t\t\t\tMCAM OTP CHECK Success"); if(up_mcam_pdaf_status) seq_printf(se_f, "\n\t\t\t\t\t\t\t\tMCAM PDAF CHECK Success"); #endif seq_printf(se_f, "\n"); } else if(pcamera_device->cam_type ==DUAL_CAMERA_SUB_SENSOR) { seq_printf(se_f, " sub camera "); #if __CUST_SCAM_OTP_PDAF_STATUS__ if(up_scam_otp_status) seq_printf(se_f, "\n\t\t\t\t\t\t\t\tSCAM OTP CHECK Success"); #endif seq_printf(se_f, "\n"); } else if(pcamera_device->cam_type == 3) { seq_printf(se_f, " main2 camera \n"); } else if(pcamera_device->cam_type == 4) { seq_printf(se_f, " sub2 camera \n"); } else if(pcamera_device->cam_type == 5) { seq_printf(se_f, " main3 camera \n"); } else seq_printf(se_f, " camera unsupportd type %d\n", pcamera_device->cam_type); } } } else { seq_printf(se_f, " \t: NONE \n"); } return 0; } static void init_camera_device(struct up_camera_device_dinfo *pdevice, struct ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT* mCamera) { memset(pdevice,0, sizeof(struct up_camera_device_dinfo)); INIT_LIST_HEAD(&pdevice->up_list); INIT_LIST_HEAD(&pdevice->camera_list); strcpy(pdevice->camera_module_descrip,mCamera->drvname); pdevice->pdata=mCamera; } int up_camera_device_add(struct ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT* mCamera, compatible_type isUsed) { struct up_type_info * camera_type_info; struct up_camera_device_dinfo * pcamera_device; int flag = -1; int reterror=0; list_for_each_entry(camera_type_info,&up_devices->type_list,up_device){ if(camera_type_info->dev_type == ID_CAMERA_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { camera_type_info = kmalloc(sizeof(struct up_type_info), GFP_KERNEL); if(camera_type_info == NULL) { printk("cam_alloc type info failed ~~~~ \n"); reterror = -1; goto malloc_faid; } if(isUsed) init_device_type_info(camera_type_info, mCamera, ID_CAMERA_TYPE); else init_device_type_info(camera_type_info, NULL, ID_CAMERA_TYPE); } else { if(isUsed &&(camera_type_info->current_used_dinfo!=NULL)) printk("~~~~add camera error , duplicated current used lcm \n"); } flag =-1; list_for_each_entry(pcamera_device,&camera_type_info->up_dinfo,camera_list){ if(!strcmp(mCamera->drvname,pcamera_device->camera_module_descrip)) { flag =1; // this mean device is ok break; } } if(flag ==1) { goto duplicated_faild; } else { pcamera_device = kmalloc(sizeof(struct up_camera_device_dinfo), GFP_KERNEL); if(camera_type_info == NULL) { printk("cam_alloc type info failed ~~~~ \n"); reterror = -2; goto malloc_faid; } init_camera_device(pcamera_device,mCamera); pcamera_device->type=isUsed; list_add(&pcamera_device->up_list, &up_devices->dev_list); list_add(&pcamera_device->camera_list,&camera_type_info->up_dinfo); } return 0; duplicated_faild: kfree(pcamera_device); malloc_faid: printk("%s: error return: %x: ---\n",__func__,reterror); return reterror; } static int up_touchpanel_set_used(char * module_name, int pdata) { struct up_type_info * touchpanel_type_info; struct up_touchpanel_device_dinfo * ptouchpanel_device; int flag = -1; int reterror=0; list_for_each_entry(touchpanel_type_info,&up_devices->type_list,up_device){ if(touchpanel_type_info->dev_type == ID_TOUCH_TYPE) { printk("touch type has find break !!\n"); flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { reterror = -1; goto error_notype; } flag =-1; list_for_each_entry(ptouchpanel_device,&touchpanel_type_info->up_dinfo,touch_list){ if(!strcmp(module_name,ptouchpanel_device->touch_descrip)) { ptouchpanel_device->type = DEVICE_USED; flag =1; // this mean device is ok break; } } if(flag == 1) return 0; error_notype: return reterror; } static int up_touchpanel_info_print(struct seq_file *se_f) { struct up_type_info * touchpanel_type_info; struct up_touchpanel_device_dinfo * ptouchpanel_device; int flag = -1; seq_printf(se_f, "--------UP TOUCHPANEL USAGE-------\t \n"); list_for_each_entry(touchpanel_type_info,&up_devices->type_list,up_device){ if(touchpanel_type_info->dev_type == ID_TOUCH_TYPE) { flag =1; // this mean type is ok break; } } if(flag == 1) { list_for_each_entry(ptouchpanel_device,&touchpanel_type_info->up_dinfo,touch_list){ seq_printf(se_f, " %20s\t: ",ptouchpanel_device->touch_descrip); if(ptouchpanel_device->type == DEVICE_SUPPORTED) seq_printf(se_f, " supported \n"); else { seq_printf(se_f, " used \t \n"); seq_printf(se_f, " %20s\t \n", touch_fw_version); } } } else { seq_printf(se_f, " \t: NONE \n"); } return 0; } static void init_touchpanel_device(struct up_touchpanel_device_dinfo *pdevice, struct i2c_driver * mTouch) { memset(pdevice,0, sizeof(struct up_touchpanel_device_dinfo)); INIT_LIST_HEAD(&pdevice->up_list); INIT_LIST_HEAD(&pdevice->touch_list); strcpy(pdevice->touch_descrip,mTouch->driver.name); pdevice->pdata=mTouch; } int up_touchpanel_device_add(struct i2c_driver* mTouch, compatible_type isUsed) { struct up_type_info * touchpanel_type_info; struct up_touchpanel_device_dinfo * ptouchpanel_device; int flag = -1; int reterror=0; list_for_each_entry(touchpanel_type_info,&up_devices->type_list,up_device){ if(touchpanel_type_info->dev_type == ID_TOUCH_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { touchpanel_type_info = kmalloc(sizeof(struct up_type_info), GFP_KERNEL); if(touchpanel_type_info == NULL) { printk("tp_alloc type info failed ~~~~ \n"); reterror = -1; goto malloc_faid; } if(isUsed) init_device_type_info(touchpanel_type_info, mTouch, ID_TOUCH_TYPE); else init_device_type_info(touchpanel_type_info, NULL, ID_TOUCH_TYPE); } else { if(isUsed &&(touchpanel_type_info->current_used_dinfo!=NULL)) printk("~~~~add tp error , duplicated current used lcm \n"); } flag =-1; list_for_each_entry(ptouchpanel_device,&touchpanel_type_info->up_dinfo,touch_list){ if(!strcmp(mTouch->driver.name,ptouchpanel_device->touch_descrip)) { flag =1; // this mean device is ok break; } } if(flag ==1) { goto duplicated_faild; } else { ptouchpanel_device = kmalloc(sizeof(struct up_touchpanel_device_dinfo), GFP_KERNEL); if(ptouchpanel_device == NULL) { printk("tp_alloc type info failed ~~~~ \n"); reterror = -2; goto malloc_faid; } init_touchpanel_device(ptouchpanel_device,mTouch); ptouchpanel_device->type=isUsed; list_add(&ptouchpanel_device->up_list, &up_devices->dev_list); list_add(&ptouchpanel_device->touch_list,&touchpanel_type_info->up_dinfo); } return 0; duplicated_faild: kfree(ptouchpanel_device); malloc_faid: printk("%s: error return: %x: ---\n",__func__,reterror); return reterror; } static int up_accsensor_set_used(char * module_name, int pdata) { struct up_type_info * accsensor_type_info; struct up_accsensor_device_dinfo * paccsensor_device; int flag = -1; int reterror=0; list_for_each_entry(accsensor_type_info,&up_devices->type_list,up_device){ if(accsensor_type_info->dev_type == ID_ACCSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { reterror = -1; goto error_notype; } flag =-1; list_for_each_entry(paccsensor_device,&accsensor_type_info->up_dinfo,sensor_list){ if(!strcmp(module_name,paccsensor_device->sensor_descrip)) { paccsensor_device->type = DEVICE_USED; flag =1; // this mean device is ok break; } } if(flag == 1) return 0; error_notype: return reterror; } static int up_accsensor_info_print(struct seq_file *se_f) { struct up_type_info * accsensor_type_info; struct up_accsensor_device_dinfo * paccsensor_device; int flag = -1; seq_printf(se_f, "--------UP accsensor USAGE-------\t \n"); list_for_each_entry(accsensor_type_info,&up_devices->type_list,up_device){ if(accsensor_type_info->dev_type == ID_ACCSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == 1) { list_for_each_entry(paccsensor_device,&accsensor_type_info->up_dinfo,sensor_list){ seq_printf(se_f, " %20s\t\t: ",paccsensor_device->sensor_descrip); if(paccsensor_device->type == DEVICE_SUPPORTED) seq_printf(se_f, " supported \n"); else { seq_printf(se_f, " used \t\n"); } } } else { seq_printf(se_f, " \t: NONE \n"); } return 0; } static void init_accsensor_device(struct up_accsensor_device_dinfo *pdevice, struct acc_init_info * maccsensor) { memset(pdevice,0, sizeof(struct up_accsensor_device_dinfo)); INIT_LIST_HEAD(&pdevice->up_list); INIT_LIST_HEAD(&pdevice->sensor_list); strcpy(pdevice->sensor_descrip,maccsensor->name); pdevice->pdata=maccsensor; } int up_accsensor_device_add(struct acc_init_info* maccsensor, compatible_type isUsed) { struct up_type_info * accsensor_type_info; struct up_accsensor_device_dinfo * paccsensor_device; struct acc_init_info * pacc_sensor; int flag = -1; int reterror=0; pacc_sensor = maccsensor; list_for_each_entry(accsensor_type_info,&up_devices->type_list,up_device){ if(accsensor_type_info->dev_type == ID_ACCSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { accsensor_type_info = kmalloc(sizeof(struct up_type_info), GFP_KERNEL); if(accsensor_type_info == NULL) { printk("acc_alloc type info failed ~~~~ \n"); reterror = -1; goto malloc_faid; } if(isUsed) init_device_type_info(accsensor_type_info, maccsensor, ID_ACCSENSOR_TYPE); else init_device_type_info(accsensor_type_info, NULL, ID_ACCSENSOR_TYPE); } else { if(isUsed &&(accsensor_type_info->current_used_dinfo!=NULL)) printk("~~~~add accsensor error , duplicated current used lcm \n"); } flag =-1; list_for_each_entry(paccsensor_device,&accsensor_type_info->up_dinfo,sensor_list){ if(!strcmp(maccsensor->name,paccsensor_device->sensor_descrip)) { flag =1; // this mean device is ok break; } } if(flag ==1) { goto duplicated_faild; } else { paccsensor_device = (struct up_accsensor_device_dinfo *)kmalloc(sizeof(struct up_accsensor_device_dinfo), GFP_KERNEL); if(paccsensor_device == NULL) { printk("acc_alloc type info failed ~~~~ \n"); reterror = -2; goto malloc_faid; } init_accsensor_device(paccsensor_device , pacc_sensor); paccsensor_device->type=isUsed; list_add(&paccsensor_device->up_list, &up_devices->dev_list); list_add(&paccsensor_device->sensor_list,&accsensor_type_info->up_dinfo); } return 0; duplicated_faild: kfree(paccsensor_device); malloc_faid: printk("%s: error return: %x: ---\n",__func__,reterror); return reterror; } //MSENSOR START static int up_msensor_set_used(char * module_name, int pdata) { struct up_type_info * msensor_type_info; struct up_msensor_device_dinfo * pmsensor_device; int flag = -1; int reterror=0; list_for_each_entry(msensor_type_info,&up_devices->type_list,up_device){ if(msensor_type_info->dev_type == ID_MSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { reterror = -1; goto error_notype; } flag =-1; list_for_each_entry(pmsensor_device,&msensor_type_info->up_dinfo,sensor_list){ if(!strcmp(module_name,pmsensor_device->sensor_descrip)) { pmsensor_device->type = DEVICE_USED; flag =1; // this mean device is ok break; } } if(flag == 1) return 0; error_notype: return reterror; } static int up_msensor_info_print(struct seq_file *se_f) { struct up_type_info * msensor_type_info; struct up_msensor_device_dinfo * pmsensor_device; int flag = -1; seq_printf(se_f, "--------UP msensor USAGE-------\t \n"); list_for_each_entry(msensor_type_info,&up_devices->type_list,up_device){ if(msensor_type_info->dev_type == ID_MSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == 1) { list_for_each_entry(pmsensor_device,&msensor_type_info->up_dinfo,sensor_list){ seq_printf(se_f, " %20s\t\t: ",pmsensor_device->sensor_descrip); if(pmsensor_device->type == DEVICE_SUPPORTED) seq_printf(se_f, " supported \n"); else { seq_printf(se_f, " used \t\n"); } } } else { seq_printf(se_f, " \t: NONE \n"); } return 0; } static void init_msensor_device(struct up_msensor_device_dinfo *pdevice, struct mag_init_info * mmsensor) { memset(pdevice,0, sizeof(struct up_msensor_device_dinfo)); INIT_LIST_HEAD(&pdevice->up_list); INIT_LIST_HEAD(&pdevice->sensor_list); strcpy(pdevice->sensor_descrip,mmsensor->name); pdevice->pdata=mmsensor; } int up_msensor_device_add(struct mag_init_info* mmsensor, compatible_type isUsed) { struct up_type_info * msensor_type_info; struct up_msensor_device_dinfo * pmsensor_device; int flag = -1; int reterror=0; list_for_each_entry(msensor_type_info,&up_devices->type_list,up_device){ if(msensor_type_info->dev_type == ID_MSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { msensor_type_info = kmalloc(sizeof(struct up_type_info), GFP_KERNEL); if(msensor_type_info == NULL) { printk("msensor_alloc type info failed ~~~~ \n"); reterror = -1; goto malloc_faid; } if(isUsed) init_device_type_info(msensor_type_info, mmsensor, ID_MSENSOR_TYPE); else init_device_type_info(msensor_type_info, NULL, ID_MSENSOR_TYPE); } else { if(isUsed &&(msensor_type_info->current_used_dinfo!=NULL)) printk("~~~~add msensor error , duplicated current used lcm \n"); } flag =-1; list_for_each_entry(pmsensor_device,&msensor_type_info->up_dinfo,sensor_list){ if(!strcmp(mmsensor->name,pmsensor_device->sensor_descrip)) { flag =1; // this mean device is ok break; } } if(flag ==1) { goto duplicated_faild; } else { pmsensor_device = kmalloc(sizeof(struct up_msensor_device_dinfo), GFP_KERNEL); if(pmsensor_device == NULL) { printk("msensor_alloc type info failed ~~~~ \n"); reterror = -2; goto malloc_faid; } init_msensor_device(pmsensor_device,mmsensor); pmsensor_device->type=isUsed; list_add(&pmsensor_device->up_list, &up_devices->dev_list); list_add(&pmsensor_device->sensor_list,&msensor_type_info->up_dinfo); } return 0; duplicated_faild: kfree(pmsensor_device); malloc_faid: printk("%s: error return: %x: ---\n",__func__,reterror); return reterror; } //MSENSOR END //ALSPSSENSOR START static int up_alspssensor_set_used(char * module_name, int pdata) { struct up_type_info * alspssensor_type_info; struct up_alspssensor_device_dinfo * palspssensor_device; int flag = -1; int reterror=0; list_for_each_entry(alspssensor_type_info,&up_devices->type_list,up_device){ if(alspssensor_type_info->dev_type == ID_ALSPSSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { reterror = -1; goto error_notype; } flag =-1; list_for_each_entry(palspssensor_device,&alspssensor_type_info->up_dinfo,sensor_list){ if(!strcmp(module_name,palspssensor_device->sensor_descrip)) { palspssensor_device->type = DEVICE_USED; flag =1; // this mean device is ok break; } } if(flag == 1) return 0; error_notype: return reterror; } static int up_alspssensor_info_print(struct seq_file *se_f) { struct up_type_info * alspssensor_type_info; struct up_alspssensor_device_dinfo * palspssensor_device; int flag = -1; seq_printf(se_f, "--------UP alspssensor USAGE-------\t \n"); list_for_each_entry(alspssensor_type_info,&up_devices->type_list,up_device){ if(alspssensor_type_info->dev_type == ID_ALSPSSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == 1) { list_for_each_entry(palspssensor_device,&alspssensor_type_info->up_dinfo,sensor_list){ seq_printf(se_f, " %20s\t\t: ",palspssensor_device->sensor_descrip); if(palspssensor_device->type == DEVICE_SUPPORTED) seq_printf(se_f, " supported \n"); else { seq_printf(se_f, " used \t\n"); } } } else { seq_printf(se_f, " \t: NONE \n"); } return 0; } static void init_alspssensor_device(struct up_alspssensor_device_dinfo *pdevice, struct alsps_init_info * malspssensor) { memset(pdevice,0, sizeof(struct up_alspssensor_device_dinfo)); INIT_LIST_HEAD(&pdevice->up_list); INIT_LIST_HEAD(&pdevice->sensor_list); strcpy(pdevice->sensor_descrip,malspssensor->name); pdevice->pdata=malspssensor; } int up_alspssensor_device_add(struct alsps_init_info* malspssensor, compatible_type isUsed) { struct up_type_info * alspssensor_type_info; struct up_alspssensor_device_dinfo * palspssensor_device; int flag = -1; int reterror=0; list_for_each_entry(alspssensor_type_info,&up_devices->type_list,up_device){ if(alspssensor_type_info->dev_type == ID_ALSPSSENSOR_TYPE) { flag =1; // this mean type is ok break; } } if(flag == -1) // this mean type is new { alspssensor_type_info = kmalloc(sizeof(struct up_type_info), GFP_KERNEL); if(alspssensor_type_info == NULL) { printk("alsps_alloc type info failed ~~~~ \n"); reterror = -1; goto malloc_faid; } if(isUsed) init_device_type_info(alspssensor_type_info, malspssensor, ID_ALSPSSENSOR_TYPE); else init_device_type_info(alspssensor_type_info, NULL, ID_ALSPSSENSOR_TYPE); } else { if(isUsed &&(alspssensor_type_info->current_used_dinfo!=NULL)) printk("~~~~add alsps error , duplicated current used lcm \n"); } flag =-1; list_for_each_entry(palspssensor_device,&alspssensor_type_info->up_dinfo,sensor_list){ if(!strcmp(malspssensor->name,palspssensor_device->sensor_descrip)) { flag =1; // this mean device is ok break; } } if(flag ==1) { goto duplicated_faild; } else { palspssensor_device = kmalloc(sizeof(struct up_alspssensor_device_dinfo), GFP_KERNEL); if(palspssensor_device == NULL) { printk("alsps_alloc type info failed ~~~~ \n"); reterror = -2; goto malloc_faid; } init_alspssensor_device(palspssensor_device,malspssensor); palspssensor_device->type=isUsed; list_add(&palspssensor_device->up_list, &up_devices->dev_list); list_add(&palspssensor_device->sensor_list,&alspssensor_type_info->up_dinfo); } return 0; duplicated_faild: kfree(palspssensor_device); malloc_faid: printk("%s: error return: %x: ---\n",__func__,reterror); return reterror; } //ALSPSSENSOR END static int up_set_device_used(int dev_type, char * module_name, int pdata) { struct up_type_info * type_info; int ret_val = 0; list_for_each_entry(type_info,&up_devices->type_list,up_device){ if(type_info->dev_type == dev_type) { if(type_info->set_used!=NULL) type_info->set_used(module_name,pdata); } } return ret_val; } int up_set_touch_device_used(char * module_name, int pdata) { int ret_val = 0; ret_val = up_set_device_used(ID_TOUCH_TYPE,module_name,pdata); return ret_val; } int up_set_camera_device_used(char * module_name, int pdata) { int ret_val = 0; ret_val = up_set_device_used(ID_CAMERA_TYPE,module_name,pdata); return ret_val; } int up_set_accsensor_device_used(char * module_name, int pdata) { int ret_val = 0; ret_val = up_set_device_used(ID_ACCSENSOR_TYPE,module_name,pdata); return ret_val; } //MSENSOR int up_set_msensor_device_used(char * module_name, int pdata) { int ret_val = 0; ret_val = up_set_device_used(ID_MSENSOR_TYPE,module_name,pdata); return ret_val; } //ALSPSSENSOR int up_set_alspssensor_device_used(char * module_name, int pdata) { int ret_val = 0; ret_val = up_set_device_used(ID_ALSPSSENSOR_TYPE,module_name,pdata); return ret_val; } extern LCM_DRIVER *lcm_driver_list[]; extern unsigned int lcm_count; extern int proc_upinfo_init(void); #ifdef CONFIG_MACH_MT6779 extern struct ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT gimgsensor_sensor_list[]; #else extern struct ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT kdSensorList[]; #endif extern LCM_DRIVER * DISP_GetLcmDrv(void); static LCM_DRIVER *lcm_drv = NULL; static void init_lcm(void) { int temp; lcm_drv = DISP_GetLcmDrv(); if(lcm_count ==1) { up_lcm_device_add(lcm_driver_list[0], DEVICE_USED); } else { for(temp= 0;temp< lcm_count;temp++) { if(lcm_drv == lcm_driver_list[temp]) up_lcm_device_add(lcm_driver_list[temp], DEVICE_USED); else up_lcm_device_add(lcm_driver_list[temp], DEVICE_SUPPORTED); } } } void up_add_display_info(char * buffer, int lenth) { struct up_mis_disp_info * new_display_info; char * buffer_info=NULL; #if 0 if(*(buffer+lenth)!="\0") { printk("display info error\n"); return; } #endif new_display_info = kmalloc(sizeof(struct up_mis_disp_info), GFP_KERNEL ); list_add(&new_display_info->mis_info_list , &updisp_info_list); buffer_info = kmalloc(lenth , GFP_KERNEL ); new_display_info->current_used_dinfo = buffer_info; memcpy(buffer_info, buffer,lenth ); } void up_display_info_dump(struct seq_file *m) { struct up_mis_disp_info * pdisp_info=NULL; seq_printf(m, "----UP INFO DUMP---\t \n"); list_for_each_entry(pdisp_info,&updisp_info_list ,mis_info_list){ seq_printf(m, "Info:%s\n",(char *)pdisp_info->current_used_dinfo); } } #ifdef EMMC_COMPATIBLE_NUM extern char *saved_command_line; int get_lpddr_emmc_used_index(void) { char *ptr; int lpddr_index=0; ptr=strstr(saved_command_line,"lpddr_used_index="); if(ptr==NULL) return -1; ptr+=strlen("lpddr_used_index="); lpddr_index=simple_strtol(ptr,NULL,10); return lpddr_index; } int get_lpddr_emmc_flash_type(void) { char *ptr; int flash_type=0; ptr=strstr(saved_command_line,"flash_type="); if(ptr==NULL) return 0xFF; ptr+=strlen("flash_type="); flash_type=simple_strtol(ptr,NULL,10); return flash_type; } #endif #if defined(CONFIG_MACH_MT6757) #include "../accdet/mt6355/accdet.h" #else //#include #endif //extern struct head_dts_data accdet_dts; #if !defined(CONFIG_SND_SOC_AW87XXX) #ifndef CONFIG_MTK_SPEAKER #ifdef CONFIG_MACH_MT6779 #else extern int extamp_sound_mode; #endif #endif #endif extern char dump_stack_arch_desc_str[128]; char bbchip_name[128]; #if defined(CONFIG_SND_SOC_AW87XXX) enum up_pa_aw87xxx_chipid { UP_PA_AW87XXX_CHIPID_39 = 0x39, UP_PA_AW87XXX_CHIPID_59 = 0x59, UP_PA_AW87XXX_CHIPID_69 = 0x69, UP_PA_AW87XXX_CHIPID_5A = 0x5A, }; enum up_userd_aw_dev_chipid { UP_USERD_AW_DEV_CHIPID_18 = 0x18, UP_USERD_AW_DEV_CHIPID_39 = 0x39, UP_USERD_AW_DEV_CHIPID_59 = 0x59, UP_USERD_AW_DEV_CHIPID_69 = 0x69, UP_USERD_AW_DEV_CHIPID_5A = 0x5A, UP_USERD_AW_DEV_CHIPID_9A = 0x9A, UP_USERD_AW_DEV_CHIPID_9B = 0x9B, YUP_USERD_AW_DEV_CHIPID_76 = 0x76, }; extern int pa_model; #endif int up_device_dump(struct seq_file *m) { static int ilcm_init = 0; struct up_type_info * type_info; int i = 0; if(0 == ilcm_init) { init_lcm(); ilcm_init = 1; } for(i=0;itype_list,up_device) { if(type_info->type_print == NULL) { printk(" error !!! this type [%d] has no dump fun \n",type_info->dev_type); } else type_info->type_print(m); } seq_printf(m,"---------CUST MIC MODE-------- \n"); //seq_printf(m," accdet mic mode : %d\n",accdet_dts.mic_mode); #if defined(CONFIG_SND_SOC_AW87XXX) switch (pa_model) { case UP_USERD_AW_DEV_CHIPID_18: seq_printf(m," audio PA : AW87539\n"); goto device_show; case UP_USERD_AW_DEV_CHIPID_39: seq_printf(m," audio PA : AW87339\n"); goto device_show; case UP_USERD_AW_DEV_CHIPID_59: seq_printf(m," audio PA : AW87519\n"); goto device_show; case UP_USERD_AW_DEV_CHIPID_69: seq_printf(m," audio PA : AW87369\n"); goto device_show; case UP_USERD_AW_DEV_CHIPID_5A: seq_printf(m," audio PA : AW87559\n"); goto device_show; case UP_USERD_AW_DEV_CHIPID_9A: seq_printf(m," audio PA : AW87309\n"); goto device_show; case UP_USERD_AW_DEV_CHIPID_9B: seq_printf(m," audio PA : AW87319\n"); goto device_show; case YUP_USERD_AW_DEV_CHIPID_76: seq_printf(m," audio PA : AW87390\n"); goto device_show; default: seq_printf(m," audio PA : No supported pa\n"); break; } #else #ifndef CONFIG_MTK_SPEAKER #ifndef __CUST_EXTAMP_MODE__ #else seq_printf(m," UP_EXTAMP_HP_MODE : %d\n",extamp_sound_mode); #endif #endif #endif #if defined(CONFIG_SND_SOC_AW87XXX) device_show: #endif seq_printf(m, "modem: %s\n", CUSTOM_MODEM); up_display_info_dump(m); return 0; } int up_memory_dump(struct seq_file *m) { #ifdef EMMC_COMPATIBLE_NUM { int tem = 0; int flash_idex=0; flash_idex = get_lpddr_emmc_used_index(); seq_printf(m, "----UP Memory USAGE---\t \n"); seq_printf(m," EMMC compatible num =%d,type=%x \n", EMMC_COMPATIBLE_NUM,get_lpddr_emmc_flash_type()); for(;tem 5){ printk("UPIOC_SET_EXTAMP_SOUND_MODE err,mode:%d \n",data); break; }else extamp_sound_mode = data; ret = copy_to_user((int *)arg, &extamp_sound_mode ,sizeof(int)); break; case UPIOC_GET_ACCDET_MIC_MODE : //ret = copy_to_user((unsigned int *)arg, & accdet_dts_data.accdet_mic_mode ,sizeof(int)); break; case UPIOC_SET_ACCDET_MIC_MODE : break; case UPIOC_GET_ADC_VALUE: ret = copy_from_user(&data ,(int *)arg,sizeof(int)); if (ret != 0) break; if( data < 0 || data > 14 ){ printk("UPIOC_GET_ADC_VALUE data err,data:%d \n",data); } ret = IMM_GetOneChannelValue(data, adcdata, &rawdata); printk("up_adc_read Channel:%d rawdata= %x adcdata= %x %x, ret=%d \n",data,rawdata, adcdata[0], adcdata[1],ret); if (ret != 0) break; ret = copy_to_user((int *)arg, &rawdata ,sizeof(int)); break; default: printk("up_devices ioctl is not exits\n"); break; } if (ret < 0){ printk("up_devices ioctl failed\n"); } return ret; } static const struct file_operations up_devices_fops = { .owner = THIS_MODULE, // .write = up_devices_write, // .read = up_devices_read, .unlocked_ioctl = up_devices_ioctl, // .compat_ioctl = up_devices_compat_ioctl, .open = up_devices_open, .release = up_devices_release, .llseek = no_llseek, }; static struct miscdevice up_devices_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "up_devices", .fops = &up_devices_fops, }; #endif int get_cts_flag_from_cmdline(void) { char *ptr; int ret=0; ptr=strstr(saved_command_line,"up_cts_flag="); if(ptr==NULL) return -1; ptr+=strlen("up_cts_flag="); ret=simple_strtol(ptr,NULL,10); printk("get_cts_flag_from_cmdline. ret = %d. \n", ret); return ret ? 1 : 0; } int is_up_cts_board(void) { #ifdef __CUST_URXDO_GPIO_SELECT__ return up_urxdo_flag; #endif #ifdef __CUST_S900_CAMERA_CTS_COMPATIBLE__ int id_volt = 0; int ret; ret = IMM_GetOneChannelValue_Cali(3, &id_volt); if (ret != 0) printk("id_volt read fail\n"); else printk("id_volt = %d\n", id_volt); if(id_volt/1000 > 1100) { return true; } else { return false; } #endif { int value = get_cts_flag_from_cmdline(); return (1 == value) ? 1: 0; } return 0; } int up_cts_dump(struct seq_file *m) { seq_printf(m, is_up_cts_board() ? "1" : "0"); return 0; } static ssize_t mt_cts_flag_show(struct device *dev, struct device_attribute *attr, char *buf) { int value; if (!dev) { printk("mt_cts_flag_show. dev is null!!\n"); return 0; } value = is_up_cts_board() ? 1 : 0; return scnprintf(buf, PAGE_SIZE, "%d\n", value); } DEVICE_ATTR(up_cts_flag, 0664, mt_cts_flag_show, NULL); static struct device_attribute *mt_sysfs_attributes[] = { &dev_attr_up_cts_flag, NULL }; static int init_up_sysfs(struct device *dev) { struct device_attribute **attr; int rc; printk("init_up_sysfs. begin. \n"); for (attr = mt_sysfs_attributes; *attr; attr++) { rc = device_create_file(dev, *attr); if (rc) goto out_unreg; } return 0; out_unreg: for (; attr >= mt_sysfs_attributes; attr--) device_remove_file(dev, *attr); return rc; } static int up_devices_probe(struct platform_device *pdev) { int temp; int err =0; struct device *dev = &pdev->dev; err = proc_upinfo_init(); if(err<0) goto proc_error; up_devices = kmalloc(sizeof(struct up_devices_info), GFP_KERNEL); if(up_devices == NULL) { printk("%s: error probe becase of mem\n",__func__); return -1; } INIT_LIST_HEAD(&up_devices->type_list); INIT_LIST_HEAD(&up_devices->dev_list); mutex_init(&up_devices->de_mutex); INIT_LIST_HEAD(&updisp_info_list); for(temp=0;;temp++) { #ifdef CONFIG_MACH_MT6779 if(gimgsensor_sensor_list[temp].SensorInit!=NULL) { up_camera_device_add(&gimgsensor_sensor_list[temp], DEVICE_SUPPORTED); } #else if(kdSensorList[temp].SensorInit!=NULL) { up_camera_device_add(&kdSensorList[temp], DEVICE_SUPPORTED); } #endif else break; } #ifdef UP_DEVICES_IOCTL_SUPPORT err = misc_register(&up_devices_misc); if (err < 0) { printk("%s: misc_register error!\n",__func__); goto proc_error; } spin_lock_init(&lock); #endif if (init_up_sysfs(dev)) { printk("failed to init_sysfs. \n"); } return 0; proc_error: return err; } /*----------------------------------------------------------------------------*/ static int up_devices_remove(struct platform_device *pdev) { #ifdef UP_DEVICES_IOCTL_SUPPORT misc_deregister(&up_devices_misc); #endif return 0; } #ifdef CONFIG_OF struct of_device_id up_device_of_match[] = { { .compatible = "mediatek,up_devices", }, {}, }; #endif /*----------------------------------------------------------------------------*/ static struct platform_driver up_devices_driver = { .probe = up_devices_probe, .remove = up_devices_remove, .driver = { .name = UP_DEVICE, .owner = THIS_MODULE, #ifdef CONFIG_OF .of_match_table = up_device_of_match, #endif }, }; #ifndef CONFIG_OF static struct platform_device up_dev = { .name = "up_devices", .id = -1, }; #endif /*----------------------------------------------------------------------------*/ int up_debug = 0; static int __init up_devices_init(void) { #ifndef CONFIG_OF retval = platform_device_register(&up_dev); if (retval != 0){ return retval; } #endif up_debug = 1; if(platform_driver_register(&up_devices_driver)) { up_debug = 0; printk("failed to register driver"); return -ENODEV; } up_debug = 0; #ifdef __CUST_URXDO_GPIO_SELECT__ #if __CUST_URXDO_GPIO_SELECT__ if(0 > get_urxdo_select_gpio()) { printk("get_urxdo_select_gpio failed.\n"); } #endif #endif return 0; } /*----------------------------------------------------------------------------*/ static void __exit up_devices_exit(void) { platform_driver_unregister(&up_devices_driver); } /*----------------------------------------------------------------------------*/ rootfs_initcall(up_devices_init); module_exit(up_devices_exit); /*----------------------------------------------------------------------------*/ MODULE_DESCRIPTION("UP DEVICE INFO"); MODULE_LICENSE("GPL");