/**
 * tp_get_glove_func_obj - it is a common function,tp can call it to creat glove_func file node in /sys/touch_screen/
 *
 * @no input value
 *
 * This function is tp call it to creat glove_func file node in /sys/touch_screen/.
 *
 * The kobject of touch_glove_func_ts will be returned,notice it is static.
 */
struct kobject* tp_get_glove_func_obj(void)
{
	struct kobject *properties_kobj;
	
	properties_kobj = tp_get_touch_screen_obj();
	if( NULL == properties_kobj )
	{
		tp_log_err("%s: Error, get kobj failed!\n", __func__);
		return NULL;
	}
	
	if( NULL == touch_glove_func_ts )
	{
		touch_glove_func_ts = kobject_create_and_add("glove_func", properties_kobj);
		if (!touch_glove_func_ts)
		{
			tp_log_err("%s: create glove_func kobjetct error!\n", __func__);
			return NULL;
		}
		else
		{
			tp_log_debug("%s: create sys/touch_screen/glove_func successful!\n", __func__);
		}
	}
	else
	{
		tp_log_debug("%s: sys/touch_screen/glove_func already exist!\n", __func__);
	}

	return touch_glove_func_ts;
}
static ssize_t ft6x06_ftsgetprojectcode_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	ssize_t num_read_chars = 0;
	char projectcode[50]; 
	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
	tp_log_info("%s %d\n",__func__,__LINE__);
	memset(projectcode, 0, sizeof(projectcode));
	mutex_lock(&g_device_mutex);
	if(ft6x06_read_project_code(client, projectcode) < 0)
	{
		tp_log_debug("%s %d num_read_chars = %d\n",__func__,__LINE__,num_read_chars);
		num_read_chars = snprintf(buf, PAGE_SIZE, "get projcet code fail!\n");
		tp_log_debug("%s %d num_read_chars = %d\n",__func__,__LINE__,num_read_chars);
	}
	else
	{
		tp_log_debug("%s %d num_read_chars = %d\n",__func__,__LINE__,num_read_chars);
		num_read_chars = snprintf(buf, PAGE_SIZE, "projcet code = %s\n", projectcode);
		tp_log_debug("%s %d num_read_chars = %d\n",__func__,__LINE__,num_read_chars);
	}
	mutex_unlock(&g_device_mutex);
	return num_read_chars;
	
}
예제 #3
0
/* read xy_data for all current touches */
static int cyttsp4_xy_worker(struct cyttsp4_proximity_data *pd)
{
	struct device *dev = &pd->ttsp->dev;
	struct cyttsp4_sysinfo *si = pd->si;
	u8 num_cur_rec;
	u8 rep_len;
	u8 rep_stat;
	u8 tt_stat;
	int rc = 0;

	/*
	 * Get event data from cyttsp4 device.
	 * The event data includes all data
	 * for all active touches.
	 * Event data also includes button data
	 */
	rep_len = si->xy_mode[si->si_ofs.rep_ofs];
	rep_stat = si->xy_mode[si->si_ofs.rep_ofs + 1];
	tt_stat = si->xy_mode[si->si_ofs.tt_stat_ofs];

	num_cur_rec = GET_NUM_TOUCH_RECORDS(tt_stat);

	if (rep_len == 0 && num_cur_rec > 0) {
		tp_log_err("%s: report length error rep_len=%d num_rec=%d\n",
			   __func__, rep_len, num_cur_rec);
		goto cyttsp4_xy_worker_exit;
	}

	/* check any error conditions */
	if (IS_BAD_PKT(rep_stat)) {
		tp_log_debug("%s: Invalid buffer detected\n", __func__);
		rc = 0;
		goto cyttsp4_xy_worker_exit;
	}

	if (IS_LARGE_AREA(tt_stat))
		tp_log_debug("%s: Large area detected\n", __func__);

	if (num_cur_rec > si->si_ofs.max_tchs) {
		tp_log_err("%s: %s (n=%d c=%d)\n", __func__,
			   "too many tch; set to max tch",
			   num_cur_rec, si->si_ofs.max_tchs);
		num_cur_rec = si->si_ofs.max_tchs;
	}

	/* extract xy_data for all currently reported touches */
	tp_log_debug("%s: extract data num_cur_rec=%d\n", __func__,
		     num_cur_rec);
	if (num_cur_rec)
		cyttsp4_get_proximity_touch(pd, num_cur_rec);
	else
		cyttsp4_report_proximity(pd, false);

	tp_log_debug("%s: done\n", __func__);
	rc = 0;

cyttsp4_xy_worker_exit:
	return rc;
}
예제 #4
0
/*****************************************************************
Parameters    :  rmi4_data
                 read     
                 write    
Return        :  ok:0, error:-1
Description   :  init ESD parameter
*****************************************************************/
int synaptics_dsx_esd_init(struct synaptics_rmi4_data *rmi4_data, 
							synaptics_read read, synaptics_write write)
{
	if (NULL == rmi4_data || NULL == read || NULL == write) 
	{
		tp_log_err("%s %d:input parameter is NULL\n", __func__, __LINE__);
		return -1;
	}

	tp_log_debug("%s %d:synaptics esd init\n", __func__, __LINE__);
	g_rmi4_data = rmi4_data;
	synaptics_esd_read = read;
	
	INIT_DELAYED_WORK(&synaptics_dsx_esd.esd_work, synaptics_esd_work);
	
	synaptics_dsx_esd.esd_work_queue = 
				create_singlethread_workqueue("synaptics_esd_workqueue");
	if (!synaptics_dsx_esd.esd_work_queue)
	{
		tp_log_err("%s %d:synaptics esd workqueue alloc failed\n", __func__, __LINE__);
		return -1;
	}
	
	/* set esd check thread state */
	atomic_set(&(synaptics_dsx_esd.esd_check_status), ESD_CHECK_STOPED);
	atomic_set(&(synaptics_dsx_esd.irq_status), 0);
	return 0;
}
static int cyttsp4_debug_release(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_debug_data *dd = dev_get_drvdata(dev);
	int rc = 0;
	tp_log_debug( "%s\n", __func__);

	if (dev_get_drvdata(&ttsp->core->dev) == NULL) {
		tp_log_err( "%s: Unable to un-subscribe attention\n",
				__func__);
		goto cyttsp4_debug_release_exit;
	}

	/* Unsubscribe from attentions */
	cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_IRQ,
		cyttsp4_debug_op_attention, CY_MODE_OPERATIONAL);
	cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_IRQ,
		cyttsp4_debug_cat_attention, CY_MODE_CAT);
	cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_STARTUP,
		cyttsp4_debug_startup_attention, 0);

