예제 #1
0
static ssize_t rmi_f09_control_test2_store(struct device *dev,
				      struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct rmi_function_container *fc;
	struct rmi_fn_09_data *data;
	unsigned int new_low, new_high, new_diff;
	int result;

	fc = to_rmi_function_container(dev);
	data = fc->data;
	if (sscanf(buf, "%u %u %u", &new_low, &new_high, &new_diff) != 3) {
		dev_err(dev,
		"%s: Error - f09_control_test1_store has an "
		"invalid len.\n",
		__func__);
		return -EINVAL;
	}

	if (new_low < 0 || new_low > 1 || new_high < 0 || new_high > 1 ||
			new_diff < 0 || new_diff > 1) {
		dev_err(dev, "%s: Invalid f09_control_test2_diff bit %s.",
			__func__, buf);
		return -EINVAL;
	}
	data->control.test2_limit_low = new_low;
	data->control.test2_limit_high = new_high;
	data->control.test2_limit_diff = new_diff;
	result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
		data->control.test2_limit_low);
	if (result < 0) {
		dev_err(dev, "%s : Could not write f09_control_test2_limit_low to 0x%x\n",
				__func__, fc->fd.control_base_addr);
		return result;
	}

	result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
		data->control.test2_limit_high);
	if (result < 0) {
		dev_err(dev, "%s : Could not write f09_control_test2_limit_high to 0x%x\n",
				__func__, fc->fd.control_base_addr);
		return result;
	}

	result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
		data->control.test2_limit_diff);
	if (result < 0) {
		dev_err(dev, "%s : Could not write f09_control_test2_limit_diff to 0x%x\n",
				__func__, fc->fd.control_base_addr);
		return result;
	}

	return count;

}
예제 #2
0
static ssize_t rmi_f09_control_test2_store(struct device *dev,
				      struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct rmi_function_dev *fn_dev;
	struct rmi_fn_09_data *data;
	unsigned int new_low, new_high, new_diff;
	int result;

	fn_dev = to_rmi_function_dev(dev);
	data = fn_dev->data;
	if (sscanf(buf, "%u %u %u", &new_low, &new_high, &new_diff) != 3) {
		dev_err(dev, "f09_control_test1_store has an invalid len.\n");
		return -EINVAL;
	}

	// Should we take a look at rmi spec?
	/*if (new_low < 0 || new_low > 1 || new_high < 0 || new_high > 1 ||
			new_diff < 0 || new_diff > 1) {
		dev_err(dev, "Invalid f09_control_test2_diff bit %s.", buf);
		return -EINVAL;
	}*/
	data->control.test2_limit_low = new_low;
	data->control.test2_limit_high = new_high;
	data->control.test2_limit_diff = new_diff;
	result = rmi_write(fn_dev->rmi_dev, fn_dev->fd.control_base_addr,
		data->control.test2_limit_low);
	if (result < 0) {
		dev_err(dev, "Could not write f09_control_test2_limit_low to %#06x\n",
				fn_dev->fd.control_base_addr);
		return result;
	}

	result = rmi_write(fn_dev->rmi_dev, fn_dev->fd.control_base_addr,
		data->control.test2_limit_high);
	if (result < 0) {
		dev_err(dev, "Could not write f09_control_test2_limit_high to %#06x\n",
				fn_dev->fd.control_base_addr);
		return result;
	}

	result = rmi_write(fn_dev->rmi_dev, fn_dev->fd.control_base_addr,
		data->control.test2_limit_diff);
	if (result < 0) {
		dev_err(dev, "%s : Could not write f09_control_test2_limit_diff to 0x%x\n",
				__func__, fn_dev->fd.control_base_addr);
		return result;
	}

	return count;

}
예제 #3
0
파일: rmi_f01.c 프로젝트: unixphere/rmi4
int rmi_driver_f01_init(struct rmi_device *rmi_dev)
{
	struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev);
	int error;
	u8 temp;

	/* set F01_CONFIGURED bit */
	error = rmi_read(rmi_dev, data->f01_fd.control_base_addr, &temp);
	if (error < 0)
		return error;

	error = rmi_write(rmi_dev, data->f01_fd.control_base_addr,
			  temp | F01_CONFIGURED);
	if (error < 0)
		return error;

	/* enable irqs and then read them to clear them */
	error = rmi_write(rmi_dev, data->f01_fd.control_base_addr + 1, 0xff);
	if (error < 0)
		return error;

	error = rmi_read(rmi_dev, data->f01_fd.data_base_addr + 1, &temp);
	if (error < 0)
		return error;

	error = rmi_read(rmi_dev, data->f01_fd.query_base_addr,
		&data->manufacturer_id);
	if (error < 0)
		return error;

	error = rmi_read_block(rmi_dev, data->f01_fd.query_base_addr + 11,
		data->product_id, RMI_PRODUCT_ID_LENGTH);
	if (error != RMI_PRODUCT_ID_LENGTH)
		return error;

	data->product_id[RMI_PRODUCT_ID_LENGTH] = '\0';

	error = rmi_read(rmi_dev, data->f01_fd.data_base_addr,
		&temp);
	if (error < 0)
		return error;

	if (temp & F01_CONFIGURED) {
		dev_err(&rmi_dev->dev,
			"Device reset during configuration process!\n");
		return -EINVAL;
	}

	return 0;
}
예제 #4
0
static ssize_t f17_rezero_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf,
					 size_t count)
{
	struct rmi_function_container *fc;
	struct rmi_f17_device_data *data;
	unsigned int new_value;
	int len;

	fc = to_rmi_function_container(dev);
	data = fc->data;
	len = sscanf(buf, "%u", &new_value);
	if (new_value != 0 && new_value != 1) {
		dev_err(dev,
			"%s: Error - rezero is not a valid value 0x%x.\n",
			__func__, new_value);
		return -EINVAL;
	}
	data->commands.rezero = new_value;
	len = rmi_write(fc->rmi_dev, fc->fd.command_base_addr,
		data->commands.rezero);

	if (len < 0) {
		dev_err(dev, "%s : Could not write rezero to 0x%x\n",
				__func__, fc->fd.command_base_addr);
		return -EINVAL;
	}
	return count;
}
예제 #5
0
static ssize_t rmi_f09_run_bist_store(struct device *dev,
				      struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct rmi_function_container *fc;
	struct rmi_fn_09_data *data;
	unsigned int new_value;
	int result;

	fc = to_rmi_function_container(dev);
	data = fc->data;
	if (sscanf(buf, "%u", &new_value) != 1) {
		dev_err(dev,
		"%s: Error - run_bist_store has an "
		"invalid len.\n",
		__func__);
		return -EINVAL;
	}

	if (new_value < 0 || new_value > 1) {
		dev_err(dev, "%s: Invalid run_bist bit %s.", __func__, buf);
		return -EINVAL;
	}
	data->cmd.run_bist = new_value;
	result = rmi_write(fc->rmi_dev, fc->fd.command_base_addr,
		data->cmd.run_bist);
	if (result < 0) {
		dev_err(dev, "%s : Could not write run_bist_store to 0x%x\n",
				__func__, fc->fd.command_base_addr);
		return result;
	}

	return count;

}
예제 #6
0
static ssize_t rmi_f09_host_test_enable_store(struct device *dev,
					  struct device_attribute *attr,
					  const char *buf, size_t count)
{
	struct rmi_function_container *fc;
	struct rmi_fn_09_data *data;
	unsigned int new_value;
	int result;

	fc = to_rmi_function_container(dev);
	data = fc->data;
	if (sscanf(buf, "%u", &new_value) != 1) {
		dev_err(dev,
			"%s: Error - hostTestEnable has an invalid length.\n",
			__func__);
		return -EINVAL;
	}

	if (new_value < 0 || new_value > 1) {
		dev_err(dev, "%s: Invalid hostTestEnable bit %s.",
			__func__, buf);
		return -EINVAL;
	}
	data->query.host_test_enable = new_value;
	result = rmi_write(fc->rmi_dev, fc->fd.query_base_addr,
		data->query.host_test_enable);
	if (result < 0) {
		dev_err(dev, "%s: Could not write hostTestEnable to 0x%x\n",
				__func__, fc->fd.query_base_addr);
		return result;
	}

	return count;

}
예제 #7
0
static ssize_t rmi_f09_test_number_control_store(struct device *dev,
				      struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct rmi_function_dev *fn_dev;
	struct rmi_fn_09_data *data;
	unsigned int new_value;
	int result;

	fn_dev = to_rmi_function_dev(dev);
	data = fn_dev->data;
	if (sscanf(buf, "%u", &new_value) != 1) {
		dev_err(dev, "test_number_control_store has aninvalid len.\n");
		return -EINVAL;
	}

	if (new_value > 1) {
		dev_err(dev, "Invalid test_number_control bit %s.", buf);
		return -EINVAL;
	}
	data->data.test_number_control = new_value;
	result = rmi_write(fn_dev->rmi_dev, fn_dev->fd.control_base_addr,
		data->data.test_number_control);
	if (result < 0) {
		dev_err(dev, "Could not write test_number_control_store to %#06x\n",
				fn_dev->fd.data_base_addr);
		return result;
	}

	return count;
}
예제 #8
0
static ssize_t rmi_driver_bsr_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	int retval;
	unsigned long val;
	struct rmi_device *rmi_dev = to_rmi_device(dev);
	struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);

	/* need to convert the string data to an actual value */
	retval = strict_strtoul(buf, 10, &val);
	if (retval < 0 || val > 255) {
		dev_err(dev, "Invalid value '%s' written to BSR.\n", buf);
		return -EINVAL;
	}

	retval = rmi_write(rmi_dev, BSR_LOCATION, (u8)val);
	if (retval < 0) {
		dev_err(dev, "%s : failed to write bsr %lu to %#06x\n",
			__func__, val, BSR_LOCATION);
		return retval;
	}

	data->bsr = val;

	return count;
}
예제 #9
0
static int rmi_f34_command(struct f34_data *f34, u8 command,
			   unsigned int timeout, bool write_bl_id)
{
	struct rmi_function *fn = f34->fn;
	struct rmi_device *rmi_dev = fn->rmi_dev;
	int ret;

	if (write_bl_id) {
		ret = rmi_f34_write_bootloader_id(f34);
		if (ret)
			return ret;
	}

	init_completion(&f34->v5.cmd_done);

	ret = rmi_read(rmi_dev, f34->v5.ctrl_address, &f34->v5.status);
	if (ret) {
		dev_err(&f34->fn->dev,
			"%s: Failed to read cmd register: %d (command %#02x)\n",
			__func__, ret, command);
		return ret;
	}

	f34->v5.status |= command & 0x0f;

	ret = rmi_write(rmi_dev, f34->v5.ctrl_address, f34->v5.status);
	if (ret < 0) {
		dev_err(&f34->fn->dev,
			"Failed to write F34 command %#02x: %d\n",
			command, ret);
		return ret;
	}

	if (!wait_for_completion_timeout(&f34->v5.cmd_done,
				msecs_to_jiffies(timeout))) {

		ret = rmi_read(rmi_dev, f34->v5.ctrl_address, &f34->v5.status);
		if (ret) {
			dev_err(&f34->fn->dev,
				"%s: cmd %#02x timed out: %d\n",
				__func__, command, ret);
			return ret;
		}

		if (f34->v5.status & 0x7f) {
			dev_err(&f34->fn->dev,
				"%s: cmd %#02x timed out, status: %#02x\n",
				__func__, command, f34->v5.status);
			return -ETIMEDOUT;
		}
	}

	return 0;
}
예제 #10
0
파일: rmi_f01.c 프로젝트: unixphere/rmi4
int rmi_driver_f01_suspend(struct rmi_device *rmi_dev)
{
	struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev);
	u8 dev_control;
	int error;

	error = rmi_read(rmi_dev, data->f01_fd.control_base_addr,
			 &dev_control);
	if (error < 0)
		return error;

	dev_control = (dev_control & ~F01_SLEEP_MASK) | sensor_sleep;

	return rmi_write(rmi_dev, data->f01_fd.control_base_addr,
			 dev_control);
}
예제 #11
0
파일: rmi_f01.c 프로젝트: unixphere/rmi4
int rmi_driver_f01_resume(struct rmi_device *rmi_dev)
{
	struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev);
	u8 dev_control;
	int error;

	error = rmi_read(rmi_dev, data->f01_fd.control_base_addr,
			 &dev_control);
	if (error < 0)
		return error;

	dev_control = (dev_control & ~F01_SLEEP_MASK) | normal_operation;

	return rmi_write(rmi_dev, data->f01_fd.control_base_addr,
			 dev_control);
}
예제 #12
0
static void do_stop(struct f05_data *f05)
{
	struct rmi_function_container *fn_dev = f05->fn_dev;
	struct rmi_driver *driver = fn_dev->rmi_dev->driver;
	struct rmi_driver_data *driver_data;
	struct rmi_device_platform_data *pdata;
	struct rmi_function_container *f01_dev;
	int retval;

	driver_data = dev_get_drvdata(&fn_dev->rmi_dev->dev);
	pdata = to_rmi_platform_data(fn_dev->rmi_dev);
	f01_dev = driver_data->f01_container;

	mutex_lock(&f05->status_mutex);
	if (f05->status == F05_STATE_IDLE) {
		mutex_unlock(&f05->status_mutex);
		return;
	}
	set_status(f05, F05_STATE_IDLE);
	f05->data_ready = false;

	f05->dev_data.report_mode = 0;
	/* Write 0 to the Report Mode back to the first Block
		* Data registers. */
	retval = rmi_write_block(fn_dev->rmi_dev, fn_dev->fd.data_base_addr,
			(u8 *) &f05->dev_data, sizeof(f05->dev_data));
	if (retval < 0) {
		dev_warn(&fn_dev->dev, "%s : Could not write report mode to 0x%x\n",
			__func__, fn_dev->fd.data_base_addr);
	}

	mutex_unlock(&f05->status_mutex);

	driver->restore_irq_mask(fn_dev->rmi_dev);

	retval = rmi_write(fn_dev->rmi_dev, f01_dev->fd.command_base_addr,
			F01_RESET_MASK);
	if (retval < 0)
		dev_warn(&fn_dev->rmi_dev->dev,
				"WARNING - post-F05 reset failed, code: %d.\n",
				retval);
	msleep(pdata->reset_delay_ms);
}
예제 #13
0
void button_debug_screen(void)
{
    char product_id[RMI_PRODUCT_ID_LEN];
    rmi_read(RMI_PRODUCT_ID, RMI_PRODUCT_ID_LEN, product_id);
    int x_max = rmi_read_single(RMI_2D_SENSOR_XMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_XMAX_LSB(0));
    int y_max = rmi_read_single(RMI_2D_SENSOR_YMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_YMAX_LSB(0));
    int func_presence = rmi_read_single(RMI_FUNCTION_PRESENCE(RMI_2D_TOUCHPAD_FUNCTION));
    int sensor_prop = rmi_read_single(RMI_2D_SENSOR_PROP2(0));
    int sensor_resol = rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0));
    int min_dist = rmi_read_single(RMI_2D_MIN_DIST);
    int gesture_settings = rmi_read_single(RMI_2D_GESTURE_SETTINGS);
    union
    {
        unsigned char data;
        signed char value;
    }sensitivity;
    rmi_read(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data);

    /* Device to screen */
    int zone_w = LCD_WIDTH;
    int zone_h = (zone_w * y_max + x_max - 1) / x_max;
    int zone_x = 0;
    int zone_y = LCD_HEIGHT - zone_h;
    #define DX2SX(x) (((x) * zone_w ) / x_max)
    #define DY2SY(y) (zone_h - ((y) * zone_h ) / y_max)
    struct viewport report_vp;
    memset(&report_vp, 0, sizeof(report_vp));
    report_vp.x = zone_x;
    report_vp.y = zone_y;
    report_vp.width = zone_w;
    report_vp.height = zone_h;
    struct viewport gesture_vp;
    memset(&gesture_vp, 0, sizeof(gesture_vp));
    gesture_vp.x = 0;
    gesture_vp.y = zone_y - 80;
    gesture_vp.width = LCD_WIDTH;
    gesture_vp.height = 80;
    
    while(1)
    {
        lcd_set_viewport(NULL);
        lcd_clear_display();
        int btns = button_read_device();
        lcd_putsf(0, 0, "button bitmap: %x", btns);
        lcd_putsf(0, 1, "RMI: id=%s p=%x s=%x", product_id, func_presence, sensor_prop);
        lcd_putsf(0, 2, "xmax=%d ymax=%d res=%d", x_max, y_max, sensor_resol);
        lcd_putsf(0, 3, "attn=%d ctl=%x int=%x",
            imx233_get_gpio_input_mask(0, 0x08000000) ? 0 : 1,
            rmi_read_single(RMI_DEVICE_CONTROL),
            rmi_read_single(RMI_INTERRUPT_REQUEST));
        lcd_putsf(0, 4, "sensi: %d min_dist: %d", (int)sensitivity.value, min_dist);
        lcd_putsf(0, 5, "gesture: %x", gesture_settings);
        
        union
        {
            unsigned char data[10];
            struct
            {
                struct rmi_2d_absolute_data_t absolute;
                struct rmi_2d_relative_data_t relative;
                struct rmi_2d_gesture_data_t gesture;
            }s;
        }u;
        int absolute_x = u.s.absolute.x_msb << 8 | u.s.absolute.x_lsb;
        int absolute_y = u.s.absolute.y_msb << 8 | u.s.absolute.y_lsb;
        int nr_fingers = u.s.absolute.misc & 7;
        bool gesture = (u.s.absolute.misc & 8) == 8;
        int palm_width = u.s.absolute.misc >> 4;
        rmi_read(RMI_DATA_REGISTER(0), 10, u.data);
        lcd_putsf(0, 6, "abs: %d %d %d", absolute_x, absolute_y, (int)u.s.absolute.z);
        lcd_putsf(0, 7, "rel: %d %d", (int)u.s.relative.x, (int)u.s.relative.y);
        lcd_putsf(0, 8, "gesture: %x %x", u.s.gesture.misc, u.s.gesture.flick);
        lcd_putsf(0, 9, "misc: w=%d g=%d f=%d", palm_width, gesture, nr_fingers);

        lcd_set_viewport(&report_vp);
        lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0, 0), LCD_BLACK);
        lcd_drawrect(0, 0, zone_w, zone_h);
        if(nr_fingers == 1)
        {
            lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0, 0, 0xff), LCD_BLACK);
            lcd_drawline(DX2SX(absolute_x) - u.s.relative.x,
                DY2SY(absolute_y) + u.s.relative.y,
                DX2SX(absolute_x), DY2SY(absolute_y));
            lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0, 0xff, 0), LCD_BLACK);
            lcd_fillrect(DX2SX(absolute_x) - 1, DY2SY(absolute_y) - 1, 3, 3);
        }
        lcd_set_viewport(&gesture_vp);
        lcd_set_drawinfo(DRMODE_SOLID, LCD_RGBPACK(0xff, 0xff, 0), LCD_BLACK);
        if(u.s.gesture.misc & RMI_2D_GEST_MISC_CONFIRMED)
        {
            switch(u.s.gesture.misc & RMI_2D_GEST_MISC_TAP_CODE_BM)
            {
                case RMI_2D_GEST_MISC_NO_TAP: break;
                case RMI_2D_GEST_MISC_SINGLE_TAP:
                    lcd_putsf(0, 0, "TAP!");
                    break;
                case RMI_2D_GEST_MISC_DOUBLE_TAP:
                    lcd_putsf(0, 0, "DOUBLE TAP!");
                    break;
                case RMI_2D_GEST_MISC_TAP_AND_HOLD:
                    lcd_putsf(0, 0, "TAP & HOLD!");
                    break;
                default: break;
            }
            
            if(u.s.gesture.misc & RMI_2D_GEST_MISC_FLICK)
            {
                lcd_putsf(0, 1, "FLICK!");
                int flick_x = u.s.gesture.flick & RMI_2D_GEST_FLICK_X_BM;
                int flick_y = (u.s.gesture.flick & RMI_2D_GEST_FLICK_Y_BM) >> RMI_2D_GEST_FLICK_Y_BP;
                #define SIGN4EXT(a) \
                    if(a & 8) a = -((a ^ 0xf) + 1);
                SIGN4EXT(flick_x);
                SIGN4EXT(flick_y);
                
                int center_x = (LCD_WIDTH * 2) / 3;
                int center_y = 40;
                lcd_drawline(center_x, center_y, center_x + flick_x * 5, center_y - flick_y * 5);
            }
        }
        lcd_update();
        
        if(btns & BUTTON_POWER)
            break;
        if(btns & BUTTON_VOL_DOWN || btns & BUTTON_VOL_UP)
        {
            if(btns & BUTTON_VOL_UP)
                sensitivity.value++;
            if(btns & BUTTON_VOL_DOWN)
                sensitivity.value--;
            rmi_write(RMI_2D_SENSITIVITY_ADJ, 1, &sensitivity.data);
        }
        
        yield();
    }
