mirror of https://gitee.com/openkylin/linux.git
Merge branch 'synaptics-rmi4' into next
Bring in latest RMI4 support in preparation to the merge window.
This commit is contained in:
commit
d5e6e0fa44
|
@ -9,9 +9,11 @@ config RMI4_CORE
|
|||
|
||||
If unsure, say Y.
|
||||
|
||||
if RMI4_CORE
|
||||
|
||||
config RMI4_I2C
|
||||
tristate "RMI4 I2C Support"
|
||||
depends on RMI4_CORE && I2C
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you want to support RMI4 devices connected to an I2C
|
||||
bus.
|
||||
|
@ -20,7 +22,7 @@ config RMI4_I2C
|
|||
|
||||
config RMI4_SPI
|
||||
tristate "RMI4 SPI Support"
|
||||
depends on RMI4_CORE && SPI
|
||||
depends on SPI
|
||||
help
|
||||
Say Y here if you want to support RMI4 devices connected to a SPI
|
||||
bus.
|
||||
|
@ -29,7 +31,7 @@ config RMI4_SPI
|
|||
|
||||
config RMI4_SMB
|
||||
tristate "RMI4 SMB Support"
|
||||
depends on RMI4_CORE && I2C
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you want to support RMI4 devices connected to an SMB
|
||||
bus.
|
||||
|
@ -40,23 +42,20 @@ config RMI4_SMB
|
|||
called rmi_smbus.
|
||||
|
||||
config RMI4_F03
|
||||
bool "RMI4 Function 03 (PS2 Guest)"
|
||||
depends on RMI4_CORE
|
||||
bool "RMI4 Function 03 (PS2 Guest)"
|
||||
depends on SERIO=y || RMI4_CORE=SERIO
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 03.
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 03.
|
||||
|
||||
Function 03 provides PS2 guest support for RMI4 devices. This
|
||||
includes support for TrackPoints on TouchPads.
|
||||
Function 03 provides PS2 guest support for RMI4 devices. This
|
||||
includes support for TrackPoints on TouchPads.
|
||||
|
||||
config RMI4_2D_SENSOR
|
||||
bool
|
||||
depends on RMI4_CORE
|
||||
|
||||
config RMI4_F11
|
||||
bool "RMI4 Function 11 (2D pointing)"
|
||||
select RMI4_2D_SENSOR
|
||||
depends on RMI4_CORE
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 11.
|
||||
|
||||
|
@ -67,7 +66,6 @@ config RMI4_F11
|
|||
config RMI4_F12
|
||||
bool "RMI4 Function 12 (2D pointing)"
|
||||
select RMI4_2D_SENSOR
|
||||
depends on RMI4_CORE
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 12.
|
||||
|
||||
|
@ -77,7 +75,6 @@ config RMI4_F12
|
|||
|
||||
config RMI4_F30
|
||||
bool "RMI4 Function 30 (GPIO LED)"
|
||||
depends on RMI4_CORE
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 30.
|
||||
|
||||
|
@ -86,7 +83,6 @@ config RMI4_F30
|
|||
|
||||
config RMI4_F34
|
||||
bool "RMI4 Function 34 (Device reflash)"
|
||||
depends on RMI4_CORE
|
||||
select FW_LOADER
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 34.
|
||||
|
@ -97,7 +93,6 @@ config RMI4_F34
|
|||
|
||||
config RMI4_F54
|
||||
bool "RMI4 Function 54 (Analog diagnostics)"
|
||||
depends on RMI4_CORE
|
||||
depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m)
|
||||
select VIDEOBUF2_VMALLOC
|
||||
select RMI4_F55
|
||||
|
@ -109,9 +104,10 @@ config RMI4_F54
|
|||
|
||||
config RMI4_F55
|
||||
bool "RMI4 Function 55 (Sensor tuning)"
|
||||
depends on RMI4_CORE
|
||||
help
|
||||
Say Y here if you want to add support for RMI4 function 55
|
||||
|
||||
Function 55 provides access to the RMI4 touch sensor tuning
|
||||
mechanism.
|
||||
|
||||
endif # RMI_CORE
|
||||
|
|
|
@ -144,8 +144,13 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
|
|||
int input_flags = 0;
|
||||
|
||||
if (sensor->report_abs) {
|
||||
if (sensor->axis_align.swap_axes)
|
||||
if (sensor->axis_align.swap_axes) {
|
||||
swap(sensor->max_x, sensor->max_y);
|
||||
swap(sensor->axis_align.clip_x_low,
|
||||
sensor->axis_align.clip_y_low);
|
||||
swap(sensor->axis_align.clip_x_high,
|
||||
sensor->axis_align.clip_y_high);
|
||||
}
|
||||
|
||||
sensor->min_x = sensor->axis_align.clip_x_low;
|
||||
if (sensor->axis_align.clip_x_high)
|
||||
|
|
|
@ -261,10 +261,10 @@ int __rmi_register_function_handler(struct rmi_function_handler *handler,
|
|||
driver->probe = rmi_function_probe;
|
||||
driver->remove = rmi_function_remove;
|
||||
|
||||
error = driver_register(&handler->driver);
|
||||
error = driver_register(driver);
|
||||
if (error) {
|
||||
pr_err("driver_register() failed for %s, error: %d\n",
|
||||
handler->driver.name, error);
|
||||
driver->name, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -265,6 +265,19 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
|
||||
struct rmi_function *entry;
|
||||
|
||||
list_for_each_entry(entry, &data->function_list, node) {
|
||||
if (entry->fd.function_number == number)
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int suspend_one_function(struct rmi_function *fn)
|
||||
{
|
||||
struct rmi_function_handler *fh;
|
||||
|
@ -364,7 +377,7 @@ static void rmi_driver_set_input_name(struct rmi_device *rmi_dev,
|
|||
struct input_dev *input)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
|
||||
char *device_name = rmi_f01_get_product_ID(data->f01_container);
|
||||
const char *device_name = rmi_f01_get_product_ID(data->f01_container);
|
||||
char *name;
|
||||
|
||||
name = devm_kasprintf(&rmi_dev->dev, GFP_KERNEL,
|
||||
|
@ -836,7 +849,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
|
|||
void *ctx, const struct pdt_entry *pdt)
|
||||
{
|
||||
struct device *dev = &rmi_dev->dev;
|
||||
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
int *current_irq_count = ctx;
|
||||
struct rmi_function *fn;
|
||||
int i;
|
||||
|
@ -1040,7 +1053,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
|
|||
}
|
||||
|
||||
if (data->bootloader_mode)
|
||||
dev_warn(&rmi_dev->dev, "Device in bootloader mode.\n");
|
||||
dev_warn(dev, "Device in bootloader mode.\n");
|
||||
|
||||
data->irq_count = irq_count;
|
||||
data->num_of_irq_regs = (data->irq_count + 7) / 8;
|
||||
|
|
|
@ -93,6 +93,7 @@ bool rmi_is_physical_driver(struct device_driver *);
|
|||
int rmi_register_physical_driver(void);
|
||||
void rmi_unregister_physical_driver(void);
|
||||
void rmi_free_function_list(struct rmi_device *rmi_dev);
|
||||
struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number);
|
||||
int rmi_enable_sensor(struct rmi_device *rmi_dev);
|
||||
int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx,
|
||||
int (*callback)(struct rmi_device *rmi_dev, void *ctx,
|
||||
|
@ -104,7 +105,7 @@ int rmi_init_functions(struct rmi_driver_data *data);
|
|||
int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx,
|
||||
const struct pdt_entry *pdt);
|
||||
|
||||
char *rmi_f01_get_product_ID(struct rmi_function *fn);
|
||||
const char *rmi_f01_get_product_ID(struct rmi_function *fn);
|
||||
|
||||
#ifdef CONFIG_RMI4_F34
|
||||
int rmi_f34_create_sysfs(struct rmi_device *rmi_dev);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/of.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include "rmi_driver.h"
|
||||
|
||||
#define RMI_PRODUCT_ID_LENGTH 10
|
||||
|
@ -54,6 +55,7 @@ struct f01_basic_properties {
|
|||
u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
|
||||
u16 productinfo;
|
||||
u32 firmware_id;
|
||||
u32 package_id;
|
||||
};
|
||||
|
||||
/* F01 device status bits */
|
||||
|
@ -220,8 +222,19 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
|
|||
has_build_id_query = !!(queries[0] & BIT(1));
|
||||
}
|
||||
|
||||
if (has_package_id_query)
|
||||
if (has_package_id_query) {
|
||||
ret = rmi_read_block(rmi_dev, prod_info_addr,
|
||||
queries, sizeof(__le64));
|
||||
if (ret) {
|
||||
dev_err(&rmi_dev->dev,
|
||||
"Failed to read package info: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
props->package_id = get_unaligned_le64(queries);
|
||||
prod_info_addr++;
|
||||
}
|
||||
|
||||
if (has_build_id_query) {
|
||||
ret = rmi_read_block(rmi_dev, prod_info_addr, queries,
|
||||
|
@ -241,13 +254,90 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
char *rmi_f01_get_product_ID(struct rmi_function *fn)
|
||||
const char *rmi_f01_get_product_ID(struct rmi_function *fn)
|
||||
{
|
||||
struct f01_data *f01 = dev_get_drvdata(&fn->dev);
|
||||
|
||||
return f01->properties.product_id;
|
||||
}
|
||||
|
||||
static ssize_t rmi_driver_manufacturer_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n",
|
||||
f01->properties.manufacturer_id);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(manufacturer_id, 0444,
|
||||
rmi_driver_manufacturer_id_show, NULL);
|
||||
|
||||
static ssize_t rmi_driver_dom_show(struct device *dev,
|
||||
struct device_attribute *dattr, char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.dom);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(date_of_manufacture, 0444, rmi_driver_dom_show, NULL);
|
||||
|
||||
static ssize_t rmi_driver_product_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.product_id);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(product_id, 0444, rmi_driver_product_id_show, NULL);
|
||||
|
||||
static ssize_t rmi_driver_firmware_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", f01->properties.firmware_id);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(firmware_id, 0444, rmi_driver_firmware_id_show, NULL);
|
||||
|
||||
static ssize_t rmi_driver_package_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
|
||||
|
||||
u32 package_id = f01->properties.package_id;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%04x.%04x\n",
|
||||
package_id & 0xffff, (package_id >> 16) & 0xffff);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(package_id, 0444, rmi_driver_package_id_show, NULL);
|
||||
|
||||
static struct attribute *rmi_f01_attrs[] = {
|
||||
&dev_attr_manufacturer_id.attr,
|
||||
&dev_attr_date_of_manufacture.attr,
|
||||
&dev_attr_product_id.attr,
|
||||
&dev_attr_firmware_id.attr,
|
||||
&dev_attr_package_id.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group rmi_f01_attr_group = {
|
||||
.attrs = rmi_f01_attrs,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int rmi_f01_of_probe(struct device *dev,
|
||||
struct rmi_device_platform_data *pdata)
|
||||
|
@ -480,9 +570,18 @@ static int rmi_f01_probe(struct rmi_function *fn)
|
|||
|
||||
dev_set_drvdata(&fn->dev, f01);
|
||||
|
||||
error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
|
||||
if (error)
|
||||
dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rmi_f01_remove(struct rmi_function *fn)
|
||||
{
|
||||
sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
|
||||
}
|
||||
|
||||
static int rmi_f01_config(struct rmi_function *fn)
|
||||
{
|
||||
struct f01_data *f01 = dev_get_drvdata(&fn->dev);
|
||||
|
@ -622,6 +721,7 @@ struct rmi_function_handler rmi_f01_handler = {
|
|||
},
|
||||
.func = 0x01,
|
||||
.probe = rmi_f01_probe,
|
||||
.remove = rmi_f01_remove,
|
||||
.config = rmi_f01_config,
|
||||
.attention = rmi_f01_attention,
|
||||
.suspend = rmi_f01_suspend,
|
||||
|
|
|
@ -175,9 +175,6 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||
int i;
|
||||
int error;
|
||||
|
||||
if (!rmi_dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (drvdata->attn_data.data) {
|
||||
/* First grab the data passed by the transport device */
|
||||
if (drvdata->attn_data.size < ob_len) {
|
||||
|
|
|
@ -157,6 +157,9 @@ static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
|
|||
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;
|
||||
|
@ -174,7 +177,7 @@ static int rmi_f34_write_config(struct f34_data *f34, const void *data)
|
|||
F34_WRITE_CONFIG_BLOCK);
|
||||
}
|
||||
|
||||
int rmi_f34_enable_flash(struct f34_data *f34)
|
||||
static int rmi_f34_enable_flash(struct f34_data *f34)
|
||||
{
|
||||
return rmi_f34_command(f34, F34_ENABLE_FLASH_PROG,
|
||||
F34_ENABLE_WAIT_MS, true);
|
||||
|
@ -184,9 +187,14 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
|
|||
const struct rmi_f34_firmware *syn_fw)
|
||||
{
|
||||
struct rmi_function *fn = f34->fn;
|
||||
u32 image_size = le32_to_cpu(syn_fw->image_size);
|
||||
u32 config_size = le32_to_cpu(syn_fw->config_size);
|
||||
int ret;
|
||||
|
||||
if (syn_fw->image_size) {
|
||||
f34->update_progress = 0;
|
||||
f34->update_size = image_size + config_size;
|
||||
|
||||
if (image_size) {
|
||||
dev_info(&fn->dev, "Erasing firmware...\n");
|
||||
ret = rmi_f34_command(f34, F34_ERASE_ALL,
|
||||
F34_ERASE_WAIT_MS, true);
|
||||
|
@ -194,18 +202,18 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
|
|||
return ret;
|
||||
|
||||
dev_info(&fn->dev, "Writing firmware (%d bytes)...\n",
|
||||
syn_fw->image_size);
|
||||
image_size);
|
||||
ret = rmi_f34_write_firmware(f34, syn_fw->data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (syn_fw->config_size) {
|
||||
if (config_size) {
|
||||
/*
|
||||
* We only need to erase config if we haven't updated
|
||||
* firmware.
|
||||
*/
|
||||
if (!syn_fw->image_size) {
|
||||
if (!image_size) {
|
||||
dev_info(&fn->dev, "Erasing config...\n");
|
||||
ret = rmi_f34_command(f34, F34_ERASE_CONFIG,
|
||||
F34_ERASE_WAIT_MS, true);
|
||||
|
@ -214,9 +222,8 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
|
|||
}
|
||||
|
||||
dev_info(&fn->dev, "Writing config (%d bytes)...\n",
|
||||
syn_fw->config_size);
|
||||
ret = rmi_f34_write_config(f34,
|
||||
&syn_fw->data[syn_fw->image_size]);
|
||||
config_size);
|
||||
ret = rmi_f34_write_config(f34, &syn_fw->data[image_size]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -224,21 +231,23 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
|
||||
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 *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;
|
||||
|
||||
syn_fw = (const struct rmi_f34_firmware *)fw->data;
|
||||
BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) !=
|
||||
F34_FW_IMAGE_OFFSET);
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
|
||||
"FW size:%d, checksum:%08x, image_size:%d, config_size:%d\n",
|
||||
(int)fw->size,
|
||||
"FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n",
|
||||
fw->size,
|
||||
le32_to_cpu(syn_fw->checksum),
|
||||
le32_to_cpu(syn_fw->image_size),
|
||||
le32_to_cpu(syn_fw->config_size));
|
||||
image_size, config_size);
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
|
||||
"FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n",
|
||||
|
@ -246,27 +255,25 @@ int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
|
|||
(int)sizeof(syn_fw->product_id), syn_fw->product_id,
|
||||
syn_fw->product_info[0], syn_fw->product_info[1]);
|
||||
|
||||
if (syn_fw->image_size &&
|
||||
syn_fw->image_size != f34->v5.fw_blocks * f34->v5.block_size) {
|
||||
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",
|
||||
syn_fw->image_size,
|
||||
f34->v5.fw_blocks * f34->v5.block_size);
|
||||
image_size, f34->v5.fw_blocks * f34->v5.block_size);
|
||||
ret = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (syn_fw->config_size &&
|
||||
syn_fw->config_size != f34->v5.config_blocks * f34->v5.block_size) {
|
||||
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",
|
||||
syn_fw->config_size,
|
||||
config_size,
|
||||
f34->v5.config_blocks * f34->v5.block_size);
|
||||
ret = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (syn_fw->image_size && !syn_fw->config_size) {
|
||||
if (image_size && !config_size) {
|
||||
dev_err(&f34->fn->dev, "Bad firmware image: no config data\n");
|
||||
ret = -EILSEQ;
|
||||
goto out;
|
||||
|
@ -283,6 +290,63 @@ int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rmi_f34_status(struct rmi_function *fn)
|
||||
{
|
||||
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
|
||||
|
||||
/*
|
||||
* The status is the percentage complete, or once complete,
|
||||
* zero for success or a negative return code.
|
||||
*/
|
||||
return f34->update_status;
|
||||
}
|
||||
|
||||
static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct rmi_function *fn = data->f34_container;
|
||||
struct f34_data *f34;
|
||||
|
||||
if (fn) {
|
||||
f34 = dev_get_drvdata(&fn->dev);
|
||||
|
||||
if (f34->bl_version == 5)
|
||||
return scnprintf(buf, PAGE_SIZE, "%c%c\n",
|
||||
f34->bootloader_id[0],
|
||||
f34->bootloader_id[1]);
|
||||
else
|
||||
return scnprintf(buf, PAGE_SIZE, "V%d.%d\n",
|
||||
f34->bootloader_id[1],
|
||||
f34->bootloader_id[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
|
||||
|
||||
static ssize_t rmi_driver_configuration_id_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
struct rmi_function *fn = data->f34_container;
|
||||
struct f34_data *f34;
|
||||
|
||||
if (fn) {
|
||||
f34 = dev_get_drvdata(&fn->dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", f34->configuration_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(configuration_id, 0444,
|
||||
rmi_driver_configuration_id_show, NULL);
|
||||
|
||||
static int rmi_firmware_update(struct rmi_driver_data *data,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
|
@ -346,7 +410,13 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
|
|||
else
|
||||
ret = rmi_f34_update_firmware(f34, fw);
|
||||
|
||||
dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret);
|
||||
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);
|
||||
|
||||
|
@ -377,9 +447,6 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rmi_firmware_update(struct rmi_driver_data *data,
|
||||
const struct firmware *fw);
|
||||
|
||||
static ssize_t rmi_driver_update_fw_store(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
const char *buf, size_t count)
|
||||
|
@ -414,8 +481,27 @@ static ssize_t rmi_driver_update_fw_store(struct device *dev,
|
|||
|
||||
static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store);
|
||||
|
||||
static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
|
||||
struct device_attribute *dattr,
|
||||
char *buf)
|
||||
{
|
||||
struct rmi_driver_data *data = dev_get_drvdata(dev);
|
||||
int update_status = 0;
|
||||
|
||||
if (data->f34_container)
|
||||
update_status = rmi_f34_status(data->f34_container);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", update_status);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(update_fw_status, 0444,
|
||||
rmi_driver_update_fw_status_show, NULL);
|
||||
|
||||
static struct attribute *rmi_firmware_attrs[] = {
|
||||
&dev_attr_bootloader_id.attr,
|
||||
&dev_attr_configuration_id.attr,
|
||||
&dev_attr_update_fw.attr,
|
||||
&dev_attr_update_fw_status.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -441,8 +527,6 @@ static int rmi_f34_probe(struct rmi_function *fn)
|
|||
/* v5 code only supported version 0, try V7 probe */
|
||||
if (version > 0)
|
||||
return rmi_f34v7_probe(f34);
|
||||
else if (version != 0)
|
||||
return -ENODEV;
|
||||
|
||||
f34->bl_version = 5;
|
||||
|
||||
|
|
|
@ -301,6 +301,10 @@ struct f34_data {
|
|||
unsigned char bootloader_id[5];
|
||||
unsigned char configuration_id[CONFIG_ID_SIZE*2 + 1];
|
||||
|
||||
int update_status;
|
||||
int update_progress;
|
||||
int update_size;
|
||||
|
||||
union {
|
||||
struct f34v5_data v5;
|
||||
struct f34v7_data v7;
|
||||
|
|
|
@ -588,6 +588,7 @@ static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34)
|
|||
u16 block_count;
|
||||
|
||||
block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
|
||||
f34->update_size += block_count;
|
||||
|
||||
if (block_count != f34->v7.blkcount.ui_firmware) {
|
||||
dev_err(&f34->fn->dev,
|
||||
|
@ -604,6 +605,7 @@ static int rmi_f34v7_check_ui_config_size(struct f34_data *f34)
|
|||
u16 block_count;
|
||||
|
||||
block_count = f34->v7.img.ui_config.size / f34->v7.block_size;
|
||||
f34->update_size += block_count;
|
||||
|
||||
if (block_count != f34->v7.blkcount.ui_config) {
|
||||
dev_err(&f34->fn->dev, "UI config size mismatch\n");
|
||||
|
@ -618,6 +620,7 @@ static int rmi_f34v7_check_dp_config_size(struct f34_data *f34)
|
|||
u16 block_count;
|
||||
|
||||
block_count = f34->v7.img.dp_config.size / f34->v7.block_size;
|
||||
f34->update_size += block_count;
|
||||
|
||||
if (block_count != f34->v7.blkcount.dp_config) {
|
||||
dev_err(&f34->fn->dev, "Display config size mismatch\n");
|
||||
|
@ -632,6 +635,8 @@ static int rmi_f34v7_check_guest_code_size(struct f34_data *f34)
|
|||
u16 block_count;
|
||||
|
||||
block_count = f34->v7.img.guest_code.size / f34->v7.block_size;
|
||||
f34->update_size += block_count;
|
||||
|
||||
if (block_count != f34->v7.blkcount.guest_code) {
|
||||
dev_err(&f34->fn->dev, "Guest code size mismatch\n");
|
||||
return -EINVAL;
|
||||
|
@ -645,6 +650,7 @@ static int rmi_f34v7_check_bl_config_size(struct f34_data *f34)
|
|||
u16 block_count;
|
||||
|
||||
block_count = f34->v7.img.bl_config.size / f34->v7.block_size;
|
||||
f34->update_size += block_count;
|
||||
|
||||
if (block_count != f34->v7.blkcount.bl_config) {
|
||||
dev_err(&f34->fn->dev, "Bootloader config size mismatch\n");
|
||||
|
@ -881,6 +887,9 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
|
|||
|
||||
block_ptr += (transfer * f34->v7.block_size);
|
||||
remaining -= transfer;
|
||||
f34->update_progress += transfer;
|
||||
f34->update_status = (f34->update_progress * 100) /
|
||||
f34->update_size;
|
||||
} while (remaining);
|
||||
|
||||
return 0;
|
||||
|
@ -1191,6 +1200,8 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
|
|||
rmi_f34v7_read_queries_bl_version(f34);
|
||||
|
||||
f34->v7.image = fw->data;
|
||||
f34->update_progress = 0;
|
||||
f34->update_size = 0;
|
||||
|
||||
ret = rmi_f34v7_parse_image_info(f34);
|
||||
if (ret < 0)
|
||||
|
|
Loading…
Reference in New Issue