cyttsp4_debug_release_exit:
	pm_runtime_suspend(dev);
	pm_runtime_disable(dev);
	device_remove_file(dev, &dev_attr_int_count);
	dev_set_drvdata(dev, NULL);
	kfree(dd);

	return rc;
}
예제 #6
0
static int cyttsp4_proximity_release(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);

	tp_log_debug("%s\n", __func__);

	if (pd->input_device_registered) {
		/* Disable proximity sensing */
		mutex_lock(&pd->sysfs_lock);
		if (pd->enable_count)
			_cyttsp4_proximity_disable(pd, true);
		mutex_unlock(&pd->sysfs_lock);
		device_remove_file(dev, &dev_attr_enable);
		input_unregister_device(pd->input);
	} else {
		input_free_device(pd->input);
		cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_STARTUP,
					      cyttsp4_setup_input_attention, 0);
	}

	pm_runtime_suspend(dev);
	pm_runtime_disable(dev);

	dev_set_drvdata(dev, NULL);
	kfree(pd);
	return 0;
}
예제 #7
0
/*****************************************************************
Parameters    :  void
Return        :    
Description   :  set irq_handle flag, esd work will read ic
*****************************************************************/
void synaptics_dsx_esd_resume(void)
{
	int resume_count = atomic_read(&synaptics_dsx_esd.irq_status);
	atomic_set(&(synaptics_dsx_esd.irq_status), resume_count + 1);
	tp_log_debug("%s %d:synaptics esd check resume, count = %d\n", 
				__func__, __LINE__, resume_count + 1);
}
예제 #8
0
/*****************************************************************
Parameters    :  work
Return        :    
Description   :  check if is running
*****************************************************************/
static void synaptics_esd_work(struct work_struct *work)
{
	int i = 0;
	int ret = 0;
	unsigned char data = 0x00;
	
	tp_log_debug("%s %d:synaptics esd check is working\n", __func__, __LINE__);
	/* if irq is be handled, cancle esd check */
	ret = atomic_read(&(synaptics_dsx_esd.irq_status));
	if (ret != 0) 
	{
		tp_log_err("%s %d:synaptics ic is handle irq, count = %d.\n", 
					__func__, __LINE__, ret);
		goto exit;
	}

	/* read 3 times, if success, ic is working, if all 3 times read 
		fail, ic is dead */
	for (i = 0; i < SYNAPTICS_ESD_RETRY_TIMES; i++) 
	{
		ret = synaptics_esd_read(g_rmi4_data, SYNAPTICS_STATUS_REG, 
									&data, sizeof(data));
		if (ret > 0) 
		{
			break;
		}
	}

	if (ret <= 0 && i == SYNAPTICS_ESD_RETRY_TIMES)
	{
		tp_log_err("%s %d:synaptics ic is dead\n", __func__, __LINE__);
#ifdef CONFIG_HUAWEI_DSM
		synp_tp_report_dsm_err(DSM_TP_ESD_ERROR_NO, ret);
#endif/*CONFIG_HUAWEI_DSM*/
		synaptics_dsx_hardware_reset(g_rmi4_data);
	}
	else
	{
		tp_log_info("%s %d:synaptics ic is working\n", __func__, __LINE__);
	}

exit:

	tp_log_debug("%s %d:synaptics data = %d\n", __func__, __LINE__, data);
	queue_delayed_work(synaptics_dsx_esd.esd_work_queue, &synaptics_dsx_esd.esd_work, msecs_to_jiffies(SYNAPTICS_ESD_CHECK_TIME));
}
예제 #9
0
static int _cyttsp4_proximity_enable(struct cyttsp4_proximity_data *pd)
{
	struct cyttsp4_device *ttsp = pd->ttsp;
	struct device *dev = &ttsp->dev;
	int rc = 0;

	tp_log_debug("%s\n", __func__);

	/* We use pm_runtime_get_sync to activate
	 * the core device until it is disabled back
	 */
	pm_runtime_get_sync(dev);

	rc = cyttsp4_request_exclusive(ttsp,
				       CY_PROXIMITY_REQUEST_EXCLUSIVE_TIMEOUT);
	if (rc < 0) {
		tp_log_err("%s: Error on request exclusive r=%d\n",
			   __func__, rc);
		goto exit;
	}

	rc = cyttsp4_request_enable_scan_type(ttsp, CY_ST_PROXIMITY);
	if (rc < 0) {
		tp_log_err
		    ("%s: Error on request enable proximity scantype r=%d\n",
		     __func__, rc);
		goto exit_release;
	}

	tp_log_debug("%s: setup subscriptions\n", __func__);

	/* set up touch call back */
	cyttsp4_subscribe_attention(ttsp, CY_ATTEN_IRQ,
				    cyttsp4_proximity_attention,
				    CY_MODE_OPERATIONAL);

	/* set up startup call back */
	cyttsp4_subscribe_attention(ttsp, CY_ATTEN_STARTUP,
				    cyttsp4_startup_attention, 0);

exit_release:
	cyttsp4_release_exclusive(ttsp);
exit:
	return rc;
}
static int cyttsp4_debug_startup_attention(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_debug_data *dd = dev_get_drvdata(dev);

	tp_log_debug( "%s\n", __func__);

	dd->monitor.mntr_status = CY_MNTR_DISABLED;

	return 0;
}
static int __init cyttsp4_debug_init(void)
{
	int rc = 0;
	int i, j;

	/* Check for invalid or duplicate core_ids */
	for (i = 0; i < num_core_ids; i++) {
		if (!strlen(core_ids[i])) {
			tp_log_err("%s: core_id %d is empty\n",
				__func__, i+1);
			return -EINVAL;
		}
		for (j = i+1; j < num_core_ids; j++)
			if (!strcmp(core_ids[i], core_ids[j])) {
				tp_log_err("%s: core_ids %d and %d are same\n",
					__func__, i+1, j+1);
				return -EINVAL;
			}
	}

	for (i = 0; i < num_core_ids; i++) {
		cyttsp4_debug_infos[i].name = cyttsp4_debug_name;
		cyttsp4_debug_infos[i].core_id = core_ids[i];
		cyttsp4_debug_infos[i].platform_data =
			&_cyttsp4_debug_platform_data;
		tp_log_debug("%s: Registering debug device for core_id: %s\n",
			__func__, cyttsp4_debug_infos[i].core_id);
		rc = cyttsp4_register_device(&cyttsp4_debug_infos[i]);
		if (rc < 0) {
			tp_log_err("%s: Error, failed registering device\n",
				__func__);
			goto fail_unregister_devices;
		}
	}
	rc = cyttsp4_register_driver(&cyttsp4_debug_driver);
	if (rc) {
		tp_log_err("%s: Error, failed registering driver\n", __func__);
		goto fail_unregister_devices;
	}

	tp_log_info("%s: Cypress TTSP Debug (Built %s) rc=%d\n",
		 __func__, CY_DRIVER_DATE, rc);
	return 0;

fail_unregister_devices:
	for (i--; i >= 0; i--) {
		cyttsp4_unregister_device(cyttsp4_debug_infos[i].name,
			cyttsp4_debug_infos[i].core_id);
		tp_log_info("%s: Unregistering device access device for core_id: %s\n",
			__func__, cyttsp4_debug_infos[i].core_id);
	}
	return rc;
}
static int cyttsp4_debug_cat_attention(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_debug_data *dd = dev_get_drvdata(dev);
	struct cyttsp4_sysinfo *si = dd->si;
	u8 cat_masked_cmd;

	tp_log_debug( "%s\n", __func__);

	/* Check for CaT command executed */
	cat_masked_cmd = si->xy_mode[CY_REG_CAT_CMD] & CY_CMD_MASK;
	if (cat_masked_cmd == CY_CMD_CAT_START_SENSOR_DATA_MODE) {
		tp_log_debug( "%s: Sensor data mode enabled\n", __func__);
		dd->monitor.mntr_status = CY_MNTR_ENABLED;
	} else if (cat_masked_cmd == CY_CMD_CAT_STOP_SENSOR_DATA_MODE) {
		tp_log_debug( "%s: Sensor data mode disabled\n", __func__);
		dd->monitor.mntr_status = CY_MNTR_DISABLED;
	}

	return 0;
}
예제 #13
0
static int cyttsp4_proximity_attention(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);
	int rc = 0;

	tp_log_debug("%s\n", __func__);

	mutex_lock(&pd->report_lock);
	if (!pd->is_suspended) {
		/* core handles handshake */
		rc = cyttsp4_xy_worker(pd);
	} else {
		tp_log_debug("%s: Ignoring report while suspended\n", __func__);
	}
	mutex_unlock(&pd->report_lock);
	if (rc < 0)
		tp_log_err("%s: xy_worker error r=%d\n", __func__, rc);

	return rc;
}
예제 #14
0
static int cyttsp4_proximity_resume(struct device *dev)
{
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);

	tp_log_debug("%s\n", __func__);

	mutex_lock(&pd->report_lock);
	pd->is_suspended = false;
	mutex_unlock(&pd->report_lock);

	return 0;
}
예제 #15
0
static int cyttsp4_setup_input_device_and_sysfs(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);
	int signal = CY_IGNORE_VALUE;
	int min, max;
	int i;
	int rc;

	rc = device_create_file(dev, &dev_attr_enable);
	if (rc) {
		tp_log_err("%s: Error, could not create enable\n", __func__);
		goto exit;
	}

	tp_log_debug("%s: Initialize event signals\n", __func__);

	__set_bit(EV_ABS, pd->input->evbit);

	for (i = 0; i < (pd->pdata->frmwrk->size / CY_NUM_ABS_SET); i++) {
		signal = pd->pdata->frmwrk->abs
		    [(i * CY_NUM_ABS_SET) + CY_SIGNAL_OST];
		if (signal != CY_IGNORE_VALUE) {
			min = pd->pdata->frmwrk->abs
			    [(i * CY_NUM_ABS_SET) + CY_MIN_OST];
			max = pd->pdata->frmwrk->abs
			    [(i * CY_NUM_ABS_SET) + CY_MAX_OST];
			input_set_abs_params(pd->input, signal, min, max,
					     pd->pdata->frmwrk->abs
					     [(i * CY_NUM_ABS_SET) +
					      CY_FUZZ_OST],
					     pd->pdata->frmwrk->
					     abs[(i * CY_NUM_ABS_SET) +
						 CY_FLAT_OST]);
		}
	}

	rc = input_register_device(pd->input);
	if (rc) {
		tp_log_err("%s: Error, failed register input device r=%d\n",
			   __func__, rc);
		goto unregister_enable;
	}

	pd->input_device_registered = true;
	return rc;

