diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2018-08-20 12:07:01 -0400 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2018-08-20 12:07:01 -0400 |
| commit | 4435b5774cdf9b3547934333e8facbb3fc1057be (patch) | |
| tree | 41ffa9a86d6d801fe935f600a91dedce8d5be628 | |
| parent | 5a12d86ce3a93b6442963e5f6e6511e8f470f760 (diff) | |
| parent | 6136f97cd2dd2b5a88d62bd73cc663a803124c09 (diff) | |
Merge branch 'for-4.19/i2c-hid' into for-linus
Low voltage support for i2c-hid
| -rw-r--r-- | Documentation/devicetree/bindings/input/hid-over-i2c.txt | 3 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 57 | ||||
| -rw-r--r-- | include/linux/platform_data/i2c-hid.h | 7 |
3 files changed, 32 insertions, 35 deletions
diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt b/Documentation/devicetree/bindings/input/hid-over-i2c.txt index 4d3da9d91de4..89e6ab89ba38 100644 --- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt +++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt | |||
| @@ -26,7 +26,8 @@ device-specific compatible properties, which should be used in addition to the | |||
| 26 | 26 | ||
| 27 | - compatible: | 27 | - compatible: |
| 28 | * "wacom,w9013" (Wacom W9013 digitizer). Supports: | 28 | * "wacom,w9013" (Wacom W9013 digitizer). Supports: |
| 29 | - vdd-supply | 29 | - vdd-supply (3.3V) |
| 30 | - vddl-supply (1.8V) | ||
| 30 | - post-power-on-delay-ms | 31 | - post-power-on-delay-ms |
| 31 | 32 | ||
| 32 | - vdd-supply: phandle of the regulator that provides the supply voltage. | 33 | - vdd-supply: phandle of the regulator that provides the supply voltage. |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index eae0cb3ddec6..2ce194a84868 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -1002,18 +1002,18 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
| 1002 | return client->irq; | 1002 | return client->irq; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL); | 1005 | ihid = devm_kzalloc(&client->dev, sizeof(*ihid), GFP_KERNEL); |
| 1006 | if (!ihid) | 1006 | if (!ihid) |
| 1007 | return -ENOMEM; | 1007 | return -ENOMEM; |
| 1008 | 1008 | ||
| 1009 | if (client->dev.of_node) { | 1009 | if (client->dev.of_node) { |
| 1010 | ret = i2c_hid_of_probe(client, &ihid->pdata); | 1010 | ret = i2c_hid_of_probe(client, &ihid->pdata); |
| 1011 | if (ret) | 1011 | if (ret) |
| 1012 | goto err; | 1012 | return ret; |
| 1013 | } else if (!platform_data) { | 1013 | } else if (!platform_data) { |
| 1014 | ret = i2c_hid_acpi_pdata(client, &ihid->pdata); | 1014 | ret = i2c_hid_acpi_pdata(client, &ihid->pdata); |
| 1015 | if (ret) | 1015 | if (ret) |
| 1016 | goto err; | 1016 | return ret; |
| 1017 | } else { | 1017 | } else { |
| 1018 | ihid->pdata = *platform_data; | 1018 | ihid->pdata = *platform_data; |
| 1019 | } | 1019 | } |
| @@ -1021,21 +1021,20 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
| 1021 | /* Parse platform agnostic common properties from ACPI / device tree */ | 1021 | /* Parse platform agnostic common properties from ACPI / device tree */ |
| 1022 | i2c_hid_fwnode_probe(client, &ihid->pdata); | 1022 | i2c_hid_fwnode_probe(client, &ihid->pdata); |
| 1023 | 1023 | ||
| 1024 | ihid->pdata.supply = devm_regulator_get(&client->dev, "vdd"); | 1024 | ihid->pdata.supplies[0].supply = "vdd"; |
| 1025 | if (IS_ERR(ihid->pdata.supply)) { | 1025 | ihid->pdata.supplies[1].supply = "vddl"; |
| 1026 | ret = PTR_ERR(ihid->pdata.supply); | 1026 | |
| 1027 | if (ret != -EPROBE_DEFER) | 1027 | ret = devm_regulator_bulk_get(&client->dev, |
| 1028 | dev_err(&client->dev, "Failed to get regulator: %d\n", | 1028 | ARRAY_SIZE(ihid->pdata.supplies), |
| 1029 | ret); | 1029 | ihid->pdata.supplies); |
| 1030 | goto err; | 1030 | if (ret) |
| 1031 | } | 1031 | return ret; |
| 1032 | |||
| 1033 | ret = regulator_bulk_enable(ARRAY_SIZE(ihid->pdata.supplies), | ||
| 1034 | ihid->pdata.supplies); | ||
| 1035 | if (ret < 0) | ||
| 1036 | return ret; | ||
| 1032 | 1037 | ||
| 1033 | ret = regulator_enable(ihid->pdata.supply); | ||
| 1034 | if (ret < 0) { | ||
| 1035 | dev_err(&client->dev, "Failed to enable regulator: %d\n", | ||
| 1036 | ret); | ||
| 1037 | goto err; | ||
| 1038 | } | ||
| 1039 | if (ihid->pdata.post_power_delay_ms) | 1038 | if (ihid->pdata.post_power_delay_ms) |
| 1040 | msleep(ihid->pdata.post_power_delay_ms); | 1039 | msleep(ihid->pdata.post_power_delay_ms); |
| 1041 | 1040 | ||
| @@ -1122,11 +1121,9 @@ err_pm: | |||
| 1122 | pm_runtime_disable(&client->dev); | 1121 | pm_runtime_disable(&client->dev); |
| 1123 | 1122 | ||
| 1124 | err_regulator: | 1123 | err_regulator: |
| 1125 | regulator_disable(ihid->pdata.supply); | 1124 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1126 | 1125 | ihid->pdata.supplies); | |
| 1127 | err: | ||
| 1128 | i2c_hid_free_buffers(ihid); | 1126 | i2c_hid_free_buffers(ihid); |
| 1129 | kfree(ihid); | ||
| 1130 | return ret; | 1127 | return ret; |
| 1131 | } | 1128 | } |
| 1132 | 1129 | ||
| @@ -1148,9 +1145,8 @@ static int i2c_hid_remove(struct i2c_client *client) | |||
| 1148 | if (ihid->bufsize) | 1145 | if (ihid->bufsize) |
| 1149 | i2c_hid_free_buffers(ihid); | 1146 | i2c_hid_free_buffers(ihid); |
| 1150 | 1147 | ||
| 1151 | regulator_disable(ihid->pdata.supply); | 1148 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1152 | 1149 | ihid->pdata.supplies); | |
| 1153 | kfree(ihid); | ||
| 1154 | 1150 | ||
| 1155 | return 0; | 1151 | return 0; |
| 1156 | } | 1152 | } |
| @@ -1201,9 +1197,8 @@ static int i2c_hid_suspend(struct device *dev) | |||
| 1201 | hid_warn(hid, "Failed to enable irq wake: %d\n", | 1197 | hid_warn(hid, "Failed to enable irq wake: %d\n", |
| 1202 | wake_status); | 1198 | wake_status); |
| 1203 | } else { | 1199 | } else { |
| 1204 | ret = regulator_disable(ihid->pdata.supply); | 1200 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1205 | if (ret < 0) | 1201 | ihid->pdata.supplies); |
| 1206 | hid_warn(hid, "Failed to disable supply: %d\n", ret); | ||
| 1207 | } | 1202 | } |
| 1208 | 1203 | ||
| 1209 | return 0; | 1204 | return 0; |
| @@ -1218,9 +1213,11 @@ static int i2c_hid_resume(struct device *dev) | |||
| 1218 | int wake_status; | 1213 | int wake_status; |
| 1219 | 1214 | ||
| 1220 | if (!device_may_wakeup(&client->dev)) { | 1215 | if (!device_may_wakeup(&client->dev)) { |
| 1221 | ret = regulator_enable(ihid->pdata.supply); | 1216 | ret = regulator_bulk_enable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1222 | if (ret < 0) | 1217 | ihid->pdata.supplies); |
| 1223 | hid_warn(hid, "Failed to enable supply: %d\n", ret); | 1218 | if (ret) |
| 1219 | hid_warn(hid, "Failed to enable supplies: %d\n", ret); | ||
| 1220 | |||
| 1224 | if (ihid->pdata.post_power_delay_ms) | 1221 | if (ihid->pdata.post_power_delay_ms) |
| 1225 | msleep(ihid->pdata.post_power_delay_ms); | 1222 | msleep(ihid->pdata.post_power_delay_ms); |
| 1226 | } else if (ihid->irq_wake_enabled) { | 1223 | } else if (ihid->irq_wake_enabled) { |
diff --git a/include/linux/platform_data/i2c-hid.h b/include/linux/platform_data/i2c-hid.h index 1fb088239d12..c628bb5e1061 100644 --- a/include/linux/platform_data/i2c-hid.h +++ b/include/linux/platform_data/i2c-hid.h | |||
| @@ -12,14 +12,13 @@ | |||
| 12 | #ifndef __LINUX_I2C_HID_H | 12 | #ifndef __LINUX_I2C_HID_H |
| 13 | #define __LINUX_I2C_HID_H | 13 | #define __LINUX_I2C_HID_H |
| 14 | 14 | ||
| 15 | #include <linux/regulator/consumer.h> | ||
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 16 | 17 | ||
| 17 | struct regulator; | ||
| 18 | |||
| 19 | /** | 18 | /** |
| 20 | * struct i2chid_platform_data - used by hid over i2c implementation. | 19 | * struct i2chid_platform_data - used by hid over i2c implementation. |
| 21 | * @hid_descriptor_address: i2c register where the HID descriptor is stored. | 20 | * @hid_descriptor_address: i2c register where the HID descriptor is stored. |
| 22 | * @supply: regulator for powering on the device. | 21 | * @supplies: regulators for powering on the device. |
| 23 | * @post_power_delay_ms: delay after powering on before device is usable. | 22 | * @post_power_delay_ms: delay after powering on before device is usable. |
| 24 | * | 23 | * |
| 25 | * Note that it is the responsibility of the platform driver (or the acpi 5.0 | 24 | * Note that it is the responsibility of the platform driver (or the acpi 5.0 |
| @@ -35,7 +34,7 @@ struct regulator; | |||
| 35 | */ | 34 | */ |
| 36 | struct i2c_hid_platform_data { | 35 | struct i2c_hid_platform_data { |
| 37 | u16 hid_descriptor_address; | 36 | u16 hid_descriptor_address; |
| 38 | struct regulator *supply; | 37 | struct regulator_bulk_data supplies[2]; |
| 39 | int post_power_delay_ms; | 38 | int post_power_delay_ms; |
| 40 | }; | 39 | }; |
| 41 | 40 | ||
