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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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); }
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); }
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(); }
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; }