static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits) { struct f34_data *f34 = dev_get_drvdata(&fn->dev); int ret; u8 status; if (f34->bl_version == 5) { ret = rmi_read(f34->fn->rmi_dev, f34->v5.ctrl_address, &status); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n", __func__, status, ret); if (!ret && !(status & 0x7f)) complete(&f34->v5.cmd_done); } else { ret = rmi_read_block(f34->fn->rmi_dev, f34->fn->fd.data_base_addr + f34->v7.off.flash_status, &status, sizeof(status)); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n", __func__, status, ret); if (!ret && !(status & 0x1f)) complete(&f34->v7.cmd_done); } return 0; }
static int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw) { const struct rmi_f34_firmware *syn_fw = (const struct rmi_f34_firmware *)fw->data; u32 image_size = le32_to_cpu(syn_fw->image_size); u32 config_size = le32_to_cpu(syn_fw->config_size); int ret; BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) != F34_FW_IMAGE_OFFSET); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n", fw->size, le32_to_cpu(syn_fw->checksum), image_size, config_size); rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n", syn_fw->bootloader_version, (int)sizeof(syn_fw->product_id), syn_fw->product_id, syn_fw->product_info[0], syn_fw->product_info[1]); if (image_size && image_size != f34->v5.fw_blocks * f34->v5.block_size) { dev_err(&f34->fn->dev, "Bad firmware image: fw size %d, expected %d\n", image_size, f34->v5.fw_blocks * f34->v5.block_size); ret = -EILSEQ; goto out; } if (config_size && config_size != f34->v5.config_blocks * f34->v5.block_size) { dev_err(&f34->fn->dev, "Bad firmware image: config size %d, expected %d\n", config_size, f34->v5.config_blocks * f34->v5.block_size); ret = -EILSEQ; goto out; } if (image_size && !config_size) { dev_err(&f34->fn->dev, "Bad firmware image: no config data\n"); ret = -EILSEQ; goto out; } dev_info(&f34->fn->dev, "Firmware image OK\n"); mutex_lock(&f34->v5.flash_mutex); ret = rmi_f34_flash_firmware(f34, syn_fw); mutex_unlock(&f34->v5.flash_mutex); out: return ret; }
int rmi_register_function(struct rmi_function *fn) { struct rmi_device *rmi_dev = fn->rmi_dev; int error; device_initialize(&fn->dev); dev_set_name(&fn->dev, "%s.fn%02x", dev_name(&rmi_dev->dev), fn->fd.function_number); fn->dev.parent = &rmi_dev->dev; fn->dev.type = &rmi_function_type; fn->dev.bus = &rmi_bus_type; error = device_add(&fn->dev); if (error) { dev_err(&rmi_dev->dev, "Failed device_register function device %s\n", dev_name(&fn->dev)); goto err_put_device; } rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "Registered F%02X.\n", fn->fd.function_number); return 0; err_put_device: put_device(&fn->dev); return error; }
static int rmi_f34_write_bootloader_id(struct f34_data *f34) { struct rmi_function *fn = f34->fn; struct rmi_device *rmi_dev = fn->rmi_dev; u8 bootloader_id[F34_BOOTLOADER_ID_LEN]; int ret; ret = rmi_read_block(rmi_dev, fn->fd.query_base_addr, bootloader_id, sizeof(bootloader_id)); if (ret) { dev_err(&fn->dev, "%s: Reading bootloader ID failed: %d\n", __func__, ret); return ret; } rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: writing bootloader id '%c%c'\n", __func__, bootloader_id[0], bootloader_id[1]); ret = rmi_write_block(rmi_dev, fn->fd.data_base_addr + F34_BLOCK_DATA_OFFSET, bootloader_id, sizeof(bootloader_id)); if (ret) { dev_err(&fn->dev, "Failed to write bootloader ID: %d\n", ret); return ret; } return 0; }
static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits) { struct f30_data *f30 = dev_get_drvdata(&fn->dev); struct rmi_device *rmi_dev = fn->rmi_dev; struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); int retval; int gpiled = 0; int value = 0; int i; int reg_num; if (!f30->input) return 0; /* Read the gpi led data. */ if (drvdata->attn_data.data) { if (drvdata->attn_data.size < f30->register_count) { dev_warn(&fn->dev, "F30 interrupted, but data is missing\n"); return 0; } memcpy(f30->data_regs, drvdata->attn_data.data, f30->register_count); drvdata->attn_data.data += f30->register_count; drvdata->attn_data.size -= f30->register_count; } else { retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr, f30->data_regs, f30->register_count); if (retval) { dev_err(&fn->dev, "%s: Failed to read F30 data registers.\n", __func__); return retval; } } for (reg_num = 0; reg_num < f30->register_count; ++reg_num) { for (i = 0; gpiled < f30->gpioled_count && i < 8; ++i, ++gpiled) { if (f30->gpioled_key_map[gpiled] != 0) { /* buttons have pull up resistors */ value = (((f30->data_regs[reg_num] >> i) & 0x01) == 0); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: call input report key (0x%04x) value (0x%02x)", __func__, f30->gpioled_key_map[gpiled], value); input_report_key(f30->input, f30->gpioled_key_map[gpiled], value); } } }
static irqreturn_t rmi_spi_irq(int irq, void *dev_id) { struct rmi_spi_xport *rmi_spi = dev_id; struct rmi_device *rmi_dev = rmi_spi->xport.rmi_dev; int ret; ret = rmi_process_interrupt_requests(rmi_dev); if (ret) rmi_dbg(RMI_DEBUG_XPORT, &rmi_dev->dev, "Failed to process interrupt request: %d\n", ret); return IRQ_HANDLED; }
/* SMB block write - wrapper over ic2_smb_write_block */ static int smb_block_write(struct rmi_transport_dev *xport, u8 commandcode, const void *buf, size_t len) { struct rmi_smb_xport *rmi_smb = container_of(xport, struct rmi_smb_xport, xport); struct i2c_client *client = rmi_smb->client; int retval; retval = i2c_smbus_write_block_data(client, commandcode, len, buf); rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "wrote %zd bytes at %#04x: %d (%*ph)\n", len, commandcode, retval, (int)len, buf); return retval; }
static int rmi_f34_write_blocks(struct f34_data *f34, const void *data, int block_count, u8 command) { struct rmi_function *fn = f34->fn; struct rmi_device *rmi_dev = fn->rmi_dev; u16 address = fn->fd.data_base_addr + F34_BLOCK_DATA_OFFSET; u8 start_address[] = { 0, 0 }; int i; int ret; ret = rmi_write_block(rmi_dev, fn->fd.data_base_addr, start_address, sizeof(start_address)); if (ret) { dev_err(&fn->dev, "Failed to write initial zeros: %d\n", ret); return ret; } for (i = 0; i < block_count; i++) { ret = rmi_write_block(rmi_dev, address, data, f34->v5.block_size); if (ret) { dev_err(&fn->dev, "failed to write block #%d: %d\n", i, ret); return ret; } ret = rmi_f34_command(f34, command, F34_IDLE_WAIT_MS, false); if (ret) { dev_err(&fn->dev, "Failed to write command for block #%d: %d\n", i, ret); return ret; } rmi_dbg(RMI_DEBUG_FN, &fn->dev, "wrote block %d of %d\n", i + 1, block_count); data += f34->v5.block_size; f34->update_progress += f34->v5.block_size; f34->update_status = (f34->update_progress * 100) / f34->update_size; } return 0; }
/** * rmi_register_transport_device - register a transport device connection * on the RMI bus. Transport drivers provide communication from the devices * on a bus (such as SPI, I2C, and so on) to the RMI4 sensor. * * @xport: the transport device to register */ int rmi_register_transport_device(struct rmi_transport_dev *xport) { static atomic_t transport_device_count = ATOMIC_INIT(0); struct rmi_device *rmi_dev; int error; rmi_dev = kzalloc(sizeof(struct rmi_device), GFP_KERNEL); if (!rmi_dev) return -ENOMEM; device_initialize(&rmi_dev->dev); rmi_dev->xport = xport; rmi_dev->number = atomic_inc_return(&transport_device_count) - 1; dev_set_name(&rmi_dev->dev, "rmi4-%02d", rmi_dev->number); rmi_dev->dev.bus = &rmi_bus_type; rmi_dev->dev.type = &rmi_device_type; xport->rmi_dev = rmi_dev; error = device_add(&rmi_dev->dev); if (error) goto err_put_device; rmi_dbg(RMI_DEBUG_CORE, xport->dev, "%s: Registered %s as %s.\n", __func__, dev_name(rmi_dev->xport->dev), dev_name(&rmi_dev->dev)); return 0; err_put_device: put_device(&rmi_dev->dev); return error; }
static int rmi_f34_probe(struct rmi_function *fn) { struct f34_data *f34; unsigned char f34_queries[9]; bool has_config_id; u8 version = fn->fd.function_version; int ret; f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL); if (!f34) return -ENOMEM; f34->fn = fn; dev_set_drvdata(&fn->dev, f34); /* v5 code only supported version 0, try V7 probe */ if (version > 0) return rmi_f34v7_probe(f34); f34->bl_version = 5; ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, f34_queries, sizeof(f34_queries)); if (ret) { dev_err(&fn->dev, "%s: Failed to query properties\n", __func__); return ret; } snprintf(f34->bootloader_id, sizeof(f34->bootloader_id), "%c%c", f34_queries[0], f34_queries[1]); mutex_init(&f34->v5.flash_mutex); init_completion(&f34->v5.cmd_done); f34->v5.block_size = get_unaligned_le16(&f34_queries[3]); f34->v5.fw_blocks = get_unaligned_le16(&f34_queries[5]); f34->v5.config_blocks = get_unaligned_le16(&f34_queries[7]); f34->v5.ctrl_address = fn->fd.data_base_addr + F34_BLOCK_DATA_OFFSET + f34->v5.block_size; has_config_id = f34_queries[2] & (1 << 2); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Bootloader ID: %s\n", f34->bootloader_id); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Block size: %d\n", f34->v5.block_size); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "FW blocks: %d\n", f34->v5.fw_blocks); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "CFG blocks: %d\n", f34->v5.config_blocks); if (has_config_id) { ret = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr, f34_queries, sizeof(f34_queries)); if (ret) { dev_err(&fn->dev, "Failed to read F34 config ID\n"); return ret; } snprintf(f34->configuration_id, sizeof(f34->configuration_id), "%02x%02x%02x%02x", f34_queries[0], f34_queries[1], f34_queries[2], f34_queries[3]); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Configuration ID: %s\n", f34->configuration_id); } return 0; }
static int rmi_firmware_update(struct rmi_driver_data *data, const struct firmware *fw) { struct rmi_device *rmi_dev = data->rmi_dev; struct device *dev = &rmi_dev->dev; struct f34_data *f34; int ret; if (!data->f34_container) { dev_warn(dev, "%s: No F34 present!\n", __func__); return -EINVAL; } f34 = dev_get_drvdata(&data->f34_container->dev); if (f34->bl_version == 7) { if (data->pdt_props & HAS_BSR) { dev_err(dev, "%s: LTS not supported\n", __func__); return -ENODEV; } } else if (f34->bl_version != 5) { dev_warn(dev, "F34 V%d not supported!\n", data->f34_container->fd.function_version); return -ENODEV; } /* Enter flash mode */ if (f34->bl_version == 7) ret = rmi_f34v7_start_reflash(f34, fw); else ret = rmi_f34_enable_flash(f34); if (ret) return ret; rmi_disable_irq(rmi_dev, false); /* Tear down functions and re-probe */ rmi_free_function_list(rmi_dev); ret = rmi_probe_interrupts(data); if (ret) return ret; ret = rmi_init_functions(data); if (ret) return ret; if (!data->bootloader_mode || !data->f34_container) { dev_warn(dev, "%s: No F34 present or not in bootloader!\n", __func__); return -EINVAL; } rmi_enable_irq(rmi_dev, false); f34 = dev_get_drvdata(&data->f34_container->dev); /* Perform firmware update */ if (f34->bl_version == 7) ret = rmi_f34v7_do_reflash(f34, fw); else ret = rmi_f34_update_firmware(f34, fw); if (ret) { f34->update_status = ret; dev_err(&f34->fn->dev, "Firmware update failed, status: %d\n", ret); } else { dev_info(&f34->fn->dev, "Firmware update complete\n"); } rmi_disable_irq(rmi_dev, false); /* Re-probe */ rmi_dbg(RMI_DEBUG_FN, dev, "Re-probing device\n"); rmi_free_function_list(rmi_dev); ret = rmi_scan_pdt(rmi_dev, NULL, rmi_initial_reset); if (ret < 0) dev_warn(dev, "RMI reset failed!\n"); ret = rmi_probe_interrupts(data); if (ret) return ret; ret = rmi_init_functions(data); if (ret) return ret; rmi_enable_irq(rmi_dev, false); if (data->f01_container->dev.driver) /* Driver already bound, so enable ATTN now. */ return rmi_enable_sensor(rmi_dev); rmi_dbg(RMI_DEBUG_FN, dev, "%s complete\n", __func__); return ret; }
static int rmi_spi_xfer(struct rmi_spi_xport *rmi_spi, const struct rmi_spi_cmd *cmd, const u8 *tx_buf, int tx_len, u8 *rx_buf, int rx_len) { struct spi_device *spi = rmi_spi->spi; struct rmi_device_platform_data_spi *spi_data = &rmi_spi->xport.pdata.spi_data; struct spi_message msg; struct spi_transfer *xfer; int ret = 0; int len; int cmd_len = 0; int total_tx_len; int i; u16 addr = cmd->addr; spi_message_init(&msg); switch (cmd->op) { case RMI_SPI_WRITE: case RMI_SPI_READ: cmd_len += 2; break; case RMI_SPI_V2_READ_UNIFIED: case RMI_SPI_V2_READ_SPLIT: case RMI_SPI_V2_WRITE: cmd_len += 4; break; } total_tx_len = cmd_len + tx_len; len = max(total_tx_len, rx_len); if (len > RMI_SPI_XFER_SIZE_LIMIT) return -EINVAL; if (rmi_spi->xfer_buf_size < len) rmi_spi_manage_pools(rmi_spi, len); if (addr == 0) /* * SPI needs an address. Use 0x7FF if we want to keep * reading from the last position of the register pointer. */ addr = 0x7FF; switch (cmd->op) { case RMI_SPI_WRITE: rmi_spi->tx_buf[0] = (addr >> 8); rmi_spi->tx_buf[1] = addr & 0xFF; break; case RMI_SPI_READ: rmi_spi->tx_buf[0] = (addr >> 8) | 0x80; rmi_spi->tx_buf[1] = addr & 0xFF; break; case RMI_SPI_V2_READ_UNIFIED: break; case RMI_SPI_V2_READ_SPLIT: break; case RMI_SPI_V2_WRITE: rmi_spi->tx_buf[0] = 0x40; rmi_spi->tx_buf[1] = (addr >> 8) & 0xFF; rmi_spi->tx_buf[2] = addr & 0xFF; rmi_spi->tx_buf[3] = tx_len; break; } if (tx_buf) memcpy(&rmi_spi->tx_buf[cmd_len], tx_buf, tx_len); if (rmi_spi->tx_xfer_count > 1) { for (i = 0; i < total_tx_len; i++) { xfer = &rmi_spi->tx_xfers[i]; memset(xfer, 0, sizeof(struct spi_transfer)); xfer->tx_buf = &rmi_spi->tx_buf[i]; xfer->len = 1; xfer->delay_usecs = spi_data->write_delay_us; spi_message_add_tail(xfer, &msg); } } else { xfer = rmi_spi->tx_xfers; memset(xfer, 0, sizeof(struct spi_transfer)); xfer->tx_buf = rmi_spi->tx_buf; xfer->len = total_tx_len; spi_message_add_tail(xfer, &msg); } rmi_dbg(RMI_DEBUG_XPORT, &spi->dev, "%s: cmd: %s tx_buf len: %d tx_buf: %*ph\n", __func__, cmd->op == RMI_SPI_WRITE ? "WRITE" : "READ", total_tx_len, total_tx_len, rmi_spi->tx_buf); if (rx_buf) { if (rmi_spi->rx_xfer_count > 1) { for (i = 0; i < rx_len; i++) { xfer = &rmi_spi->rx_xfers[i]; memset(xfer, 0, sizeof(struct spi_transfer)); xfer->rx_buf = &rmi_spi->rx_buf[i]; xfer->len = 1; xfer->delay_usecs = spi_data->read_delay_us; spi_message_add_tail(xfer, &msg); } } else { xfer = rmi_spi->rx_xfers; memset(xfer, 0, sizeof(struct spi_transfer)); xfer->rx_buf = rmi_spi->rx_buf; xfer->len = rx_len; spi_message_add_tail(xfer, &msg); } } ret = spi_sync(spi, &msg); if (ret < 0) { dev_err(&spi->dev, "spi xfer failed: %d\n", ret); return ret; } if (rx_buf) { memcpy(rx_buf, rmi_spi->rx_buf, rx_len); rmi_dbg(RMI_DEBUG_XPORT, &spi->dev, "%s: (%d) %*ph\n", __func__, rx_len, rx_len, rx_buf); } return 0; }
static int rmi_smb_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev); struct rmi_smb_xport *rmi_smb; int retval; int smbus_version; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_HOST_NOTIFY)) { dev_err(&client->dev, "adapter does not support required functionality.\n"); return -ENODEV; } if (client->irq <= 0) { dev_err(&client->dev, "no IRQ provided, giving up.\n"); return client->irq ? client->irq : -ENODEV; } rmi_smb = devm_kzalloc(&client->dev, sizeof(struct rmi_smb_xport), GFP_KERNEL); if (!rmi_smb) return -ENOMEM; if (!pdata) { dev_err(&client->dev, "no platform data, aborting\n"); return -ENOMEM; } rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Probing %s.\n", dev_name(&client->dev)); rmi_smb->client = client; mutex_init(&rmi_smb->page_mutex); mutex_init(&rmi_smb->mappingtable_mutex); rmi_smb->xport.dev = &client->dev; rmi_smb->xport.pdata = *pdata; rmi_smb->xport.pdata.irq = client->irq; rmi_smb->xport.proto_name = "smb2"; rmi_smb->xport.ops = &rmi_smb_ops; retval = rmi_smb_get_version(rmi_smb); if (retval < 0) return retval; smbus_version = retval; rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", smbus_version); if (smbus_version != 2) { dev_err(&client->dev, "Unrecognized SMB version %d.\n", smbus_version); return -ENODEV; } i2c_set_clientdata(client, rmi_smb); retval = rmi_register_transport_device(&rmi_smb->xport); if (retval) { dev_err(&client->dev, "Failed to register transport driver at 0x%.2X.\n", client->addr); i2c_set_clientdata(client, NULL); return retval; } dev_info(&client->dev, "registered rmi smb driver at %#04x.\n", client->addr); return 0; }