예제 #14
0
static ssize_t rmi_fn_34_cmd_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf,
				size_t count)
{
	struct rmi_function_dev *fn_dev;
	struct rmi_fn_34_data *instance_data;
	unsigned long val;
	u16 data_base_addr;
	int error;

	fn_dev = to_rmi_function_dev(dev);
	instance_data = fn_dev->data;
	data_base_addr = fn_dev->fd.data_base_addr;

	/* need to convert the string data to an actual value */
	error = strict_strtoul(buf, 10, &val);
	if (error)
		return error;

	/* make sure we are in Flash Prog mode for all cmds except the
	 * Enable Flash Programming cmd - otherwise we are in error */
	if ((val != F34_ENABLE_FLASH_PROG) && !instance_data->inflashprogmode) {
		dev_err(dev, "Cannot send command to sensor - not in flash programming mode.\n");
		return -EINVAL;
	}

	instance_data->cmd = val;

	/* Validate command value and (if necessary) write it to the command
	 * register.
	 */
	switch (instance_data->cmd) {
	case F34_ENABLE_FLASH_PROG:
	case F34_ERASE_ALL:
	case F34_ERASE_CONFIG:
	case F34_WRITE_FW_BLOCK:
	case F34_READ_CONFIG_BLOCK:
	case F34_WRITE_CONFIG_BLOCK:
	case F34_READ_SENSOR_ID:
		/* Reset the status to indicate we are in progress on a cmd. */
		/* The status will change when the ATTN interrupt happens
		   and the status of the cmd that was issued is read from
		   the F34_Flash_Data3 register - result should be 0x80 for
		   success - any other value indicates an error */

		/* Issue the command to the device. */
		error = rmi_write(fn_dev->rmi_dev,
				data_base_addr + instance_data->blocksize +
				BLK_NUM_OFF, instance_data->cmd);

		if (error < 0) {
			dev_err(dev, "Could not write command %#04x to %#06x\n",
				instance_data->cmd,
				data_base_addr + instance_data->blocksize +
				BLK_NUM_OFF);
			return error;
		}

		if (instance_data->cmd == F34_ENABLE_FLASH_PROG)
			instance_data->inflashprogmode = true;

		/* set status to indicate we are in progress */
		instance_data->status = F34_STATUS_IN_PROGRESS;
		break;
	default:
		dev_dbg(dev, "RMI4 F34 - unknown command 0x%02lx.\n", val);
		count = -EINVAL;
		break;
	}

	return count;
}