unregister_enable:
	device_remove_file(dev, &dev_attr_enable);
exit:
	return rc;
}
/**
 * tp_get_touch_screen_obj - it is a common function,tp can call it to creat /sys/touch_screen file node
 *
 * @no input value
 *
 * This function is tp call it to creat /sys/touch_screen file node.
 *
 * The kobject of touch_screen_kobject_ts will be returned,notice it is static.
 */
struct kobject* tp_get_touch_screen_obj(void)
{
	if( NULL == touch_screen_kobject_ts )
	{
		touch_screen_kobject_ts = kobject_create_and_add("touch_screen", NULL);
		if (!touch_screen_kobject_ts)
		{
			tp_log_err("%s: create touch_screen kobjetct error!\n", __func__);
			return NULL;
		}
		else
		{
			tp_log_debug("%s: create sys/touch_screen successful!\n", __func__);
		}
	}
	else
	{
		tp_log_debug("%s: sys/touch_screen already exist!\n", __func__);
	}

	return touch_screen_kobject_ts;
}
int cyttsp4_detect(struct cyttsp4_core_platform_data *pdata,
		struct device *dev, cyttsp4_platform_read read)
{
	int retry = 3;
	int rc;
	char buf[1];

	while (retry--) {
		/* Perform reset, wait for 100 ms and perform read */
		tp_log_debug( "%s: Performing a reset\n", __func__);
		pdata->xres(pdata, dev);
		msleep(100);
		rc = read(dev, 0, buf, 1);
		if (!rc)
			return 0;

		tp_log_debug( "%s: Read unsuccessful, try=%d\n",
			__func__, 3 - retry);
	}

