static ssize_t touchkey_firmup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { if(Flip_status){ printk(KERN_ERR "[TKEY] flip opened\n"); melfas_touchkey_switch_early_resume(Flip_status,1); }else{ disable_irq(touchkey_driver->client->irq); } printk(TCHKEY_KERN_DEBUG "Touchkey firm-up start!\n"); get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "F/W version: 0x%x, Module version:0x%x\n", version_info[1], version_info[2]); if ((version_info[1] < MCS5080_last_ver) || (version_info[1] == 0xff)){ mdelay(350); mcsdl_download_binary_data(MCS5080_CHIP); mdelay(100); get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "Updated F/W version: 0x%x, Module version:0x%x\n", version_info[1], version_info[2]); } else printk(KERN_ERR "Touchkey IC module is new, can't update!"); if(Flip_status){ printk(KERN_ERR "[TKEY] flip opened\n"); melfas_touchkey_switch_early_suspend(Flip_status,1); }else{ enable_irq(touchkey_driver->client->irq); } return size; }
static ssize_t touchkey_firmup_show(struct device *dev, struct device_attribute *attr, char *buf) { printk(TCHKEY_KERN_DEBUG "Touchkey firm-up start!\n"); if(version_info[2]==MCS5000_CHIP) mcsdl_download_binary_data(MCS5000_CHIP); else if(version_info[2]==MCS5080_CHIP) mcsdl_download_binary_data(MCS5080_CHIP); else printk(KERN_ERR "Touchkey IC module is old, can't update!"); get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "Updated F/W version: 0x%x, Module version:0x%x\n", version_info[1], version_info[2]); return sprintf(buf,"%02x\n",version_info[1]); }
static int i2c_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; struct input_dev *input_dev; struct melfas_touchkey_platform_data *pdata; int err = 0; printk(KERN_ERR "[TKEY] %s\n",__func__); printk("melfas touchkey probe called!\n"); touchkey_driver = kzalloc(sizeof(struct i2c_touchkey_driver), GFP_KERNEL); if (touchkey_driver == NULL) { dev_err(dev, "failed to create our state\n"); return -ENOMEM; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(struct melfas_touchkey_platform_data), GFP_KERNEL); if (!pdata) { dev_info(&client->dev, "Failed to allocate memory\n"); return -ENOMEM; } err = melfas_parse_dt(&client->dev, pdata); if (err) return err; }else pdata = client->dev.platform_data; melfas_request_gpio(pdata); // init_hw(); /* melfas_power_onoff(pdata,1); msleep(100); get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "%s F/W version: 0x%x, Module version:0x%x\n",__FUNCTION__, version_info[1], version_info[2]); */ irq_set_irq_type(gpio_to_irq(pdata->gpio_int), IRQF_TRIGGER_FALLING); melfas_config_gpio_i2c(pdata, 0); get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "%s F/W version: 0x%x, Module version:0x%x\n",__FUNCTION__, version_info[1], version_info[2]); touchkey_driver->client = client; touchkey_driver->client->irq = gpio_to_irq(pdata->gpio_int); strlcpy(touchkey_driver->client->name, "melfas_touchkey", I2C_NAME_SIZE); input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; touchkey_driver->input_dev = input_dev; input_dev->name = DEVICE_NAME; input_dev->phys = "melfas_touchkey/input0"; input_dev->id.bustype = BUS_HOST; set_bit(EV_SYN, input_dev->evbit); set_bit(EV_LED, input_dev->evbit); set_bit(LED_MISC, input_dev->ledbit); set_bit(EV_KEY, input_dev->evbit); set_bit(touchkey_keycode[1], input_dev->keybit); set_bit(touchkey_keycode[2], input_dev->keybit); set_bit(touchkey_keycode[3], input_dev->keybit); set_bit(touchkey_keycode[4], input_dev->keybit); mutex_init(&melfas_tsk_lock); err = input_register_device(input_dev); if (err) { input_free_device(input_dev); return err; } gpio_pend_mask_mem = ioremap(INT_PEND_BASE, 0x10); touchkey_wq = create_singlethread_workqueue("melfas_touchkey_wq"); if (!touchkey_wq) return -ENOMEM; INIT_WORK(&touchkey_driver->work, touchkey_work_func); #ifdef CONFIG_HAS_EARLYSUSPEND touchkey_driver->early_suspend.suspend = melfas_touchkey_early_suspend; touchkey_driver->early_suspend.resume = melfas_touchkey_early_resume; register_early_suspend(&touchkey_driver->early_suspend); #endif /* CONFIG_HAS_EARLYSUSPEND */ touchkey_enable = 1; if (request_irq(touchkey_driver->client->irq, touchkey_interrupt, IRQF_DISABLED, DEVICE_NAME, touchkey_driver)) { printk(KERN_ERR "%s Can't allocate irq ..\n", __FUNCTION__); return -EBUSY; } return 0; }
static int __init touchkey_init(void) { int ret = 0; u8 updated = 0; if ((ret = gpio_request(_3_GPIO_TOUCH_EN, "_3_GPIO_TOUCH_EN"))) printk(KERN_ERR "Failed to request gpio %s:%d\n", __func__, __LINE__); // if (ret = gpio_request(_3_GPIO_TOUCH_INT, "_3_GPIO_TOUCH_INT")) // printk(KERN_ERR "Failed to request gpio %s:%d\n", __func__, __LINE__); ret = misc_register(&touchkey_update_device); if (ret) { printk(KERN_ERR "%s misc_register fail\n",__FUNCTION__); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_activation) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_activation\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_activation.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_version) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_version\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_version.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_recommend) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_recommend\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_recommend.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_firmup) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_firmup\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_firmup.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_init) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_init\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_init.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_menu) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_menu\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_menu.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_touchkey_back) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touchkey_back\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_touchkey_back.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_brightness) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_brightness\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_brightness.attr.name); } if (device_create_file(touchkey_update_device.this_device, &dev_attr_enable_disable) < 0) { printk(KERN_ERR "%s device_create_file fail dev_attr_touch_update\n",__FUNCTION__); pr_err("Failed to create device file(%s)!\n", dev_attr_enable_disable.attr.name); } init_hw(); get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "%s F/W version: 0x%x, Module version:0x%x\n",__FUNCTION__, version_info[1], version_info[2]); //------------------- Auto Firmware Update Routine Start -------------------// if(HWREV>=8) { if(version_info[1]==0xff) //unknown firmware state { if(!mcsdl_download_binary_data(MCS5000_CHIP)) //try MCS-5000 download mcsdl_download_binary_data(MCS5080_CHIP); // if first try is fail, MCS-5080 download updated = 1; } else { if(version_info[2]>=MCS5000_CHIP) //MCS-5000 { if(version_info[1]!=MCS5000_last_ver) //not latest version { mcsdl_download_binary_data(MCS5000_CHIP); updated = 1; } } else if(version_info[2]==MCS5080_CHIP)//MCS-5080 { if(version_info[1]!=MCS5080_last_ver) //not latest version { mcsdl_download_binary_data(MCS5080_CHIP); updated = 1; } } else printk("Touchkey IC module is old, can't update!"); } if(updated) { get_touchkey_data(version_info, 3); printk(TCHKEY_KERN_DEBUG "Updated F/W version: 0x%x, Module version:0x%x\n", version_info[1], version_info[2]); } } //------------------- Auto Firmware Update Routine End -------------------// ret = i2c_add_driver(&touchkey_i2c_driver); if(ret||(touchkey_driver==NULL)) { touchkey_dead = 1; printk("ret = %d, touch_driver= %p:", ret, touchkey_driver); printk(KERN_ERR "melfas touch keypad registration failed, module not inserted.ret= %d\n", ret); } return ret; }
void touchkey_work_func(struct work_struct * p) { u8 data[5]; int keycode; int retry = 10; if(!gpio_get_value(_3_GPIO_TOUCH_INT) && !touchkey_dead) { get_touchkey_data(data, 5); if((data[0] & ESD_STATE_BIT)|(data[3]>=45)|(data[4]>=45)) // ESD state or abnormal sensitivity { is_suspending = 1; printk(KERN_ERR "touchkey ESD_STATE_BIT set\n"); if(user_press_on==1) { input_report_key(touchkey_driver->input_dev, TOUCHKEY_KEYCODE_MENU, 0); printk(TCHKEY_KERN_DEBUG "ESD release menu key\n"); } else if(user_press_on==2) { input_report_key(touchkey_driver->input_dev, TOUCHKEY_KEYCODE_BACK, 0); printk(TCHKEY_KERN_DEBUG "ESD release back key\n"); } user_press_on = 0; while(retry--) { gpio_direction_output(_3_GPIO_TOUCH_EN, 0); gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); msleep(300); init_hw(); if(i2c_touchkey_read(KEYCODE_REG, data, 3)>=0) { printk(TCHKEY_KERN_DEBUG "touchkey ESD init success\n"); enable_irq(IRQ_TOUCH_INT); is_suspending = 0; return; } printk(KERN_ERR "i2c transfer error after ESD, retry...%d",retry); } touchkey_dead = 1; gpio_direction_output(_3_GPIO_TOUCH_EN, 0); gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); printk(KERN_ERR "touchkey died after ESD"); return; } else { keycode = touchkey_keycode[data[0] & KEYCODE_BIT]; } if(activation_onoff){ if(data[0] & UPDOWN_EVENT_BIT) // key released { user_press_on = 0; input_report_key(touchkey_driver->input_dev, keycode, 0); input_sync(touchkey_driver->input_dev); // printk(TCHKEY_KERN_DEBUG "touchkey release keycode: %d\n", keycode); } else // key pressed { if(touch_state_val == 1) { printk(TCHKEY_KERN_DEBUG "touchkey pressed but don't send event because touch is pressed. \n"); } else { if(keycode==TOUCHKEY_KEYCODE_BACK) { //TSP_forced_release(); Jiseong.oh #ifdef CONFIG_CPU_FREQ // set_dvfs_target_level(LEV_800MHZ);//set to comment temporarily by mseok.chae 2011.01.11 #endif user_press_on = 2; back_sensitivity = data[4]; input_report_key(touchkey_driver->input_dev, keycode,1); input_sync(touchkey_driver->input_dev); // printk(TCHKEY_KERN_DEBUG "back key sensitivity = %d\n",back_sensitivity); // printk(TCHKEY_KERN_DEBUG " touchkey press keycode: %d\n", keycode); } else if(keycode==TOUCHKEY_KEYCODE_MENU) { user_press_on = 1; menu_sensitivity = data[3]; input_report_key(touchkey_driver->input_dev, keycode,1); input_sync(touchkey_driver->input_dev); // printk(TCHKEY_KERN_DEBUG "menu key sensitivity = %d\n",menu_sensitivity); // printk(TCHKEY_KERN_DEBUG " touchkey press keycode: %d\n", keycode); } } } } } else printk(KERN_ERR "touchkey interrupt line is high!\n"); enable_irq(IRQ_TOUCH_INT); return ; }