aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/wacom_sys.c
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2015-06-15 21:01:45 -0400
committerJiri Kosina <jkosina@suse.cz>2015-06-18 04:42:40 -0400
commit2a6cdbdd4cc0da0b0190b9a43648dff7b44adc0a (patch)
treecd511d93cf8a2ecfb09f527a930376de7ab2743d /drivers/hid/wacom_sys.c
parent2636a3f2d1421e3e629dfc96489c23727bab17d7 (diff)
HID: wacom: Introduce new 'touch_input' device
Instead of having a single 'input_dev' device that will take either pen or touch data depending on the type of the device, create seperate devices devices for each. By splitting things like this, we can support devices (e.g. the I2C "AES" sensors in some newer tablet PCs) that send both pen and touch reports from a single endpoint. Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/wacom_sys.c')
-rw-r--r--drivers/hid/wacom_sys.c116
1 files changed, 70 insertions, 46 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index ca15c7f59dc7..4c0ffca97bef 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -253,7 +253,7 @@ static void wacom_post_parse_hid(struct hid_device *hdev,
253 if (features->type == HID_GENERIC) { 253 if (features->type == HID_GENERIC) {
254 /* Any last-minute generic device setup */ 254 /* Any last-minute generic device setup */
255 if (features->touch_max > 1) { 255 if (features->touch_max > 1) {
256 input_mt_init_slots(wacom_wac->input, wacom_wac->features.touch_max, 256 input_mt_init_slots(wacom_wac->touch_input, wacom_wac->features.touch_max,
257 INPUT_MT_DIRECT); 257 INPUT_MT_DIRECT);
258 } 258 }
259 } 259 }
@@ -1130,7 +1130,7 @@ static struct input_dev *wacom_allocate_input(struct wacom *wacom)
1130 if (!input_dev) 1130 if (!input_dev)
1131 return NULL; 1131 return NULL;
1132 1132
1133 input_dev->name = wacom_wac->name; 1133 input_dev->name = wacom_wac->pen_name;
1134 input_dev->phys = hdev->phys; 1134 input_dev->phys = hdev->phys;
1135 input_dev->dev.parent = &hdev->dev; 1135 input_dev->dev.parent = &hdev->dev;
1136 input_dev->open = wacom_open; 1136 input_dev->open = wacom_open;
@@ -1149,27 +1149,33 @@ static void wacom_free_inputs(struct wacom *wacom)
1149{ 1149{
1150 struct wacom_wac *wacom_wac = &(wacom->wacom_wac); 1150 struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
1151 1151
1152 if (wacom_wac->input) 1152 if (wacom_wac->pen_input)
1153 input_free_device(wacom_wac->input); 1153 input_free_device(wacom_wac->pen_input);
1154 if (wacom_wac->touch_input)
1155 input_free_device(wacom_wac->touch_input);
1154 if (wacom_wac->pad_input) 1156 if (wacom_wac->pad_input)
1155 input_free_device(wacom_wac->pad_input); 1157 input_free_device(wacom_wac->pad_input);
1156 wacom_wac->input = NULL; 1158 wacom_wac->pen_input = NULL;
1159 wacom_wac->touch_input = NULL;
1157 wacom_wac->pad_input = NULL; 1160 wacom_wac->pad_input = NULL;
1158} 1161}
1159 1162
1160static int wacom_allocate_inputs(struct wacom *wacom) 1163static int wacom_allocate_inputs(struct wacom *wacom)
1161{ 1164{
1162 struct input_dev *input_dev, *pad_input_dev; 1165 struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev;
1163 struct wacom_wac *wacom_wac = &(wacom->wacom_wac); 1166 struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
1164 1167
1165 input_dev = wacom_allocate_input(wacom); 1168 pen_input_dev = wacom_allocate_input(wacom);
1169 touch_input_dev = wacom_allocate_input(wacom);
1166 pad_input_dev = wacom_allocate_input(wacom); 1170 pad_input_dev = wacom_allocate_input(wacom);
1167 if (!input_dev || !pad_input_dev) { 1171 if (!pen_input_dev || !touch_input_dev || !pad_input_dev) {
1168 wacom_free_inputs(wacom); 1172 wacom_free_inputs(wacom);
1169 return -ENOMEM; 1173 return -ENOMEM;
1170 } 1174 }
1171 1175
1172 wacom_wac->input = input_dev; 1176 wacom_wac->pen_input = pen_input_dev;
1177 wacom_wac->touch_input = touch_input_dev;
1178 wacom_wac->touch_input->name = wacom_wac->touch_name;
1173 wacom_wac->pad_input = pad_input_dev; 1179 wacom_wac->pad_input = pad_input_dev;
1174 wacom_wac->pad_input->name = wacom_wac->pad_name; 1180 wacom_wac->pad_input->name = wacom_wac->pad_name;
1175 1181
@@ -1178,11 +1184,17 @@ static int wacom_allocate_inputs(struct wacom *wacom)
1178 1184
1179static void wacom_clean_inputs(struct wacom *wacom) 1185static void wacom_clean_inputs(struct wacom *wacom)
1180{ 1186{
1181 if (wacom->wacom_wac.input) { 1187 if (wacom->wacom_wac.pen_input) {
1182 if (wacom->wacom_wac.input_registered) 1188 if (wacom->wacom_wac.pen_registered)
1183 input_unregister_device(wacom->wacom_wac.input); 1189 input_unregister_device(wacom->wacom_wac.pen_input);
1184 else 1190 else
1185 input_free_device(wacom->wacom_wac.input); 1191 input_free_device(wacom->wacom_wac.pen_input);
1192 }
1193 if (wacom->wacom_wac.touch_input) {
1194 if (wacom->wacom_wac.touch_registered)
1195 input_unregister_device(wacom->wacom_wac.touch_input);
1196 else
1197 input_free_device(wacom->wacom_wac.touch_input);
1186 } 1198 }
1187 if (wacom->wacom_wac.pad_input) { 1199 if (wacom->wacom_wac.pad_input) {
1188 if (wacom->wacom_wac.pad_registered) 1200 if (wacom->wacom_wac.pad_registered)
@@ -1190,33 +1202,49 @@ static void wacom_clean_inputs(struct wacom *wacom)
1190 else 1202 else
1191 input_free_device(wacom->wacom_wac.pad_input); 1203 input_free_device(wacom->wacom_wac.pad_input);
1192 } 1204 }
1193 wacom->wacom_wac.input = NULL; 1205 wacom->wacom_wac.pen_input = NULL;
1206 wacom->wacom_wac.touch_input = NULL;
1194 wacom->wacom_wac.pad_input = NULL; 1207 wacom->wacom_wac.pad_input = NULL;
1195 wacom_destroy_leds(wacom); 1208 wacom_destroy_leds(wacom);
1196} 1209}
1197 1210
1198static int wacom_register_inputs(struct wacom *wacom) 1211static int wacom_register_inputs(struct wacom *wacom)
1199{ 1212{
1200 struct input_dev *input_dev, *pad_input_dev; 1213 struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev;
1201 struct wacom_wac *wacom_wac = &(wacom->wacom_wac); 1214 struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
1202 struct wacom_features *features = &wacom_wac->features;
1203 int error = 0; 1215 int error = 0;
1204 1216
1205 input_dev = wacom_wac->input; 1217 pen_input_dev = wacom_wac->pen_input;
1218 touch_input_dev = wacom_wac->touch_input;
1206 pad_input_dev = wacom_wac->pad_input; 1219 pad_input_dev = wacom_wac->pad_input;
1207 1220
1208 if (!input_dev || !pad_input_dev) 1221 if (!pen_input_dev || !touch_input_dev || !pad_input_dev)
1209 return -EINVAL; 1222 return -EINVAL;
1210 1223
1211 if (features->device_type & WACOM_DEVICETYPE_PEN) 1224 error = wacom_setup_pen_input_capabilities(pen_input_dev, wacom_wac);
1212 error = wacom_setup_pen_input_capabilities(input_dev, wacom_wac); 1225 if (error) {
1213 if (!error && features->device_type & WACOM_DEVICETYPE_TOUCH) 1226 /* no pen in use on this interface */
1214 error = wacom_setup_touch_input_capabilities(input_dev, wacom_wac); 1227 input_free_device(pen_input_dev);
1215 if (!error) { 1228 wacom_wac->pen_input = NULL;
1216 error = input_register_device(input_dev); 1229 pen_input_dev = NULL;
1230 } else {
1231 error = input_register_device(pen_input_dev);
1232 if (error)
1233 goto fail_register_pen_input;
1234 wacom_wac->pen_registered = true;
1235 }
1236
1237 error = wacom_setup_touch_input_capabilities(touch_input_dev, wacom_wac);
1238 if (error) {
1239 /* no touch in use on this interface */
1240 input_free_device(touch_input_dev);
1241 wacom_wac->touch_input = NULL;
1242 touch_input_dev = NULL;
1243 } else {
1244 error = input_register_device(touch_input_dev);
1217 if (error) 1245 if (error)
1218 return error; 1246 goto fail_register_touch_input;
1219 wacom_wac->input_registered = true; 1247 wacom_wac->touch_registered = true;
1220 } 1248 }
1221 1249
1222 error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); 1250 error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
@@ -1243,9 +1271,14 @@ fail_leds:
1243 pad_input_dev = NULL; 1271 pad_input_dev = NULL;
1244 wacom_wac->pad_registered = false; 1272 wacom_wac->pad_registered = false;
1245fail_register_pad_input: 1273fail_register_pad_input:
1246 input_unregister_device(input_dev); 1274 input_unregister_device(touch_input_dev);
1247 wacom_wac->input = NULL; 1275 wacom_wac->touch_input = NULL;
1248 wacom_wac->input_registered = false; 1276 wacom_wac->touch_registered = false;
1277fail_register_touch_input:
1278 input_unregister_device(pen_input_dev);
1279 wacom_wac->pen_input = NULL;
1280 wacom_wac->pen_registered = false;
1281fail_register_pen_input:
1249 return error; 1282 return error;
1250} 1283}
1251 1284
@@ -1306,7 +1339,7 @@ static void wacom_wireless_work(struct work_struct *work)
1306 if (wacom_wac1->features.type != INTUOSHT && 1339 if (wacom_wac1->features.type != INTUOSHT &&
1307 wacom_wac1->features.type != BAMBOO_PT) 1340 wacom_wac1->features.type != BAMBOO_PT)
1308 wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD; 1341 wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD;
1309 snprintf(wacom_wac1->name, WACOM_NAME_MAX, "%s (WL) Pen", 1342 snprintf(wacom_wac1->pen_name, WACOM_NAME_MAX, "%s (WL) Pen",
1310 wacom_wac1->features.name); 1343 wacom_wac1->features.name);
1311 snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad", 1344 snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad",
1312 wacom_wac1->features.name); 1345 wacom_wac1->features.name);
@@ -1325,7 +1358,7 @@ static void wacom_wireless_work(struct work_struct *work)
1325 *((struct wacom_features *)id->driver_data); 1358 *((struct wacom_features *)id->driver_data);
1326 wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; 1359 wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
1327 wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; 1360 wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
1328 snprintf(wacom_wac2->name, WACOM_NAME_MAX, 1361 snprintf(wacom_wac2->touch_name, WACOM_NAME_MAX,
1329 "%s (WL) Finger",wacom_wac2->features.name); 1362 "%s (WL) Finger",wacom_wac2->features.name);
1330 snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, 1363 snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX,
1331 "%s (WL) Pad",wacom_wac2->features.name); 1364 "%s (WL) Pad",wacom_wac2->features.name);
@@ -1342,7 +1375,7 @@ static void wacom_wireless_work(struct work_struct *work)
1342 1375
1343 if (wacom_wac1->features.type == INTUOSHT && 1376 if (wacom_wac1->features.type == INTUOSHT &&
1344 wacom_wac1->features.touch_max) 1377 wacom_wac1->features.touch_max)
1345 wacom_wac->shared->touch_input = wacom_wac2->input; 1378 wacom_wac->shared->touch_input = wacom_wac2->touch_input;
1346 } 1379 }
1347 1380
1348 error = wacom_initialize_battery(wacom); 1381 error = wacom_initialize_battery(wacom);
@@ -1457,21 +1490,12 @@ static void wacom_update_name(struct wacom *wacom)
1457 } 1490 }
1458 1491
1459 /* Append the device type to the name */ 1492 /* Append the device type to the name */
1493 snprintf(wacom_wac->pen_name, sizeof(wacom_wac->pen_name),
1494 "%s Pen", name);
1495 snprintf(wacom_wac->touch_name, sizeof(wacom_wac->touch_name),
1496 "%s Finger", name);
1460 snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name), 1497 snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name),
1461 "%s Pad", name); 1498 "%s Pad", name);
1462
1463 if (features->device_type & WACOM_DEVICETYPE_PEN) {
1464 snprintf(wacom_wac->name, sizeof(wacom_wac->name),
1465 "%s Pen", name);
1466 }
1467 else if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
1468 snprintf(wacom_wac->name, sizeof(wacom_wac->name),
1469 "%s Finger", name);
1470 }
1471 else if (features->device_type & WACOM_DEVICETYPE_PAD) {
1472 snprintf(wacom_wac->name, sizeof(wacom_wac->name),
1473 "%s Pad", name);
1474 }
1475} 1499}
1476 1500
1477static int wacom_probe(struct hid_device *hdev, 1501static int wacom_probe(struct hid_device *hdev,
@@ -1615,7 +1639,7 @@ static int wacom_probe(struct hid_device *hdev,
1615 1639
1616 if (wacom_wac->features.type == INTUOSHT && 1640 if (wacom_wac->features.type == INTUOSHT &&
1617 wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) { 1641 wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) {
1618 wacom_wac->shared->touch_input = wacom_wac->input; 1642 wacom_wac->shared->touch_input = wacom_wac->touch_input;
1619 } 1643 }
1620 1644
1621 return 0; 1645 return 0;