	return rc;
}
예제 #18
0
static int cyttsp4_startup_attention(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);

	tp_log_debug("%s\n", __func__);

	mutex_lock(&pd->report_lock);
	cyttsp4_report_proximity(pd, false);
	mutex_unlock(&pd->report_lock);

	return 0;
}
/**
 * tp_get_virtual_key_obj - it is a common function,tp can call it to creat virtual_key file node in /sys/
 *
 * @no input value
 *
 * This function is tp call it to creat virtual_key file node in /sys/
 *
 * The kobject of virtual_key_kobject_ts will be returned
 */
struct kobject* tp_get_virtual_key_obj(char *name)
{
	if( NULL == virtual_key_kobject_ts )
	{
		virtual_key_kobject_ts = kobject_create_and_add(name, NULL);
		if (!virtual_key_kobject_ts)
		{
			tp_log_err("%s: create virtual_key kobjetct error!\n", __func__);
			return NULL;
		}
		else
		{
			tp_log_debug("%s: create virtual_key successful!\n", __func__);
		}
	}
	else
	{
		tp_log_debug("%s: virtual_key already exist!\n", __func__);
	}

	return virtual_key_kobject_ts;
}
static int cyttsp4_debug_op_attention(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_debug_data *dd = dev_get_drvdata(dev);
	int rc = 0;

	tp_log_debug( "%s\n", __func__);

	/* core handles handshake */
	rc = cyttsp4_xy_worker(dd);
	if (rc < 0)
		tp_log_err( "%s: xy_worker error r=%d\n", __func__, rc);

	return rc;
}
int cyttsp4_xres(struct cyttsp4_core_platform_data *pdata,
		struct device *dev)
{
	int rst_gpio = pdata->rst_gpio;
	int rc = 0;

