Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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;
	
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
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;
}