示例#1
0
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;
}
示例#2
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;
}
示例#3
0
文件: rmi_bus.c 项目: 513855417/linux
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;
}
示例#4
0
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;
}
示例#5
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);
            }

        }
    }
示例#6
0
文件: rmi_spi.c 项目: 020gzh/linux
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;
}
示例#7
0
/* 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;
}
示例#8
0
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;
}
示例#9
0
文件: rmi_bus.c 项目: 513855417/linux
/**
 * 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;
}
示例#10
0
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;
}
示例#11
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;
}
示例#12
0
文件: rmi_spi.c 项目: 020gzh/linux
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;
}
示例#13
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;

}