diff options
| -rw-r--r-- | drivers/hid/hid-huion.c | 96 |
1 files changed, 49 insertions, 47 deletions
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c index 60f44cd1b0ed..a683d4b4a531 100644 --- a/drivers/hid/hid-huion.c +++ b/drivers/hid/hid-huion.c | |||
| @@ -116,6 +116,10 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
| 116 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | 116 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); |
| 117 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); | 117 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); |
| 118 | __le16 buf[6]; | 118 | __le16 buf[6]; |
| 119 | s32 params[HUION_PH_ID_NUM]; | ||
| 120 | s32 resolution; | ||
| 121 | __u8 *p; | ||
| 122 | s32 v; | ||
| 119 | 123 | ||
| 120 | /* | 124 | /* |
| 121 | * Read string descriptor containing tablet parameters. The specific | 125 | * Read string descriptor containing tablet parameters. The specific |
| @@ -128,56 +132,54 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
| 128 | (USB_DT_STRING << 8) + 0x64, | 132 | (USB_DT_STRING << 8) + 0x64, |
| 129 | 0x0409, buf, sizeof(buf), | 133 | 0x0409, buf, sizeof(buf), |
| 130 | USB_CTRL_GET_TIMEOUT); | 134 | USB_CTRL_GET_TIMEOUT); |
| 131 | if (rc == -EPIPE) | 135 | if (rc == -EPIPE) { |
| 132 | hid_warn(hdev, "device parameters not found\n"); | 136 | hid_err(hdev, "device parameters not found\n"); |
| 133 | else if (rc < 0) | 137 | return -ENODEV; |
| 134 | hid_warn(hdev, "failed to get device parameters: %d\n", rc); | 138 | } else if (rc < 0) { |
| 135 | else if (rc != sizeof(buf)) | 139 | hid_err(hdev, "failed to get device parameters: %d\n", rc); |
| 136 | hid_warn(hdev, "invalid device parameters\n"); | 140 | return -ENODEV; |
| 137 | else { | 141 | } else if (rc != sizeof(buf)) { |
| 138 | s32 params[HUION_PH_ID_NUM]; | 142 | hid_err(hdev, "invalid device parameters\n"); |
| 139 | s32 resolution; | 143 | return -ENODEV; |
| 140 | __u8 *p; | 144 | } |
| 141 | s32 v; | ||
| 142 | 145 | ||
| 143 | /* Extract device parameters */ | 146 | /* Extract device parameters */ |
| 144 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); | 147 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); |
| 145 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); | 148 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); |
| 146 | params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); | 149 | params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); |
| 147 | resolution = le16_to_cpu(buf[5]); | 150 | resolution = le16_to_cpu(buf[5]); |
| 148 | if (resolution == 0) { | 151 | if (resolution == 0) { |
| 149 | params[HUION_PH_ID_X_PM] = 0; | 152 | params[HUION_PH_ID_X_PM] = 0; |
| 150 | params[HUION_PH_ID_Y_PM] = 0; | 153 | params[HUION_PH_ID_Y_PM] = 0; |
| 151 | } else { | 154 | } else { |
| 152 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * | 155 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * |
| 153 | 1000 / resolution; | 156 | 1000 / resolution; |
| 154 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * | 157 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * |
| 155 | 1000 / resolution; | 158 | 1000 / resolution; |
| 156 | } | 159 | } |
| 157 | 160 | ||
| 158 | /* Allocate fixed report descriptor */ | 161 | /* Allocate fixed report descriptor */ |
| 159 | drvdata->rdesc = devm_kmalloc(&hdev->dev, | 162 | drvdata->rdesc = devm_kmalloc(&hdev->dev, |
| 160 | sizeof(huion_tablet_rdesc_template), | 163 | sizeof(huion_tablet_rdesc_template), |
| 161 | GFP_KERNEL); | 164 | GFP_KERNEL); |
| 162 | if (drvdata->rdesc == NULL) { | 165 | if (drvdata->rdesc == NULL) { |
| 163 | hid_err(hdev, "failed to allocate fixed rdesc\n"); | 166 | hid_err(hdev, "failed to allocate fixed rdesc\n"); |
| 164 | return -ENOMEM; | 167 | return -ENOMEM; |
| 165 | } | 168 | } |
| 166 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | 169 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); |
| 167 | 170 | ||
| 168 | /* Format fixed report descriptor */ | 171 | /* Format fixed report descriptor */ |
| 169 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, | 172 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, |
| 170 | drvdata->rsize); | 173 | drvdata->rsize); |
| 171 | for (p = drvdata->rdesc; | 174 | for (p = drvdata->rdesc; |
| 172 | p <= drvdata->rdesc + drvdata->rsize - 4;) { | 175 | p <= drvdata->rdesc + drvdata->rsize - 4;) { |
| 173 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && | 176 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && |
| 174 | p[3] < sizeof(params)) { | 177 | p[3] < sizeof(params)) { |
| 175 | v = params[p[3]]; | 178 | v = params[p[3]]; |
| 176 | put_unaligned(cpu_to_le32(v), (s32 *)p); | 179 | put_unaligned(cpu_to_le32(v), (s32 *)p); |
| 177 | p += 4; | 180 | p += 4; |
| 178 | } else { | 181 | } else { |
| 179 | p++; | 182 | p++; |
| 180 | } | ||
| 181 | } | 183 | } |
| 182 | } | 184 | } |
| 183 | 185 | ||
