.. | .. |
---|
26 | 26 | #include <linux/delay.h> |
---|
27 | 27 | #include <linux/slab.h> |
---|
28 | 28 | #include <linux/pm.h> |
---|
29 | | -#include <linux/pm_runtime.h> |
---|
30 | 29 | #include <linux/device.h> |
---|
31 | 30 | #include <linux/wait.h> |
---|
32 | 31 | #include <linux/err.h> |
---|
.. | .. |
---|
48 | 47 | /* quirks to control the device */ |
---|
49 | 48 | #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) |
---|
50 | 49 | #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) |
---|
51 | | -#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) |
---|
52 | | -#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3) |
---|
53 | 50 | #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) |
---|
54 | 51 | #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) |
---|
55 | 52 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) |
---|
| 53 | +#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7) |
---|
56 | 54 | |
---|
57 | 55 | |
---|
58 | 56 | /* flags */ |
---|
.. | .. |
---|
163 | 161 | |
---|
164 | 162 | bool irq_wake_enabled; |
---|
165 | 163 | struct mutex reset_lock; |
---|
166 | | - |
---|
167 | | - unsigned long sleep_delay; |
---|
168 | 164 | }; |
---|
169 | 165 | |
---|
170 | 166 | static const struct i2c_hid_quirks { |
---|
.. | .. |
---|
172 | 168 | __u16 idProduct; |
---|
173 | 169 | __u32 quirks; |
---|
174 | 170 | } i2c_hid_quirks[] = { |
---|
175 | | - { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8752, |
---|
176 | | - I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, |
---|
177 | | - { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8755, |
---|
| 171 | + { USB_VENDOR_ID_WEIDA, HID_ANY_ID, |
---|
178 | 172 | I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, |
---|
179 | 173 | { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, |
---|
180 | | - I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | |
---|
181 | | - I2C_HID_QUIRK_NO_RUNTIME_PM }, |
---|
182 | | - { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, |
---|
183 | | - I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, |
---|
184 | | - { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001, |
---|
185 | | - I2C_HID_QUIRK_NO_RUNTIME_PM }, |
---|
186 | | - { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
---|
187 | | - I2C_HID_QUIRK_BOGUS_IRQ }, |
---|
| 174 | + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
---|
| 175 | + { I2C_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15, |
---|
| 176 | + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
---|
| 177 | + { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, |
---|
| 178 | + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
---|
188 | 179 | { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, |
---|
189 | 180 | I2C_HID_QUIRK_RESET_ON_RESUME }, |
---|
190 | 181 | { I2C_VENDOR_ID_SYNAPTICS, I2C_PRODUCT_ID_SYNAPTICS_SYNA2393, |
---|
191 | 182 | I2C_HID_QUIRK_RESET_ON_RESUME }, |
---|
192 | 183 | { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, |
---|
193 | 184 | I2C_HID_QUIRK_BAD_INPUT_SIZE }, |
---|
| 185 | + /* |
---|
| 186 | + * Sending the wakeup after reset actually break ELAN touchscreen controller |
---|
| 187 | + */ |
---|
| 188 | + { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
---|
| 189 | + I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | |
---|
| 190 | + I2C_HID_QUIRK_BOGUS_IRQ }, |
---|
194 | 191 | { 0, 0 } |
---|
195 | 192 | }; |
---|
196 | 193 | |
---|
.. | .. |
---|
333 | 330 | * @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT |
---|
334 | 331 | * @reportID: the report ID |
---|
335 | 332 | * @buf: the actual data to transfer, without the report ID |
---|
336 | | - * @len: size of buf |
---|
| 333 | + * @data_len: size of buf |
---|
337 | 334 | * @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report |
---|
338 | 335 | */ |
---|
339 | 336 | static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType, |
---|
.. | .. |
---|
406 | 403 | { |
---|
407 | 404 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
---|
408 | 405 | int ret; |
---|
409 | | - unsigned long now, delay; |
---|
410 | 406 | |
---|
411 | 407 | i2c_hid_dbg(ihid, "%s\n", __func__); |
---|
412 | 408 | |
---|
.. | .. |
---|
424 | 420 | goto set_pwr_exit; |
---|
425 | 421 | } |
---|
426 | 422 | |
---|
427 | | - if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && |
---|
428 | | - power_state == I2C_HID_PWR_ON) { |
---|
429 | | - now = jiffies; |
---|
430 | | - if (time_after(ihid->sleep_delay, now)) { |
---|
431 | | - delay = jiffies_to_usecs(ihid->sleep_delay - now); |
---|
432 | | - usleep_range(delay, delay + 1); |
---|
433 | | - } |
---|
434 | | - } |
---|
435 | | - |
---|
436 | 423 | ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, |
---|
437 | 424 | 0, NULL, 0, NULL, 0); |
---|
438 | | - |
---|
439 | | - if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && |
---|
440 | | - power_state == I2C_HID_PWR_SLEEP) |
---|
441 | | - ihid->sleep_delay = jiffies + msecs_to_jiffies(20); |
---|
442 | 425 | |
---|
443 | 426 | if (ret) |
---|
444 | 427 | dev_err(&client->dev, "failed to change power setting.\n"); |
---|
.. | .. |
---|
484 | 467 | if (ret) { |
---|
485 | 468 | dev_err(&client->dev, "failed to reset device.\n"); |
---|
486 | 469 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
---|
| 470 | + goto out_unlock; |
---|
487 | 471 | } |
---|
| 472 | + |
---|
| 473 | + /* At least some SIS devices need this after reset */ |
---|
| 474 | + if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET)) |
---|
| 475 | + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); |
---|
488 | 476 | |
---|
489 | 477 | out_unlock: |
---|
490 | 478 | mutex_unlock(&ihid->reset_lock); |
---|
.. | .. |
---|
632 | 620 | if (report_type == HID_OUTPUT_REPORT) |
---|
633 | 621 | return -EINVAL; |
---|
634 | 622 | |
---|
| 623 | + /* |
---|
| 624 | + * In case of unnumbered reports the response from the device will |
---|
| 625 | + * not have the report ID that the upper layers expect, so we need |
---|
| 626 | + * to stash it the buffer ourselves and adjust the data size. |
---|
| 627 | + */ |
---|
| 628 | + if (!report_number) { |
---|
| 629 | + buf[0] = 0; |
---|
| 630 | + buf++; |
---|
| 631 | + count--; |
---|
| 632 | + } |
---|
| 633 | + |
---|
635 | 634 | /* +2 bytes to include the size of the reply in the query buffer */ |
---|
636 | 635 | ask_count = min(count + 2, (size_t)ihid->bufsize); |
---|
637 | 636 | |
---|
.. | .. |
---|
653 | 652 | count = min(count, ret_count - 2); |
---|
654 | 653 | memcpy(buf, ihid->rawbuf + 2, count); |
---|
655 | 654 | |
---|
| 655 | + if (!report_number) |
---|
| 656 | + count++; |
---|
| 657 | + |
---|
656 | 658 | return count; |
---|
657 | 659 | } |
---|
658 | 660 | |
---|
.. | .. |
---|
669 | 671 | |
---|
670 | 672 | mutex_lock(&ihid->reset_lock); |
---|
671 | 673 | |
---|
672 | | - if (report_id) { |
---|
673 | | - buf++; |
---|
674 | | - count--; |
---|
675 | | - } |
---|
676 | | - |
---|
| 674 | + /* |
---|
| 675 | + * Note that both numbered and unnumbered reports passed here |
---|
| 676 | + * are supposed to have report ID stored in the 1st byte of the |
---|
| 677 | + * buffer, so we strip it off unconditionally before passing payload |
---|
| 678 | + * to i2c_hid_set_or_send_report which takes care of encoding |
---|
| 679 | + * everything properly. |
---|
| 680 | + */ |
---|
677 | 681 | ret = i2c_hid_set_or_send_report(client, |
---|
678 | 682 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, |
---|
679 | | - report_id, buf, count, use_data); |
---|
| 683 | + report_id, buf + 1, count - 1, use_data); |
---|
680 | 684 | |
---|
681 | | - if (report_id && ret >= 0) |
---|
682 | | - ret++; /* add report_id to the number of transfered bytes */ |
---|
| 685 | + if (ret >= 0) |
---|
| 686 | + ret++; /* add report_id to the number of transferred bytes */ |
---|
683 | 687 | |
---|
684 | 688 | mutex_unlock(&ihid->reset_lock); |
---|
685 | 689 | |
---|
.. | .. |
---|
810 | 814 | { |
---|
811 | 815 | struct i2c_client *client = hid->driver_data; |
---|
812 | 816 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
---|
813 | | - int ret = 0; |
---|
814 | | - |
---|
815 | | - ret = pm_runtime_get_sync(&client->dev); |
---|
816 | | - if (ret < 0) |
---|
817 | | - return ret; |
---|
818 | 817 | |
---|
819 | 818 | set_bit(I2C_HID_STARTED, &ihid->flags); |
---|
820 | 819 | return 0; |
---|
.. | .. |
---|
826 | 825 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
---|
827 | 826 | |
---|
828 | 827 | clear_bit(I2C_HID_STARTED, &ihid->flags); |
---|
829 | | - |
---|
830 | | - /* Save some power */ |
---|
831 | | - pm_runtime_put(&client->dev); |
---|
832 | | -} |
---|
833 | | - |
---|
834 | | -static int i2c_hid_power(struct hid_device *hid, int lvl) |
---|
835 | | -{ |
---|
836 | | - struct i2c_client *client = hid->driver_data; |
---|
837 | | - struct i2c_hid *ihid = i2c_get_clientdata(client); |
---|
838 | | - |
---|
839 | | - i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl); |
---|
840 | | - |
---|
841 | | - switch (lvl) { |
---|
842 | | - case PM_HINT_FULLON: |
---|
843 | | - pm_runtime_get_sync(&client->dev); |
---|
844 | | - break; |
---|
845 | | - case PM_HINT_NORMAL: |
---|
846 | | - pm_runtime_put(&client->dev); |
---|
847 | | - break; |
---|
848 | | - } |
---|
849 | | - return 0; |
---|
850 | 828 | } |
---|
851 | 829 | |
---|
852 | 830 | struct hid_ll_driver i2c_hid_ll_driver = { |
---|
.. | .. |
---|
855 | 833 | .stop = i2c_hid_stop, |
---|
856 | 834 | .open = i2c_hid_open, |
---|
857 | 835 | .close = i2c_hid_close, |
---|
858 | | - .power = i2c_hid_power, |
---|
859 | 836 | .output_report = i2c_hid_output_report, |
---|
860 | 837 | .raw_request = i2c_hid_raw_request, |
---|
861 | 838 | }; |
---|
.. | .. |
---|
982 | 959 | acpi_device_fix_up_power(adev); |
---|
983 | 960 | } |
---|
984 | 961 | |
---|
| 962 | +static void i2c_hid_acpi_enable_wakeup(struct device *dev) |
---|
| 963 | +{ |
---|
| 964 | + if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) { |
---|
| 965 | + device_set_wakeup_capable(dev, true); |
---|
| 966 | + device_set_wakeup_enable(dev, false); |
---|
| 967 | + } |
---|
| 968 | +} |
---|
| 969 | + |
---|
| 970 | +static void i2c_hid_acpi_shutdown(struct device *dev) |
---|
| 971 | +{ |
---|
| 972 | + acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D3_COLD); |
---|
| 973 | +} |
---|
| 974 | + |
---|
985 | 975 | static const struct acpi_device_id i2c_hid_acpi_match[] = { |
---|
986 | 976 | {"ACPI0C50", 0 }, |
---|
987 | 977 | {"PNP0C50", 0 }, |
---|
.. | .. |
---|
996 | 986 | } |
---|
997 | 987 | |
---|
998 | 988 | static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {} |
---|
| 989 | + |
---|
| 990 | +static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {} |
---|
| 991 | + |
---|
| 992 | +static inline void i2c_hid_acpi_shutdown(struct device *dev) {} |
---|
999 | 993 | #endif |
---|
1000 | 994 | |
---|
1001 | 995 | #ifdef CONFIG_OF |
---|
.. | .. |
---|
1123 | 1117 | |
---|
1124 | 1118 | i2c_hid_acpi_fix_up_power(&client->dev); |
---|
1125 | 1119 | |
---|
1126 | | - pm_runtime_get_noresume(&client->dev); |
---|
1127 | | - pm_runtime_set_active(&client->dev); |
---|
1128 | | - pm_runtime_enable(&client->dev); |
---|
| 1120 | + i2c_hid_acpi_enable_wakeup(&client->dev); |
---|
| 1121 | + |
---|
1129 | 1122 | device_enable_async_suspend(&client->dev); |
---|
1130 | 1123 | |
---|
1131 | 1124 | /* Make sure there is something at this address */ |
---|
.. | .. |
---|
1133 | 1126 | if (ret < 0) { |
---|
1134 | 1127 | dev_dbg(&client->dev, "nothing at this address: %d\n", ret); |
---|
1135 | 1128 | ret = -ENXIO; |
---|
1136 | | - goto err_pm; |
---|
| 1129 | + goto err_regulator; |
---|
1137 | 1130 | } |
---|
1138 | 1131 | |
---|
1139 | 1132 | ret = i2c_hid_fetch_hid_descriptor(ihid); |
---|
1140 | 1133 | if (ret < 0) |
---|
1141 | | - goto err_pm; |
---|
| 1134 | + goto err_regulator; |
---|
1142 | 1135 | |
---|
1143 | 1136 | ret = i2c_hid_init_irq(client); |
---|
1144 | 1137 | if (ret < 0) |
---|
1145 | | - goto err_pm; |
---|
| 1138 | + goto err_regulator; |
---|
1146 | 1139 | |
---|
1147 | 1140 | hid = hid_allocate_device(); |
---|
1148 | 1141 | if (IS_ERR(hid)) { |
---|
.. | .. |
---|
1173 | 1166 | goto err_mem_free; |
---|
1174 | 1167 | } |
---|
1175 | 1168 | |
---|
1176 | | - if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM)) |
---|
1177 | | - pm_runtime_put(&client->dev); |
---|
1178 | | - |
---|
1179 | 1169 | return 0; |
---|
1180 | 1170 | |
---|
1181 | 1171 | err_mem_free: |
---|
.. | .. |
---|
1183 | 1173 | |
---|
1184 | 1174 | err_irq: |
---|
1185 | 1175 | free_irq(client->irq, ihid); |
---|
1186 | | - |
---|
1187 | | -err_pm: |
---|
1188 | | - pm_runtime_put_noidle(&client->dev); |
---|
1189 | | - pm_runtime_disable(&client->dev); |
---|
1190 | 1176 | |
---|
1191 | 1177 | err_regulator: |
---|
1192 | 1178 | regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), |
---|
.. | .. |
---|
1199 | 1185 | { |
---|
1200 | 1186 | struct i2c_hid *ihid = i2c_get_clientdata(client); |
---|
1201 | 1187 | struct hid_device *hid; |
---|
1202 | | - |
---|
1203 | | - if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM)) |
---|
1204 | | - pm_runtime_get_sync(&client->dev); |
---|
1205 | | - pm_runtime_disable(&client->dev); |
---|
1206 | | - pm_runtime_set_suspended(&client->dev); |
---|
1207 | | - pm_runtime_put_noidle(&client->dev); |
---|
1208 | 1188 | |
---|
1209 | 1189 | hid = ihid->hid; |
---|
1210 | 1190 | hid_destroy_device(hid); |
---|
.. | .. |
---|
1226 | 1206 | |
---|
1227 | 1207 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
---|
1228 | 1208 | free_irq(client->irq, ihid); |
---|
| 1209 | + |
---|
| 1210 | + i2c_hid_acpi_shutdown(&client->dev); |
---|
1229 | 1211 | } |
---|
1230 | 1212 | |
---|
1231 | 1213 | #ifdef CONFIG_PM_SLEEP |
---|
.. | .. |
---|
1238 | 1220 | int wake_status; |
---|
1239 | 1221 | |
---|
1240 | 1222 | if (hid->driver && hid->driver->suspend) { |
---|
1241 | | - /* |
---|
1242 | | - * Wake up the device so that IO issues in |
---|
1243 | | - * HID driver's suspend code can succeed. |
---|
1244 | | - */ |
---|
1245 | | - ret = pm_runtime_resume(dev); |
---|
1246 | | - if (ret < 0) |
---|
1247 | | - return ret; |
---|
1248 | | - |
---|
1249 | 1223 | ret = hid->driver->suspend(hid, PMSG_SUSPEND); |
---|
1250 | 1224 | if (ret < 0) |
---|
1251 | 1225 | return ret; |
---|
1252 | 1226 | } |
---|
1253 | 1227 | |
---|
1254 | | - if (!pm_runtime_suspended(dev)) { |
---|
1255 | | - /* Save some power */ |
---|
1256 | | - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
---|
| 1228 | + /* Save some power */ |
---|
| 1229 | + i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
---|
1257 | 1230 | |
---|
1258 | | - disable_irq(client->irq); |
---|
1259 | | - } |
---|
| 1231 | + disable_irq(client->irq); |
---|
1260 | 1232 | |
---|
1261 | 1233 | if (device_may_wakeup(&client->dev)) { |
---|
1262 | 1234 | wake_status = enable_irq_wake(client->irq); |
---|
.. | .. |
---|
1298 | 1270 | wake_status); |
---|
1299 | 1271 | } |
---|
1300 | 1272 | |
---|
1301 | | - /* We'll resume to full power */ |
---|
1302 | | - pm_runtime_disable(dev); |
---|
1303 | | - pm_runtime_set_active(dev); |
---|
1304 | | - pm_runtime_enable(dev); |
---|
1305 | | - |
---|
1306 | 1273 | enable_irq(client->irq); |
---|
1307 | 1274 | |
---|
1308 | 1275 | /* Instead of resetting device, simply powers the device on. This |
---|
.. | .. |
---|
1330 | 1297 | } |
---|
1331 | 1298 | #endif |
---|
1332 | 1299 | |
---|
1333 | | -#ifdef CONFIG_PM |
---|
1334 | | -static int i2c_hid_runtime_suspend(struct device *dev) |
---|
1335 | | -{ |
---|
1336 | | - struct i2c_client *client = to_i2c_client(dev); |
---|
1337 | | - |
---|
1338 | | - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); |
---|
1339 | | - disable_irq(client->irq); |
---|
1340 | | - return 0; |
---|
1341 | | -} |
---|
1342 | | - |
---|
1343 | | -static int i2c_hid_runtime_resume(struct device *dev) |
---|
1344 | | -{ |
---|
1345 | | - struct i2c_client *client = to_i2c_client(dev); |
---|
1346 | | - |
---|
1347 | | - enable_irq(client->irq); |
---|
1348 | | - i2c_hid_set_power(client, I2C_HID_PWR_ON); |
---|
1349 | | - return 0; |
---|
1350 | | -} |
---|
1351 | | -#endif |
---|
1352 | | - |
---|
1353 | 1300 | static const struct dev_pm_ops i2c_hid_pm = { |
---|
1354 | 1301 | SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume) |
---|
1355 | | - SET_RUNTIME_PM_OPS(i2c_hid_runtime_suspend, i2c_hid_runtime_resume, |
---|
1356 | | - NULL) |
---|
1357 | 1302 | }; |
---|
1358 | 1303 | |
---|
1359 | 1304 | static const struct i2c_device_id i2c_hid_id_table[] = { |
---|
.. | .. |
---|
1368 | 1313 | .driver = { |
---|
1369 | 1314 | .name = "i2c_hid", |
---|
1370 | 1315 | .pm = &i2c_hid_pm, |
---|
| 1316 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
---|
1371 | 1317 | .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match), |
---|
1372 | 1318 | .of_match_table = of_match_ptr(i2c_hid_of_match), |
---|
1373 | 1319 | }, |
---|