	gpio_set_value(rst_gpio, 1);
	msleep(20);
	gpio_set_value(rst_gpio, 0);
	msleep(40);
	gpio_set_value(rst_gpio, 1);
	msleep(20);
	tp_log_debug(
		"%s: RESET CYTTSP gpio=%d r=%d\n", __func__,
		pdata->rst_gpio, rc);
	return rc;
}
예제 #22
0
static ssize_t cyttsp4_proximity_enable_store(struct device *dev,
					      struct device_attribute *attr,
					      const char *buf, u32 size)
{
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);
	unsigned long value;
	int rc;

	rc = kstrtoul(buf, 10, &value);
	if (rc < 0 || (value != 0 && value != 1)) {
		tp_log_err("%s: Invalid value\n", __func__);
		return -EINVAL;
	}

	mutex_lock(&pd->sysfs_lock);
	if (value) {
		if (pd->enable_count++) {
			tp_log_debug("%s: '%s' already enabled\n", __func__,
				     pd->ttsp->name);
		} else {
			rc = _cyttsp4_proximity_enable(pd);
			if (rc)
				pd->enable_count--;
		}
	} else {
		if (--pd->enable_count) {
			if (pd->enable_count < 0) {
				tp_log_err("%s: '%s' unbalanced disable\n",
					   __func__, pd->ttsp->name);
				pd->enable_count = 0;
			}
		} else {
			rc = _cyttsp4_proximity_disable(pd, false);
			if (rc)
				pd->enable_count++;
		}
	}
	mutex_unlock(&pd->sysfs_lock);

	if (rc)
		return rc;

	return size;
}
예제 #23
0
static int cyttsp4_setup_input_attention(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_proximity_data *pd = dev_get_drvdata(dev);
	int rc;

	tp_log_debug("%s\n", __func__);

	pd->si = cyttsp4_request_sysinfo(ttsp);
	if (!pd->si)
		return -EINVAL;

	rc = cyttsp4_setup_input_device_and_sysfs(ttsp);

	cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_STARTUP,
				      cyttsp4_setup_input_attention, 0);

	return rc;
}
예제 #24
0
/*
*ft6x06_i2c_Read-read data and write data by i2c
*@client: handle of i2c
*@writebuf: Data that will be written to the slave
*@writelen: How many bytes to write
*@readbuf: Where to store data read from slave
*@readlen: How many bytes to read
*
*Returns negative errno, else the number of messages executed
*
*
*/
int ft6x06_i2c_Read(struct i2c_client *client, char *writebuf,
		    int writelen, char *readbuf, int readlen)
{
	int ret;
	tp_log_debug("in ft6x06_i2c_Read\n");
	if (writelen > 0) {
		struct i2c_msg msgs[] = {
			{
			 .addr = client->addr,
			 .flags = 0,
			 .len = writelen,
			 .buf = writebuf,
			 },
			{
			 .addr = client->addr,
			 .flags = I2C_M_RD,
			 .len = readlen,
			 .buf = readbuf,
			 },
		};
예제 #25
0
static int _cyttsp4_proximity_disable(struct cyttsp4_proximity_data *pd,
				      bool force)
{
	struct cyttsp4_device *ttsp = pd->ttsp;
	struct device *dev = &ttsp->dev;
	int rc = 0;

	tp_log_debug("%s\n", __func__);

	rc = cyttsp4_request_exclusive(ttsp,
				       CY_PROXIMITY_REQUEST_EXCLUSIVE_TIMEOUT);
	if (rc < 0) {
		tp_log_err("%s: Error on request exclusive r=%d\n",
			   __func__, rc);
		goto exit;
	}

	rc = cyttsp4_request_disable_scan_type(ttsp, CY_ST_PROXIMITY);
	if (rc < 0) {
		tp_log_err("%s: Error on request disable proximity scan r=%d\n",
			   __func__, rc);
		goto exit_release;
	}

exit_release:
	cyttsp4_release_exclusive(ttsp);

exit:
	if (!rc || force) {
		cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_IRQ,
					      cyttsp4_proximity_attention,
					      CY_MODE_OPERATIONAL);

		cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_STARTUP,
					      cyttsp4_startup_attention, 0);

		pm_runtime_put(dev);
	}

	return rc;
}
static int ft6x06_read_project_code(struct i2c_client * client, char * pProjectCode)
{
	u8 reg_val[2] = {0};
	u32 i = 0;
	u32  j=0;
	u32  temp;
	u8 	packet_buf[4];
	u8  	auc_i2c_write_buf[10];
	int      i_ret;
	u8 is_5336_new_bootloader = 0;
	int rc =0;
	for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
    	/*********Step 1:Reset  CTPM *****/
    	/*write 0xaa to register 0xbc*/
	   	ft6x06_write_reg(client, 0xbc, FT_UPGRADE_AA);
		msleep(FT6X06_UPGRADE_AA_DELAY);
		
		 /*write 0x55 to register 0xbc*/
		ft6x06_write_reg(client, 0xbc, FT_UPGRADE_55);   
		msleep(FT6X06_UPGRADE_55_DELAY+20);   

		/*********Step 2:Enter upgrade mode *****/
		auc_i2c_write_buf[0] = FT_UPGRADE_55;
		auc_i2c_write_buf[1] = FT_UPGRADE_AA;
		do{
			j++;
	  	i_ret = ft6x06_i2c_Write(client, auc_i2c_write_buf, 2);
	  	msleep(5);
	  }while(i_ret <= 0 && j<5);
	    /*********Step 3:check READ-ID***********************/   
		msleep(FT6X06_UPGRADE_READID_DELAY);
	   	auc_i2c_write_buf[0] = 0x90; 
		auc_i2c_write_buf[1] = auc_i2c_write_buf[2] = auc_i2c_write_buf[3] = 0x00;

		rc = ft6x06_i2c_Read(client, auc_i2c_write_buf, 4, reg_val, 2);
		if(rc < 0)
			tp_log_err("error:%s,line=%d,rc=%d\n", __func__, __LINE__,rc);
		if (reg_val[0] == FT6X06_UPGRADE_ID_1 
			&& reg_val[1] == FT6X06_UPGRADE_ID_2)
		{
    		tp_log_debug("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]);
    		break;
		}
		else
		{
			tp_log_err("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]);
	    	continue;
		}
	}
	if (i >= FTS_UPGRADE_LOOP)
    {
		return -EIO;
	}
    
	auc_i2c_write_buf[0] = 0xcd;
	rc = ft6x06_i2c_Read(client, auc_i2c_write_buf, 1, reg_val, 1);
	if(rc < 0)
		tp_log_err("error:%s,line=%d,rc=%d\n", __func__, __LINE__,rc);
	if (reg_val[0] > 4)
		is_5336_new_bootloader = 1;

	tp_log_debug("bootloader version:%d\n", reg_val[0]);

	/*read project code*/

	packet_buf[0] = 0x03;
	packet_buf[1] = 0x00;
	for (j=0;j<33;j++)
	{
		if (is_5336_new_bootloader)
			temp = 0x07d0 + j;
		else
			temp = 0x7820 + j;
		packet_buf[2] = (u8)(temp>>8);
		packet_buf[3] = (u8)temp;

		rc = ft6x06_i2c_Read(client, packet_buf, sizeof(packet_buf), pProjectCode+j, 1);
		if(rc < 0)
			tp_log_err("error:%s,line=%d,rc=%d\n", __func__, __LINE__,rc);
		if (*(pProjectCode+j) == '\0')
			break;
		tp_log_debug("j = %d\n",j);
	}
	//if(strcmp(pProjectCode,"FTS0000P000") == 0)
	tp_log_debug("project code = %s \n", pProjectCode);
#if 1
	/*********reset the new FW***********************/
	tp_log_debug("%s %d\n",__func__,__LINE__);
	auc_i2c_write_buf[0] = 0x07;
	ft6x06_i2c_Write(client, auc_i2c_write_buf, 1);
	msleep(300);  /*make sure CTP startup normally*/
	tp_log_debug("%s %d\n",__func__,__LINE__);
#endif
	return 0;
}
예제 #27
0
static int cyttsp4_proximity_probe(struct cyttsp4_device *ttsp)
{
	struct cyttsp4_proximity_data *pd;
	struct device *dev = &ttsp->dev;
	struct cyttsp4_proximity_platform_data *pdata = dev_get_platdata(dev);
	int rc = 0;

	tp_log_info("%s\n", __func__);
	tp_log_debug("%s: debug on\n", __func__);
	tp_log_debug("%s: verbose debug on\n", __func__);

	if (pdata == NULL) {
		tp_log_err("%s: Missing platform data\n", __func__);
		rc = -ENODEV;
		goto error_no_pdata;
	}

	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
	if (pd == NULL) {
		tp_log_err("%s: Error, kzalloc\n", __func__);
		rc = -ENOMEM;
		goto error_alloc_data_failed;
	}

	mutex_init(&pd->report_lock);
	mutex_init(&pd->sysfs_lock);
	pd->ttsp = ttsp;
	pd->pdata = pdata;
	dev_set_drvdata(dev, pd);
	/* Create the input device and register it. */
	tp_log_debug("%s: Create the input device and register it\n", __func__);
	pd->input = input_allocate_device();
	if (pd->input == NULL) {
		tp_log_err("%s: Error, failed to allocate input device\n",
			   __func__);
		rc = -ENOSYS;
		goto error_alloc_failed;
	}

	pd->input->name = ttsp->name;
	scnprintf(pd->phys, sizeof(pd->phys) - 1, "%s", dev_name(dev));
	pd->input->phys = pd->phys;
	pd->input->dev.parent = &pd->ttsp->dev;
	input_set_drvdata(pd->input, pd);

	pm_runtime_enable(dev);

	/* get sysinfo */
	pd->si = cyttsp4_request_sysinfo(ttsp);
	if (pd->si) {
		rc = cyttsp4_setup_input_device_and_sysfs(ttsp);
		if (rc)
			goto error_init_input;
	} else {
		tp_log_err("%s: Fail get sysinfo pointer from core \n",
			   __func__);
		cyttsp4_subscribe_attention(ttsp, CY_ATTEN_STARTUP,
					    cyttsp4_setup_input_attention, 0);
	}

	tp_log_debug("%s: ok\n", __func__);
	return 0;

error_init_input:
	pm_runtime_suspend(dev);
	pm_runtime_disable(dev);
	input_free_device(pd->input);
error_alloc_failed:
	dev_set_drvdata(dev, NULL);
	kfree(pd);
error_alloc_data_failed:
error_no_pdata:
	tp_log_err("%s failed.\n", __func__);
	return rc;
}
ssize_t cyttsp5_dsm_record_basic_err_info(struct device *dev)
{
	ssize_t size = 0;
	ssize_t total_size = 0;
	struct cyttsp5_core_data *cd = dev_get_drvdata(dev);

	/* power status,include mode, is enable, voltage */
	if((cd->cpdata->power_config->vbus_type == CY_POWER_PMU)&&(cd->cpdata->power_config->vbus_reg)) {
		tp_log_debug("%s: record power!\n", __func__);
		size = dsm_client_record(tp_cyp_dclient,
					"[vbus power] mode:%d, enable:%d, vol:%d\n",
					regulator_get_mode(cd->cpdata->power_config->vbus_reg),
					regulator_is_enabled(cd->cpdata->power_config->vbus_reg),
					regulator_get_voltage(cd->cpdata->power_config->vbus_reg));

		total_size += size;

		tp_log_err("[vbus power] mode:%d, enable:%d, vol:%d\n",
					regulator_get_mode(cd->cpdata->power_config->vbus_reg),
					regulator_is_enabled(cd->cpdata->power_config->vbus_reg),
					regulator_get_voltage(cd->cpdata->power_config->vbus_reg));
	}

	if((cd->cpdata->power_config->vdd_type == CY_POWER_PMU)&&(cd->cpdata->power_config->vdd_reg)) {
		tp_log_debug("%s: record power!\n", __func__);
		size = dsm_client_record(tp_cyp_dclient,
					"[vdd power]  mode:%d, enable:%d, vol:%d\n",
					regulator_get_mode(cd->cpdata->power_config->vdd_reg),
					regulator_is_enabled(cd->cpdata->power_config->vdd_reg),
					regulator_get_voltage(cd->cpdata->power_config->vdd_reg));

		total_size += size;

		tp_log_err("[vdd power]  mode:%d, enable:%d, vol:%d\n",
					regulator_get_mode(cd->cpdata->power_config->vdd_reg),
					regulator_is_enabled(cd->cpdata->power_config->vdd_reg),
					regulator_get_voltage(cd->cpdata->power_config->vdd_reg));
	}

	if (cd->cpdata->power_config->vdd_type == CY_POWER_GPIO) {

		tp_log_debug("%s: record power!\n", __func__);
		size = dsm_client_record(tp_cyp_dclient,
				"[vdd power]  mode:%d, enable:%d\n",
				cd->cpdata->power_config->vdd_type,
				gpio_get_value(cd->cpdata->power_config->vdd_en_gpio));

		total_size += size;

		tp_log_err("[vdd power]  mode:%d, enable:%d\n",
					cd->cpdata->power_config->vdd_type,
					gpio_get_value(cd->cpdata->power_config->vdd_en_gpio));

	}

	if (cd->cpdata->power_config->vbus_type == CY_POWER_GPIO) {

		tp_log_debug("%s: record power!\n", __func__);
		size = dsm_client_record(tp_cyp_dclient,
				"[vdd power]  mode:%d, enable:%d\n",
				cd->cpdata->power_config->vdd_type,
				gpio_get_value(cd->cpdata->power_config->vbus_en_gpio));

		total_size += size;

		tp_log_err("[vdd power]  mode:%d, enable:%d\n",
					cd->cpdata->power_config->vdd_type,
					gpio_get_value(cd->cpdata->power_config->vbus_en_gpio));

	}

	/* record irq and reset gpio status */
	tp_log_debug("%s: record irq and reset gpio!\n", __func__);
	size = dsm_client_record(tp_cyp_dclient,
				"[irq gpio]   num:%d, irq gpio status:%d\n"
				"[reset gpio] num:%d, reset gpio status:%d\n",
				g_tp_dsm_info.irq_gpio, gpio_get_value(g_tp_dsm_info.irq_gpio),
				g_tp_dsm_info.rst_gpio, gpio_get_value(g_tp_dsm_info.rst_gpio));
	total_size += size;

	tp_log_err("[irq gpio]   num:%d, irq gpio status:%d\n"
				"[reset gpio] num:%d, reset gpio status:%d\n",
				g_tp_dsm_info.irq_gpio, gpio_get_value(g_tp_dsm_info.irq_gpio),
				g_tp_dsm_info.rst_gpio, gpio_get_value(g_tp_dsm_info.rst_gpio));

	return total_size;
}
/* read xy_data for all touches for debug */
static int cyttsp4_xy_worker(struct cyttsp4_debug_data *dd)
{
	struct device *dev = &dd->ttsp->dev;
	struct cyttsp4_sysinfo *si = dd->si;
	u8 tt_stat = si->xy_mode[si->si_ofs.tt_stat_ofs];
	u8 num_cur_rec = GET_NUM_TOUCH_RECORDS(tt_stat);
	uint32_t formated_output;
	int rc;

	mutex_lock(&dd->sysfs_lock);
	dd->interrupt_count++;
	formated_output = dd->formated_output;
	mutex_unlock(&dd->sysfs_lock);

	/* Read command parameters */
	rc = cyttsp4_read(dd->ttsp, CY_MODE_OPERATIONAL,
			si->si_ofs.cmd_ofs + 1,
			&si->xy_mode[si->si_ofs.cmd_ofs + 1],
			si->si_ofs.rep_ofs - si->si_ofs.cmd_ofs - 1);
	if (rc < 0) {
		tp_log_err( "%s: read fail on command parameter regs r=%d\n",
				__func__, rc);
	}

	if (si->si_ofs.num_btns > 0) {
		/* read button diff data */
		rc = cyttsp4_read(dd->ttsp, CY_MODE_OPERATIONAL,
				/*  replace with btn_diff_ofs when that field
				 *  becomes supported in the firmware */
				si->si_ofs.tt_stat_ofs + 1 +
				si->si_ofs.max_tchs * si->si_ofs.tch_rec_size,
				si->btn_rec_data,
				si->si_ofs.num_btns * si->si_ofs.btn_rec_size);
		if (rc < 0) {
			tp_log_err( "%s: read fail on button regs r=%d\n",
					__func__, rc);
		}
	}

	/* Interrupt */
#if 0//huawei 0701
	tp_log_info("Interrupt(%u)\n", dd->interrupt_count);
#endif //huawei 0701
	if (formated_output)
		cyttsp4_debug_formated(dev, dd->pr_buf, si, num_cur_rec);
	else
		/* print data for TTHE */
		cyttsp4_pr_buf_op_mode(dev, dd->pr_buf, si, num_cur_rec);

	if (dd->monitor.mntr_status == CY_MNTR_ENABLED) {
		int offset = (si->si_ofs.max_tchs * si->si_ofs.tch_rec_size)
				+ (si->si_ofs.num_btns
					* si->si_ofs.btn_rec_size)
				+ (si->si_ofs.tt_stat_ofs + 1);
		rc = cyttsp4_read(dd->ttsp, CY_MODE_OPERATIONAL,
				offset, &(dd->monitor.sensor_data[0]), 150);
		if (rc < 0)
			tp_log_err( "%s: read fail on sensor monitor regs r=%d\n",
					__func__, rc);
		/* print data for the sensor monitor */
		cyttsp4_debug_print(dev, dd->pr_buf, dd->monitor.sensor_data,
				150, "cyttsp4_sensor_monitor");
	}

#if 0//huawei 0701
	tp_log_info("\n");
#endif //huawei 0701
	tp_log_debug( "%s: done\n", __func__);

	return 0;
}
static int cyttsp4_debug_probe(struct cyttsp4_device *ttsp)
{
	struct device *dev = &ttsp->dev;
	struct cyttsp4_debug_data *dd;
	struct cyttsp4_debug_platform_data *pdata = dev_get_platdata(dev);
	int rc;

	tp_log_info( "%s: startup\n", __func__);
	tp_log_debug( "%s: debug on\n", __func__);
	tp_log_debug( "%s: verbose debug on\n", __func__);

	/* get context and debug print buffers */
	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
	if (dd == NULL) {
		tp_log_err( "%s: Error, kzalloc\n", __func__);
		rc = -ENOMEM;
		goto cyttsp4_debug_probe_alloc_failed;
	}

	rc = device_create_file(dev, &dev_attr_int_count);
	if (rc) {
		tp_log_err( "%s: Error, could not create int_count\n",
				__func__);
		goto cyttsp4_debug_probe_create_int_count_failed;
	}

	rc = device_create_file(dev, &dev_attr_formated_output);
	if (rc) {
		tp_log_err( "%s: Error, could not create formated_output\n",
				__func__);
		goto cyttsp4_debug_probe_create_formated_failed;
	}

	mutex_init(&dd->sysfs_lock);
	dd->ttsp = ttsp;
	dd->pdata = pdata;
	dev_set_drvdata(dev, dd);

	pm_runtime_enable(dev);

	dd->si = cyttsp4_request_sysinfo(ttsp);
	if (dd->si == NULL) {
		tp_log_err( "%s: Fail get sysinfo pointer from core\n",
				__func__);
		rc = -ENODEV;
		goto cyttsp4_debug_probe_sysinfo_failed;
	}

	rc = cyttsp4_subscribe_attention(ttsp, CY_ATTEN_IRQ,
		cyttsp4_debug_op_attention, CY_MODE_OPERATIONAL);
	if (rc < 0) {
		tp_log_err( "%s: Error, could not subscribe Operating mode attention cb\n",
				__func__);
		goto cyttsp4_debug_probe_subscribe_op_failed;
	}

	rc = cyttsp4_subscribe_attention(ttsp, CY_ATTEN_IRQ,
		cyttsp4_debug_cat_attention, CY_MODE_CAT);
	if (rc < 0) {
		tp_log_err( "%s: Error, could not subscribe CaT mode attention cb\n",
				__func__);
		goto cyttsp4_debug_probe_subscribe_cat_failed;
	}

	rc = cyttsp4_subscribe_attention(ttsp, CY_ATTEN_STARTUP,
		cyttsp4_debug_startup_attention, 0);
	if (rc < 0) {
		tp_log_err( "%s: Error, could not subscribe startup attention cb\n",
				__func__);
		goto cyttsp4_debug_probe_subscribe_startup_failed;
	}
	return 0;

cyttsp4_debug_probe_subscribe_startup_failed:
	cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_IRQ,
		cyttsp4_debug_cat_attention, CY_MODE_CAT);
cyttsp4_debug_probe_subscribe_cat_failed:
	cyttsp4_unsubscribe_attention(ttsp, CY_ATTEN_IRQ,
		cyttsp4_debug_op_attention, CY_MODE_OPERATIONAL);
cyttsp4_debug_probe_subscribe_op_failed:
cyttsp4_debug_probe_sysinfo_failed:
	pm_runtime_suspend(dev);
	pm_runtime_disable(dev);
	dev_set_drvdata(dev, NULL);
	device_remove_file(dev, &dev_attr_formated_output);
cyttsp4_debug_probe_create_formated_failed:
	device_remove_file(dev, &dev_attr_int_count);
cyttsp4_debug_probe_create_int_count_failed:
	kfree(dd);
cyttsp4_debug_probe_alloc_failed:
	tp_log_err( "%s failed.\n", __func__);
	return rc;
}