diff options
| author | Stephen Boyd <swboyd@chromium.org> | 2018-06-21 22:27:17 -0400 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2018-06-25 09:12:42 -0400 |
| commit | 6136f97cd2dd2b5a88d62bd73cc663a803124c09 (patch) | |
| tree | 28b21fc0c45c8bba0cd6b2414dfb36fd4702152f | |
| parent | d6f83894110de247a81392ab7ef89e5498df7e80 (diff) | |
HID: i2c-hid: Add vddl regulator control
Some wacom w9013 devices have a vddl supply for "low valtage"
requirements. Add support in this driver to turn on this low voltage
supply. We can also drop a handful of error messages because the
regulator core is already printing an error when bulk regulators fail to
enable or disable.
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Dmitry Torokhov <dtor@chromium.org>
Cc: Doug Anderson <dianders@chromium.org>
Acked-by: Rob Herring <robh@kernel.org>
Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
| -rw-r--r-- | Documentation/devicetree/bindings/input/hid-over-i2c.txt | 3 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 48 | ||||
| -rw-r--r-- | include/linux/platform_data/i2c-hid.h | 7 |
3 files changed, 29 insertions, 29 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 c7d6738dc524..4f532d9238fb 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -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,9 +1121,8 @@ 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 | return ret; | 1127 | return ret; |
| 1130 | } | 1128 | } |
| @@ -1147,7 +1145,8 @@ static int i2c_hid_remove(struct i2c_client *client) | |||
| 1147 | if (ihid->bufsize) | 1145 | if (ihid->bufsize) |
| 1148 | i2c_hid_free_buffers(ihid); | 1146 | i2c_hid_free_buffers(ihid); |
| 1149 | 1147 | ||
| 1150 | regulator_disable(ihid->pdata.supply); | 1148 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1149 | ihid->pdata.supplies); | ||
| 1151 | 1150 | ||
| 1152 | return 0; | 1151 | return 0; |
| 1153 | } | 1152 | } |
| @@ -1198,9 +1197,8 @@ static int i2c_hid_suspend(struct device *dev) | |||
| 1198 | hid_warn(hid, "Failed to enable irq wake: %d\n", | 1197 | hid_warn(hid, "Failed to enable irq wake: %d\n", |
| 1199 | wake_status); | 1198 | wake_status); |
| 1200 | } else { | 1199 | } else { |
| 1201 | ret = regulator_disable(ihid->pdata.supply); | 1200 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1202 | if (ret < 0) | 1201 | ihid->pdata.supplies); |
| 1203 | hid_warn(hid, "Failed to disable supply: %d\n", ret); | ||
| 1204 | } | 1202 | } |
| 1205 | 1203 | ||
| 1206 | return 0; | 1204 | return 0; |
| @@ -1215,9 +1213,11 @@ static int i2c_hid_resume(struct device *dev) | |||
| 1215 | int wake_status; | 1213 | int wake_status; |
| 1216 | 1214 | ||
| 1217 | if (!device_may_wakeup(&client->dev)) { | 1215 | if (!device_may_wakeup(&client->dev)) { |
| 1218 | ret = regulator_enable(ihid->pdata.supply); | 1216 | ret = regulator_bulk_enable(ARRAY_SIZE(ihid->pdata.supplies), |
| 1219 | if (ret < 0) | 1217 | ihid->pdata.supplies); |
| 1220 | 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 | |||
| 1221 | if (ihid->pdata.post_power_delay_ms) | 1221 | if (ihid->pdata.post_power_delay_ms) |
| 1222 | msleep(ihid->pdata.post_power_delay_ms); | 1222 | msleep(ihid->pdata.post_power_delay_ms); |
| 1223 | } 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 | ||
