void timer_handler(unsigned long data) { int event_ms; int curr_ms; if (get_event_mode) { if ((ts_data->status.power == 1) && (ts_data->status.update != 1)) { ktime_get_ts(&t_current); curr_ms = t_current.tv_sec * 1000 + t_current.tv_nsec / 1000000; event_ms = t_event.tv_sec * 1000 + t_event.tv_nsec / 1000000; tsp_verb("event_ms %d, current: %d\n", event_ms, curr_ms); if (ts_data->status.calib == 1) { if (curr_ms - event_ms >= 2000) { // 2second ts_data->status.calib = 0; tsp_debug("calibration timeout over 3sec\n"); schedule_delayed_work(&work_reset_check, 0); ktime_get_ts(&t_event); } } #if IST30XX_NOISE_MODE else if (curr_ms - event_ms >= 5000) { // 5second tsp_warn("idle timeout over 5sec\n"); schedule_delayed_work(&work_reset_check, 0); } #endif // IST30XX_NOISE_MODE } } mod_timer(&idle_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); }
void print_tsp_event(finger_info *finger) { int idx = finger->bit_field.id - 1; int press = finger->bit_field.udmg & PRESS_MSG_MASK; if ( idx < 0 ) { tsp_err("finger idx err! idx value : %d\n", idx); return; } if (press == PRESS_MSG_MASK) { if (tsp_touched[idx] == 0) { // touch down tsp_info("%s - %d (%d, %d)\n", TOUCH_DOWN_MESSAGE, finger->bit_field.id, finger->bit_field.x, finger->bit_field.y); tsp_touched[idx] = 1; } else { // touch move tsp_debug("%s %d (%d, %d)\n", TOUCH_MOVE_MESSAGE, finger->bit_field.id, finger->bit_field.x, finger->bit_field.y); } } else { if (tsp_touched[idx] == 1) { // touch up tsp_info("%s - %d (%d, %d)\n", TOUCH_UP_MESSAGE, finger->bit_field.id, finger->bit_field.x, finger->bit_field.y); tsp_touched[idx] = 0; } } }
int print_cm_slope_result(struct ist30xx_data *data, u8 flag, s16 *buf16, char *buf) { int i, j; int type, idx; int count = 0, err_cnt = 0; int min_spec, max_spec; char msg[128]; CMCS_INFO *cmcs = (CMCS_INFO *)&data->cmcs->cmcs; struct CMCS_SLOPE_INFO *spec = (struct CMCS_SLOPE_INFO *)&cmcs->slope; if (flag == CMCS_FLAG_CM_SLOPE0) { min_spec = spec->x_min; max_spec = spec->x_max; } else if (flag == CMCS_FLAG_CM_SLOPE1) { min_spec = spec->y_min; max_spec = spec->y_max; } else { count = sprintf(msg, "Unknown flag: %d\n", flag); strcat(buf, msg); return count; } min_spec *= -1; tsp_debug("CS Slope Spec: %d ~ %d\n", min_spec, max_spec); for (i = 0; i < cmcs->ch.tx_num; i++) { for (j = 0; j < cmcs->ch.rx_num; j++) { idx = (i * cmcs->ch.rx_num) + j; type = check_tsp_type(data, i, j); if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) continue; // Ignore if ((buf16[idx] > min_spec) && (buf16[idx] < max_spec)) continue; // OK count += sprintf(msg, "%2d,%2d:%4d\n", i, j, buf16[idx]); strcat(buf, msg); err_cnt++; } } /* Check error count */ if (err_cnt == 0) count += sprintf(msg, "OK\n"); else count += sprintf(msg, "Fail, node count: %d\n", err_cnt); strcat(buf, msg); return count; }
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; }
int print_cs_result(struct ist30xx_data *data, s16 *buf16, char *buf, int cs_num) { int i, j; int type, idx; int count = 0, err_cnt = 0; int min_spec, max_spec; char msg[128]; CMCS_INFO *cmcs = (CMCS_INFO *)&data->cmcs->cmcs; struct CMCS_SPEC_INFO *spec; if (cs_num == 0) spec = (struct CMCS_SPEC_INFO *)&cmcs->spec_cs0; else spec = (struct CMCS_SPEC_INFO *)&cmcs->spec_cs1; tsp_debug("CS %d Spec: screen(%d~%d), key(%d~%d)\n", cs_num, spec->screen_min, spec->screen_max, spec->key_min, spec->key_max); for (i = 0; i < cmcs->ch.tx_num; i++) { for (j = 0; j < cmcs->ch.rx_num; j++) { idx = (i * cmcs->ch.rx_num) + j; type = check_tsp_type(data, i, j); if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) continue; // Ignore if (type == TSP_CH_SCREEN) { min_spec = spec->screen_min; max_spec = spec->screen_max; } else { // TSP_CH_KEY min_spec = spec->key_min; max_spec = spec->key_max; } if ((buf16[idx] > min_spec) && (buf16[idx] < max_spec)) continue; // OK count += sprintf(msg, "%2d,%2d:%4d\n", i, j, buf16[idx]); strcat(buf, msg); err_cnt++; } } /* Check error count */ if (err_cnt == 0) count += sprintf(msg, "OK\n"); else count += sprintf(msg, "Fail, node count: %d\n", err_cnt); strcat(buf, msg); return count; }
static void release_key(finger_info *key, u8 key_status) { int id = key->bit_field.id; input_report_key(ts_data->input_dev, ist30xx_key_code[id], key_status); tsp_debug("%s key%d, event: %d, status: %d\n", __func__, id, key->bit_field.w, key_status); key->bit_field.id = 0; input_sync(ts_data->input_dev); }
static int ist30xx_parse_dt(struct device *dev, struct ist30xx_tsi_platform_data *pdata) { struct device_node *np = dev->of_node; //struct property *prop; u32 temp_val;//, num_buttons; // u32 button_map[MAX_NUM_OF_BUTTON]; int rc; char propname[128]; strcpy(propname, "imagis,i2c-pull-up"); pdata->i2c_pull_up = of_property_read_bool(np, propname); tsp_debug("%s : %d \n", propname, pdata->i2c_pull_up); // x,y cordination strcpy(propname, "imagis,panel-x"); rc = of_property_read_u32(np, propname, &temp_val); if (rc && (rc != -EINVAL)) { return rc; } else { pdata->x_max = temp_val; } tsp_debug("%s :rc=%d val=%d \n", propname, rc, pdata->x_max); strcpy(propname, "imagis,panel-y"); rc = of_property_read_u32(np, propname, &temp_val); if (rc && (rc != -EINVAL)) { return rc; } else { pdata->y_max = temp_val; } tsp_debug("%s :rc=%d val=%d \n", propname, rc, pdata->y_max); strcpy(propname, "imagis,i2c_int_gpio"); pdata->i2c_int_gpio = of_get_named_gpio_flags(np, propname, 0, &pdata->irq_flag); //irq_flag active low or high tsp_debug("%s : i2c_int_gpio=%d flag=%d \n", propname, pdata->i2c_int_gpio, pdata->irq_flag); return 0; }
static int ist30xx_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct ist30xx_data *data = i2c_get_clientdata(client); tsp_debug("ist30xx_resume \n"); mutex_lock(&ist30xx_mutex); ist30xx_internal_resume(data); ist30xx_start(data); ist30xx_enable_irq(data); mutex_unlock(&ist30xx_mutex); return 0; }
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; }
void ist30xx_print_info(void) { TSP_INFO *tsp = &ist30xx_tsp_info; TKEY_INFO *tkey = &ist30xx_tkey_info; tsp_debug("tkey enable: %d, key num: %d\n", tkey->enable, tkey->key_num); tsp_debug("tkey axis_ch: %d, tx: %d\n", tkey->axis_chnum, tkey->tx_line); tsp_debug("tkey ch_num[0]: %d, [1]: %d, [2]: %d, [3]: %d, [4]: %d\n", tkey->ch_num[0], tkey->ch_num[1], tkey->ch_num[2], tkey->ch_num[3], tkey->ch_num[4]); tsp_debug("tscn internal x,y num: %d, %d\n", tsp->intl.x, tsp->intl.y); tsp_debug("tscn module x,y num: %d, %d\n", tsp->mod.x, tsp->mod.y); tsp_debug("tscn dir.txch_y: %d, swap: %d\n", tsp->dir.txch_y, tsp->dir.swap_xy); tsp_debug("tscn dir.flip_x, y: %d, %d\n", tsp->dir.flip_x, tsp->dir.flip_y); }
static void report_input_data(struct ist30xx_data *data, int finger_counts, int key_counts) { int i, press, count; finger_info *fingers = (finger_info *)data->fingers; memset(data->prev_fingers, 0, sizeof(data->prev_fingers)); #if 1 // for LGE scenario if (finger_counts) { for (i = 0; i < 5; i++) { //tsp_debug("finger[%d]: %08x\n", i, data->prev_keys[i].full_field); if (data->prev_keys[i].bit_field.id ==0) continue; if (data->prev_keys[i].bit_field.w == PRESS_MSG_KEY) { tsp_warn("key cancel: %08x\n", data->prev_keys[i].full_field); release_key(&data->prev_keys[i], CANCEL_KEY); } } } #endif for (i = 0, count = 0; i < finger_counts; i++) { press = fingers[i].bit_field.udmg & PRESS_MSG_MASK; //print_tsp_event(&fingers[i]); #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0)) input_mt_slot(data->input_dev, fingers[i].bit_field.id - 1); input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, (press ? true : false)); if (press) { input_report_abs(data->input_dev, ABS_MT_POSITION_X, fingers[i].bit_field.x); input_report_abs(data->input_dev, ABS_MT_POSITION_Y, fingers[i].bit_field.y); input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, fingers[i].bit_field.w); } printk("[ TSP ] id : %2d, press : %2d , x : %3d, y :%3d, width : %3d\n", fingers[i].bit_field.id - 1, press, fingers[i].bit_field.x, fingers[i].bit_field.y, fingers[i].bit_field.w); #else input_report_abs(data->input_dev, ABS_MT_POSITION_X, fingers[i].bit_field.x); input_report_abs(data->input_dev, ABS_MT_POSITION_Y, fingers[i].bit_field.y); input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, press); input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, fingers[i].bit_field.w); input_mt_sync(data->input_dev); #endif // (LINUX_VERSION_CODE > KERNEL_VERSION(3, 0, 0) data->prev_fingers[i] = fingers[i]; count++; } #if IST30XX_USE_KEY for (i = finger_counts; i < finger_counts + key_counts; i++) { key_id = fingers[i].bit_field.id; key_press = (fingers[i].bit_field.w == PRESS_MSG_KEY) ? 1 : 0; if (finger_on_screen()) { // Ignore touch key tsp_warn("Ignore key id: %d\n", key_id); continue; } tsp_debug("key(%08x) id: %d, press: %d, sensitivity: %d\n", fingers[i].full_field, key_id, key_press, fingers[i].bit_field.y); input_report_key(data->input_dev, ist30xx_key_code[key_id], key_press); data->prev_keys[key_id-1] = fingers[i]; count++; } #endif // IST30XX_USE_KEY if (count > 0) input_sync(data->input_dev); data->num_fingers = finger_counts; ist30xx_error_cnt = 0; }
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; }
static int ist30xx_regulator_configure(struct ist30xx_data *ts, bool on) { int retval; if (on == true) { tsp_debug("ist30xx_regulator_configure : On \n"); } else { tsp_debug("ist30xx_regulator_configure : Off \n"); } if (on == false) goto hw_shutdown; ts->vdd = regulator_get(&ts->client->dev, "vdd"); if (IS_ERR(ts->vdd)) { tsp_debug("Failed to get vdd regulator \n"); return PTR_ERR(ts->vdd); } if (regulator_count_voltages(ts->vdd) > 0) { tsp_debug("regulator_set_voltage(VDD L22, %d, %d) \n", IST30XX_VDD_VOLTAGE, IST30XX_VDD_VOLTAGE); retval = regulator_set_voltage(ts->vdd, IST30XX_VDD_VOLTAGE, IST30XX_VDD_VOLTAGE); if (retval) { tsp_debug("regulator set_vtg failed retval=%d \n", retval); goto err_set_vtg_vdd; } } if (ts->pdata->i2c_pull_up) { tsp_debug("this device has i2c_pull_up \n"); ts->vcc_i2c = regulator_get(&ts->client->dev, "vcc_i2c"); if (IS_ERR(ts->vcc_i2c)) { tsp_debug("Failed to get i2c regulator \n"); retval = PTR_ERR(ts->vcc_i2c); goto err_get_vtg_i2c; } if (regulator_count_voltages(ts->vcc_i2c) > 0) { tsp_debug("regulator_set_voltage(vcc_i2c, %d, %d) \n", IST30XX_I2C_VOLTAGE, IST30XX_I2C_VOLTAGE); retval = regulator_set_voltage(ts->vcc_i2c, IST30XX_I2C_VOLTAGE, IST30XX_I2C_VOLTAGE); if (retval) { tsp_debug("reg set i2c vtg failed retval=%d \n", retval); goto err_set_vtg_i2c; } } } tsp_debug("ist30xx_regulator_configure : On Done \n"); return 0; err_set_vtg_i2c: if (ts->pdata->i2c_pull_up) regulator_put(ts->vcc_i2c); err_get_vtg_i2c: if (regulator_count_voltages(ts->vdd) > 0) regulator_set_voltage(ts->vdd, 0, IST30XX_VDD_VOLTAGE); err_set_vtg_vdd: regulator_put(ts->vdd); tsp_debug("ist30xx_regulator_configure err \n"); return retval; hw_shutdown: if (regulator_count_voltages(ts->vdd) > 0) regulator_set_voltage(ts->vdd, 0, IST30XX_VDD_VOLTAGE); regulator_put(ts->vdd); if (ts->pdata->i2c_pull_up) { if (regulator_count_voltages(ts->vcc_i2c) > 0) regulator_set_voltage(ts->vcc_i2c, 0, IST30XX_I2C_VOLTAGE); regulator_put(ts->vcc_i2c); } tsp_debug("ist30xx_regulator_configure : Off done \n"); return 0; }
static int ist30xx_ldo_power_on(struct ist30xx_data *ts, bool on) { int retval; if (on == true) { tsp_debug("ist30xx_ldo_power_on : On \n"); } else { tsp_debug("ist30xx_ldo_power_on : Off \n"); } if (on == false) goto power_off; retval = reg_set_optimum_mode_check(ts->vdd, 100000); if (retval < 0) { tsp_debug("Regulator vdd set opt failed retval = %d \n", retval); return retval; } retval = regulator_enable(ts->vdd); if (retval < 0) { tsp_debug("Regulator vdd enable failed retval = %d \n", retval); goto err_reg_en_vdd; } if (ts->pdata->i2c_pull_up) { retval = reg_set_optimum_mode_check(ts->vcc_i2c, 100000); if (retval < 0) { tsp_debug("Regulator vcc_i2c set opt failed retval = %d \n", retval); goto err_reg_opt_i2c; } retval = regulator_enable(ts->vcc_i2c); if (retval < 0) { tsp_debug("Regulator vcc_i2c enable failed retval = %d \n", retval); goto err_reg_en_vcc_i2c; } } tsp_debug("ist30xx_ldo_power_on On Done \n"); return 0; err_reg_en_vcc_i2c: reg_set_optimum_mode_check(ts->vdd, 0); err_reg_opt_i2c: regulator_disable(ts->vdd); err_reg_en_vdd: reg_set_optimum_mode_check(ts->vdd, 0); tsp_debug("ist30xx_ldo_power_on err \n"); return retval; power_off: reg_set_optimum_mode_check(ts->vdd, 0); regulator_disable(ts->vdd); if (ts->pdata->i2c_pull_up) { reg_set_optimum_mode_check(ts->vcc_i2c, 0); regulator_disable(ts->vcc_i2c); } tsp_debug("ist30xx_ldo_power_on : Off Done \n"); return 0; }
ssize_t ist30xx_cmcs_test_all_show(struct device *dev, struct device_attribute *attr, char *buf) { int ret; char* msg = NULL; struct ist30xx_data *data = dev_get_drvdata(dev); CMCS_INFO *cmcs = (CMCS_INFO *)&data->cmcs->cmcs; msg = kzalloc(sizeof(char) * 4096, GFP_KERNEL); if (!msg) { tsp_err("Memory allocation failed\n"); return 0; } /* CMCS Binary */ ret = ist30xx_load_cmcs_binary(data); if (unlikely(ret)) { kfree(msg); return sprintf(buf, "Binary loaded failed(%d).\n", data->cmcs_bin_size); } ist30xx_get_cmcs_info(data, data->cmcs_bin, data->cmcs_bin_size); mutex_lock(&data->ist30xx_mutex); ret = ist30xx_cmcs_test(data, data->cmcs_bin, data->cmcs_bin_size); mutex_unlock(&data->ist30xx_mutex); if (likely(data->cmcs_bin != NULL)) { kfree(data->cmcs_bin); data->cmcs_bin = NULL; data->cmcs_bin_size = 0; } if (ret == 0) { tsp_debug("CMCS Binary test passed!\n"); } else { kfree(msg); return sprintf(buf, "CMCS Binary test failed!\n"); } if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) { kfree(msg); return sprintf(buf, "CMCS not enabled!\n"); } /* CM Result */ memset(msg, 0, sizeof(msg)); ret = print_cm_result(data, msg); if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { tsp_debug("CM result test passed!\n"); } else { goto out; } /* CM Slope 0 Result */ memset(msg, 0, sizeof(msg)); ret = print_cm_slope_result(data, CMCS_FLAG_CM_SLOPE0, data->cmcs_buf->slope0, msg); if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { tsp_debug("CM Slope 0 test passed!\n"); } else { goto out; } /* CM Slope 1 Result */ memset(msg, 0, sizeof(msg)); ret = print_cm_slope_result(data, CMCS_FLAG_CM_SLOPE1, data->cmcs_buf->slope1, msg); if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { tsp_debug("CM Slope 1 test passed!\n"); } else { goto out; } /* CS 0 Result */ memset(msg, 0, sizeof(msg)); ret = print_cs_result(data, data->cmcs_buf->cs0, msg, 0); if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { tsp_debug("CS 0 test passed!\n"); } else { goto out; } /* CS 1 Result */ memset(msg, 0, sizeof(msg)); ret = print_cs_result(data, data->cmcs_buf->cs1, msg, 1); if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { tsp_debug("CS 1 test passed!\n"); } else { goto out; } out: ret = sprintf(buf, "%s", msg); kfree(msg); return ret; }