aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-huion.c96
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