@@ -32,24 +32,44 @@
#include "i2c-hid.h"
+#define MAX_BULK_SUPPLIES 2
+
+struct i2c_hid_of_chip_data {
+ const char * const *supply_names;
+ int num_supplies;
+ int post_power_delay_ms;
+ int post_reset_delay_ms;
+ u16 hid_descriptor_address;
+};
+
struct i2c_hid_of {
struct i2chid_ops ops;
struct i2c_client *client;
struct gpio_desc *reset_gpio;
- struct regulator_bulk_data supplies[2];
+ struct regulator_bulk_data supplies[MAX_BULK_SUPPLIES];
+ int num_supplies;
int post_power_delay_ms;
int post_reset_delay_ms;
};
+static const char * const i2c_hid_of_default_supply_names[] = {
+ "vdd",
+ "vddl",
+};
+
+static const struct i2c_hid_of_chip_data i2c_hid_of_default_chip_data = {
+ .supply_names = i2c_hid_of_default_supply_names,
+ .num_supplies = ARRAY_SIZE(i2c_hid_of_default_supply_names),
+};
+
static int i2c_hid_of_power_up(struct i2chid_ops *ops)
{
struct i2c_hid_of *ihid_of = container_of(ops, struct i2c_hid_of, ops);
struct device *dev = &ihid_of->client->dev;
int ret;
- ret = regulator_bulk_enable(ARRAY_SIZE(ihid_of->supplies),
- ihid_of->supplies);
+ ret = regulator_bulk_enable(ihid_of->num_supplies, ihid_of->supplies);
if (ret) {
dev_warn(dev, "Failed to enable supplies: %d\n", ret);
return ret;
@@ -70,18 +90,28 @@ static void i2c_hid_of_power_down(struct i2chid_ops *ops)
struct i2c_hid_of *ihid_of = container_of(ops, struct i2c_hid_of, ops);
gpiod_set_value_cansleep(ihid_of->reset_gpio, 1);
- regulator_bulk_disable(ARRAY_SIZE(ihid_of->supplies),
- ihid_of->supplies);
+ regulator_bulk_disable(ihid_of->num_supplies, ihid_of->supplies);
}
static int i2c_hid_of_probe(struct i2c_client *client)
{
+ const struct i2c_hid_of_chip_data *chip_data;
struct device *dev = &client->dev;
struct i2c_hid_of *ihid_of;
u16 hid_descriptor_address;
u32 quirks = 0;
int ret;
u32 val;
+ int i;
+
+ chip_data = device_get_match_data(dev);
+ if (!chip_data)
+ chip_data = &i2c_hid_of_default_chip_data;
+
+ if (chip_data->num_supplies > MAX_BULK_SUPPLIES) {
+ dev_err(dev, "Error chip_data->num_supplies > MAX_BULK_SUPPLIES (internal kernel error)\n");
+ return -EINVAL;
+ }
ihid_of = devm_kzalloc(dev, sizeof(*ihid_of), GFP_KERNEL);
if (!ihid_of)
@@ -90,16 +120,22 @@ static int i2c_hid_of_probe(struct i2c_client *client)
ihid_of->ops.power_up = i2c_hid_of_power_up;
ihid_of->ops.power_down = i2c_hid_of_power_down;
+ /* chip_data as defaults, allow device-properties to override things */
+ ihid_of->post_power_delay_ms = chip_data->post_power_delay_ms;
+ ihid_of->post_reset_delay_ms = chip_data->post_reset_delay_ms;
+ hid_descriptor_address = chip_data->hid_descriptor_address;
+
ret = device_property_read_u32(dev, "hid-descr-addr", &val);
- if (ret) {
+ if (ret == 0) {
+ if (val >> 16) {
+ dev_err(dev, "Bad HID register address: 0x%08x\n", val);
+ return -EINVAL;
+ }
+ hid_descriptor_address = val;
+ } else if (!hid_descriptor_address) {
dev_err(dev, "HID register address not provided\n");
return -ENODEV;
}
- if (val >> 16) {
- dev_err(dev, "Bad HID register address: 0x%08x\n", val);
- return -EINVAL;
- }
- hid_descriptor_address = val;
if (!device_property_read_u32(dev, "post-power-on-delay-ms", &val))
ihid_of->post_power_delay_ms = val;
@@ -112,10 +148,11 @@ static int i2c_hid_of_probe(struct i2c_client *client)
if (IS_ERR(ihid_of->reset_gpio))
return PTR_ERR(ihid_of->reset_gpio);
- ihid_of->supplies[0].supply = "vdd";
- ihid_of->supplies[1].supply = "vddl";
- ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ihid_of->supplies),
- ihid_of->supplies);
+ ihid_of->num_supplies = chip_data->num_supplies;
+ for (i = 0; i < ihid_of->num_supplies; i++)
+ ihid_of->supplies[i].supply = chip_data->supply_names[i];
+
+ ret = devm_regulator_bulk_get(dev, ihid_of->num_supplies, ihid_of->supplies);
if (ret)
return ret;
Add a chip_data struct which can be used to set different supply-names and default power-on-delay, reset-deassert-delay and hid_descriptor_address values. This is a preparation patch for consolidating the 2 specialized i2c-hid-of-elan.c and i2c-hid-of-goodix.c drivers into the generic i2c-hid-of driver. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/hid/i2c-hid/i2c-hid-of.c | 67 +++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 15 deletions(-)