/* /sys/class/factory/tsp/fw_ver */ ssize_t factory_tsp_fw_ver_show(struct device *dev, struct device_attribute *attr, char *buf) { int ret; ist30xx_disable_irq(ts_data); ret = ist30xx_cmd_run_device(ts_data->client); if (ret) return sprintf(buf, "NULL"); ret = ist30xx_read_cmd(ts_data->client, CMD_GET_FW_VER, &ts_data->fw.ver); if (ret) return sprintf(buf, "NULL"); ret = ist30xx_read_cmd(ts_data->client, CMD_GET_PARAM_VER, &ts_data->param_ver); if (ret) return sprintf(buf, "NULL"); ist30xx_enable_irq(ts_data); tsp_info("tsp version: %d.%d(%d.%d.%d)\n", (ts_data->param_ver >> 8) & 0xFF, ts_data->param_ver & 0xFF, (ts_data->fw.ver >> 16) & 0xFF, (ts_data->fw.ver >> 8) & 0xFF, ts_data->fw.ver & 0xFF); return sprintf(buf, "%d.%d(%d.%d.%d)\n", (ts_data->param_ver >> 8) & 0xFF, ts_data->param_ver & 0xFF, (ts_data->fw.ver >> 16) & 0xFF, (ts_data->fw.ver >> 8) & 0xFF, ts_data->fw.ver & 0xFF); }
/* /sys/class/factory/tsp/panel_vendor */ ssize_t factory_tsp_panel_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) { int ret; u32 panel_vendor; ist30xx_disable_irq(ts_data); ret = ist30xx_cmd_run_device(ts_data->client); if (ret) return sprintf(buf, "NULL"); ret = ist30xx_read_cmd(ts_data->client, CMD_GET_TSP_VENDOR, &panel_vendor); if (ret) return sprintf(buf, "NULL"); /* * TSP panel_vendor * - ALPS 1 * - SUNTEL 2 * - TOVIS 3 * - ILJIN 4 * - SYNOPEX 5 * - TAEYANG 6 */ ist30xx_enable_irq(ts_data); tsp_info("tsp panel vendor: %d\n", panel_vendor); return sprintf(buf, "%d\n", panel_vendor); }
/* /sys/class/factory/tsp/chip_name */ ssize_t factory_tsp_chip_name_show(struct device *dev, struct device_attribute *attr, char *buf) { int ret; ist30xx_disable_irq(ts_data); ret = ist30xx_cmd_run_device(ts_data->client); if (ret) return sprintf(buf, "NULL"); ret = ist30xx_read_cmd(ts_data->client, CMD_GET_CHIP_ID, &ts_data->chip_id); if (ret) return sprintf(buf, "NULL"); ist30xx_enable_irq(ts_data); if ((ts_data->chip_id != IST30XX_CHIP_ID) && (ts_data->chip_id != IST30XXA_CHIP_ID)) return sprintf(buf, "NULL"); tsp_info("tsp chip name: %s\n", IST30XX_CHIP_NAME); return sprintf(buf, "%s\n", IST30XX_CHIP_NAME); }
ssize_t factory_tkey_zvalue_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int ret; int cmd = 0; u32 val = 0; sscanf(buf, "%d", &cmd); DMSG("[TSP] tkey zvalue cmd(%d)\n", cmd); val = (cmd > 0 ? 0x00C80001 : 0); if (cmd) { ist30xx_disable_irq(ts_data); ist30xx_cmd_run_device(ts_data->client); ist30xx_enable_irq(ts_data); } ret = ist30xx_write_cmd(ts_data->client, CMD_ZVALUE_MODE, val); if (ret) { pr_err("[ TSP ] fail, zvalue mode enter(%d)\n", ret); return size; } get_zvalue_mode = (cmd > 0 ? true : false); DMSG("[TSP] tkey zvalue val: %x, cmd: %d\n", val, cmd); return size; }
static void fw_update_func(struct work_struct *work) { if ((ts_data == NULL) || (ts_data->client == NULL)) return; tsp_info("FW update function\n"); if (ist30xx_auto_bin_update(ts_data)) ist30xx_disable_irq(ts_data); }
int ist30xx_get_info(struct ist30xx_data *data) { int ret; u32 calib_msg; int retry = 0; ist30xx_tsp_info.finger_num = IST30XX_MAX_MT_FINGERS; mutex_lock(&ist30xx_mutex); ist30xx_disable_irq(data); RETRY : ret = ist30xx_write_cmd(data->client, CMD_RUN_DEVICE, 0); msleep(50); ret = ist30xx_get_ver_info(data); if(ret != 0) { if(retry++ < 10) { tsp_debug("ist30xx_get_info retry : %d \n", retry); ist30xx_ts_reset(); goto RETRY; } } ret = ist30xx_tsp_update_info(); ret = ist30xx_tkey_update_info(); ist30xx_print_info(); ret = ist30xx_read_cmd(ts_data->client, CMD_GET_CALIB_RESULT, &calib_msg); if (ret == 0) { tsp_info("calib status: 0x%08x\n", calib_msg); if ((calib_msg & CALIB_MSG_MASK) != CALIB_MSG_VALID || CALIB_TO_STATUS(calib_msg) > 0) { ist30xx_calibrate(IST30XX_FW_UPDATE_RETRY); ist30xx_cmd_run_device(data->client); } } ist30xx_start(ts_data); #if IST30XX_EVENT_MODE ktime_get_ts(&t_event); #endif data->status.calib = 0; ist30xx_enable_irq(data); mutex_unlock(&ist30xx_mutex); return ret; }
static void ist30xx_early_suspend(struct early_suspend *h) { struct ist30xx_data *data = container_of(h, struct ist30xx_data, early_suspend); mutex_lock(&ist30xx_mutex); ist30xx_disable_irq(data); ist30xx_internal_suspend(data); clear_input_data(data); mutex_unlock(&ist30xx_mutex); }
static int ist30xx_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct ist30xx_data *data = i2c_get_clientdata(client); tsp_debug("ist30xx_suspend \n"); mutex_lock(&ist30xx_mutex); ist30xx_disable_irq(data); ist30xx_internal_suspend(data); clear_input_data(data); mutex_unlock(&ist30xx_mutex); return 0; }
static void reset_work_func(struct work_struct *work) { if ((ts_data == NULL) || (ts_data->client == NULL)) return; tsp_info("Request reset function\n"); if ((ts_data->status.power == 1) && (ts_data->status.update != 1) && (ts_data->status.calib != 1)) { mutex_lock(&ist30xx_mutex); ist30xx_disable_irq(ts_data); clear_input_data(ts_data); ist30xx_cmd_run_device(ts_data->client); ist30xx_start(ts_data); ist30xx_enable_irq(ts_data); mutex_unlock(&ist30xx_mutex); } }
int ist30xx_init_touch_driver(struct ist30xx_data *data) { int ret = 0; mutex_lock(&ist30xx_mutex); ist30xx_disable_irq(data); ret = ist30xx_cmd_run_device(data->client); if (ret) goto init_touch_end; ret = ist30xx_get_ver_info(data); if (ret) goto init_touch_end; init_touch_end: ist30xx_start(data); ist30xx_enable_irq(data); mutex_unlock(&ist30xx_mutex); return ret; }
int ist30xx_cmcs_test(const u8 *buf, int size) { int ret; int len; u32 chksum = 0; u32 *buf32; struct i2c_client *client = (struct i2c_client *)ts_data->client; CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; tsp_info("*** CM/CS test ***\n"); tsp_info(" mode: 0x%x, baseline(screen: %d, key: %d)\n", cmcs->cmd.mode, cmcs->cmd.base_screen, cmcs->cmd.base_key); tsp_info(" start_cp (cm: %d, cs: %d), vcmp (cm: %d, cs: %d)\n", cmcs->cmd.start_cp_cm, cmcs->cmd.start_cp_cs, cmcs->cmd.vcmp_cm, cmcs->cmd.vcmp_cs); ist30xx_disable_irq(ts_data); ist30xx_reset(false); ret = ist30xx_cmd_reg(client, CMD_ENTER_REG_ACCESS); cmcs_next_step(ret); /* Set sensor register */ buf32 = ts_cmcs->buf_sensor; ret = ist30xx_set_cmcs_sensor(client, cmcs, buf32); cmcs_next_step(ret); /* Set command */ ret = ist30xx_set_cmcs_cmd(client, cmcs); cmcs_next_step(ret); ret = ist30xx_cmd_reg(client, CMD_EXIT_REG_ACCESS); cmcs_next_step(ret); /* Load cmcs test code */ ret = ist30xx_write_cmd(client, CMD_EXEC_MEM_CODE, 0); cmcs_next_step(ret); buf32 = (u32 *)ts_cmcs->buf_cmcs; len = cmcs->cmd.cmcs_size / IST30XX_DATA_LEN; tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); ret = ist30xx_write_buf(client, len, buf32, len); cmcs_next_step(ret); /* Check checksum */ ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); cmcs_next_step(ret); if (chksum != IST30XX_CMCS_LOAD_END) goto end; tsp_info("CM/CS code ready!!\n"); /* Check checksum */ ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); cmcs_next_step(ret); tsp_info("CM/CS code chksum: %08x, %08x\n", chksum, cmcs->cmcs_chksum); ist30xx_enable_irq(ts_data); /* Wait CMCS test result */ if (ist30xx_calib_wait() == 1) tsp_info("CM/CS test OK.\n"); else tsp_info("CM/CS test fail.\n"); ist30xx_disable_irq(ts_data); /* Read CM/CS data*/ if (ENABLE_CM_MODE(cmcs->cmd.mode)) { /* Read CM data */ memset(ts_cmcs_buf->cm, 0, sizeof(ts_cmcs_buf->cm)); ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cm); cmcs_next_step(ret); ret = ist30xx_apply_cmcs_slope(cmcs, ts_cmcs_buf); } if (ENABLE_CS_MODE(cmcs->cmd.mode)) { /* Read CS0 data */ memset(ts_cmcs_buf->cs0, 0, sizeof(ts_cmcs_buf->cs0)); memset(ts_cmcs_buf->cs1, 0, sizeof(ts_cmcs_buf->cs1)); ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cs0); cmcs_next_step(ret); /* Read CS1 data */ ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cs1); cmcs_next_step(ret); } ist30xx_reset(false); ist30xx_start(ts_data); cmcs_ready = CMCS_READY; end: if (unlikely(ret)) { tsp_warn("CM/CS test Fail!, ret=%d\n", ret); } else if (unlikely(chksum != cmcs->cmcs_chksum)) { tsp_warn("Error CheckSum: %x(%x)\n", chksum, cmcs->cmcs_chksum); ret = -ENOEXEC; } ist30xx_enable_irq(ts_data); return ret; }
int ist30xx_get_info(struct ist30xx_data *data) { int ret; u32 calib_msg; ist30xx_tsp_info.finger_num = IST30XX_MAX_MT_FINGERS; mutex_lock(&ist30xx_mutex); ist30xx_disable_irq(data); #if !(IST30XX_INTERNAL_BIN) ret = ist30xx_write_cmd(data->client, CMD_RUN_DEVICE, 0); if (ret) goto get_info_end; msleep(10); ret = ist30xx_get_ver_info(data); if (ret) goto get_info_end; #endif // !(IST30XX_INTERNAL_BIN) #if IST30XX_DEBUG # if IST30XX_INTERNAL_BIN ist30xx_get_tsp_info(); ist30xx_get_tkey_info(); # else ret = ist30xx_tsp_update_info(); if (ret) goto get_info_end; ret = ist30xx_tkey_update_info(); if (ret) goto get_info_end; # endif ist30xx_print_info(); #endif // IST30XX_DEBUG ret = ist30xx_read_cmd(ts_data->client, CMD_GET_CALIB_RESULT, &calib_msg); if (ret == 0) { tsp_info("calib status: 0x%08x\n", calib_msg); if ((calib_msg & CALIB_MSG_MASK) != CALIB_MSG_VALID || CALIB_TO_STATUS(calib_msg) > 0) { ist30xx_calibrate(IST30XX_FW_UPDATE_RETRY); ist30xx_cmd_run_device(data->client); } } ist30xx_start(ts_data); #if IST30XX_EVENT_MODE ktime_get_ts(&t_event); #endif data->status.calib = 0; #if !(IST30XX_INTERNAL_BIN) get_info_end: #endif if (ret == 0) ist30xx_enable_irq(data); else printk("[ TSP ] ist30xx_get_info return value : %d\n", ret); mutex_unlock(&ist30xx_mutex); return ret; }
static int __devinit ist30xx_probe(struct i2c_client * client, const struct i2c_device_id * id) { int ret; struct ist30xx_data *data; struct input_dev *input_dev; #if 0 /* [email protected] */ struct touch_platform_data *ts_pdata; // struct ist30xx_ts_device *dev; ts_pdata = client->dev.platform_data; // dev = &ist30xx_ts_dev; /* [email protected] */ #endif tsp_info("\n%s(), the i2c addr=0x%x \n", __func__, client->addr); /* dev->power = ts_pdata->power; dev->num_irq = ts_pdata->irq; dev->sda_gpio = ts_pdata->sda; dev->scl_gpio = ts_pdata->scl;*/ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { tsp_debug("failed to i2c functionality check"); ret = -ENODEV; goto err_check_functionality_failed; } data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->client = client; if(client->dev.of_node) { data->pdata = devm_kzalloc(&client->dev, sizeof(struct ist30xx_tsi_platform_data), GFP_KERNEL); if(!data->pdata) { tsp_debug("failed to allocate platform_data"); return -ENOMEM; } ret = ist30xx_parse_dt(&client->dev, data->pdata); if(ret) { tsp_debug("device tree parsing failed"); return ret; } } else { data->pdata = client->dev.platform_data; } ret = ist30xx_regulator_configure(data, true); if (ret < 0) { tsp_debug("Failed to configure regulators"); } ret = ist30xx_ldo_power_on(data, true); if (ret < 0) { tsp_debug("Failed to power on"); } input_dev = input_allocate_device(); if (!input_dev) { ret = -ENOMEM; tsp_err("%s(), input_allocate_device failed (%d)\n", __func__, ret); goto err_alloc_dev; } #if 0 DMSG("[ TSP ] irq : %d, scl : %d, sda : %d\n", client->irq, ts_pdata->scl, ts_pdata->sda); #endif data->num_fingers = IST30XX_MAX_MT_FINGERS; data->num_keys = IST30XX_MAX_MT_FINGERS; data->irq_enabled = 1; data->client = client; data->input_dev = input_dev; #if 0 /* [email protected] */ data->power = ts_pdata->power; /* [email protected] */ #endif i2c_set_clientdata(client, data); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) input_mt_init_slots(input_dev, IST30XX_MAX_MT_FINGERS); #endif input_dev->name = "ist30xx_ts_input"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; set_bit(EV_ABS, input_dev->evbit); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) set_bit(INPUT_PROP_DIRECT, input_dev->propbit); #endif input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, IST30XX_MAX_X, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, IST30XX_MAX_Y, 0, 0); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, IST30XX_MAX_W, 0, 0); #else input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, IST30XX_MAX_Z, 0, 0); input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, IST30XX_MAX_W, 0, 0); #endif #if IST30XX_USE_KEY { int i; set_bit(EV_KEY, input_dev->evbit); set_bit(EV_SYN, input_dev->evbit); for (i = 1; i < ARRAY_SIZE(ist30xx_key_code); i++) set_bit(ist30xx_key_code[i], input_dev->keybit); } #endif input_set_drvdata(input_dev, data); ret = input_register_device(input_dev); if (ret) { input_free_device(input_dev); goto err_reg_dev; } #if defined(CONFIG_FB) data->fb_notif.notifier_call = fb_notifier_callback; ret = fb_register_client(&data->fb_notif); if(ret) tsp_debug("Unable to register fb_notifier \n"); else tsp_debug("Register fb_notifier \n"); #elif defined(CONFIG_HAS_EARLYSUSPEND) data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; data->early_suspend.suspend = ist30xx_early_suspend; data->early_suspend.resume = ist30xx_late_resume; register_early_suspend(&data->early_suspend); #endif ts_data = data; ret = ist30xx_init_system(); if (ret) { dev_err(&client->dev, "chip initialization failed\n"); goto err_init_drv; } ret = ist30xx_init_update_sysfs(); if (ret) goto err_init_drv; #if IST30XX_DEBUG ret = ist30xx_init_misc_sysfs(); if (ret) goto err_init_drv; #endif # if IST30XX_FACTORY_TEST ret = ist30xx_init_factory_sysfs(); if (ret) goto err_init_drv; #endif #if IST30XX_TRACKING_MODE ret = ist30xx_init_tracking_sysfs(); if (ret) goto err_init_drv; #endif ret = request_threaded_irq(client->irq, NULL, ist30xx_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "ist30xx_ts", data); if (ret) goto err_irq; ist30xx_disable_irq(data); #if IST30XX_INTERNAL_BIN # if IST30XX_UPDATE_BY_WORKQUEUE INIT_DELAYED_WORK(&work_fw_update, fw_update_func); schedule_delayed_work(&work_fw_update, IST30XX_UPDATE_DELAY); # else ret = ist30xx_auto_bin_update(data); if (ret < 0) goto err_irq; # endif #endif // IST30XX_INTERNAL_BIN ret = ist30xx_get_info(data); tsp_info("Get info: %s\n", (ret == 0 ? "success" : "fail")); INIT_DELAYED_WORK(&work_reset_check, reset_work_func); #if IRQ_THREAD_WORK_QUEUE INIT_WORK(&work_irq_thread, irq_thread_func); #endif #if IST30XX_DETECT_TA ist30xx_ta_status = 0; #endif #if IST30XX_EVENT_MODE init_timer(&idle_timer); idle_timer.function = timer_handler; idle_timer.expires = jiffies_64 + (EVENT_TIMER_INTERVAL); mod_timer(&idle_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); ktime_get_ts(&t_event); #endif ist30xx_initialized = 1; return 0; err_irq: ist30xx_disable_irq(data); free_irq(client->irq, data); err_init_drv: #if IST30XX_EVENT_MODE get_event_mode = false; #endif tsp_err("Error, ist30xx init driver\n"); // ist30xx_power_off(); ist30xx_ts_off(); input_unregister_device(input_dev); return 0; err_reg_dev: err_alloc_dev: tsp_err("Error, ist30xx mem free\n"); kfree(data); err_check_functionality_failed: return 0; }