1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/fs.h>
15#include <linux/input.h>
16#include <linux/ioctl.h>
17#include <linux/kernel.h>
18#include <linux/kfifo.h>
19#include <linux/kref.h>
20#include <linux/miscdevice.h>
21#include <linux/module.h>
22#include <linux/mutex.h>
23#include <linux/platform_device.h>
24#include <linux/poll.h>
25#include <linux/rwsem.h>
26#include <linux/slab.h>
27#include <linux/workqueue.h>
28
29#include <linux/surface_aggregator/controller.h>
30#include <linux/surface_aggregator/device.h>
31#include <linux/surface_aggregator/dtx.h>
32
33
34
35
36enum sam_event_cid_bas {
37 SAM_EVENT_CID_DTX_CONNECTION = 0x0c,
38 SAM_EVENT_CID_DTX_REQUEST = 0x0e,
39 SAM_EVENT_CID_DTX_CANCEL = 0x0f,
40 SAM_EVENT_CID_DTX_LATCH_STATUS = 0x11,
41};
42
43enum ssam_bas_base_state {
44 SSAM_BAS_BASE_STATE_DETACH_SUCCESS = 0x00,
45 SSAM_BAS_BASE_STATE_ATTACHED = 0x01,
46 SSAM_BAS_BASE_STATE_NOT_FEASIBLE = 0x02,
47};
48
49enum ssam_bas_latch_status {
50 SSAM_BAS_LATCH_STATUS_CLOSED = 0x00,
51 SSAM_BAS_LATCH_STATUS_OPENED = 0x01,
52 SSAM_BAS_LATCH_STATUS_FAILED_TO_OPEN = 0x02,
53 SSAM_BAS_LATCH_STATUS_FAILED_TO_REMAIN_OPEN = 0x03,
54 SSAM_BAS_LATCH_STATUS_FAILED_TO_CLOSE = 0x04,
55};
56
57enum ssam_bas_cancel_reason {
58 SSAM_BAS_CANCEL_REASON_NOT_FEASIBLE = 0x00,
59 SSAM_BAS_CANCEL_REASON_TIMEOUT = 0x02,
60 SSAM_BAS_CANCEL_REASON_FAILED_TO_OPEN = 0x03,
61 SSAM_BAS_CANCEL_REASON_FAILED_TO_REMAIN_OPEN = 0x04,
62 SSAM_BAS_CANCEL_REASON_FAILED_TO_CLOSE = 0x05,
63};
64
65struct ssam_bas_base_info {
66 u8 state;
67 u8 base_id;
68} __packed;
69
70static_assert(sizeof(struct ssam_bas_base_info) == 2);
71
72SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_lock, {
73 .target_category = SSAM_SSH_TC_BAS,
74 .target_id = 0x01,
75 .command_id = 0x06,
76 .instance_id = 0x00,
77});
78
79SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_unlock, {
80 .target_category = SSAM_SSH_TC_BAS,
81 .target_id = 0x01,
82 .command_id = 0x07,
83 .instance_id = 0x00,
84});
85
86SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_request, {
87 .target_category = SSAM_SSH_TC_BAS,
88 .target_id = 0x01,
89 .command_id = 0x08,
90 .instance_id = 0x00,
91});
92
93SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_confirm, {
94 .target_category = SSAM_SSH_TC_BAS,
95 .target_id = 0x01,
96 .command_id = 0x09,
97 .instance_id = 0x00,
98});
99
100SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_heartbeat, {
101 .target_category = SSAM_SSH_TC_BAS,
102 .target_id = 0x01,
103 .command_id = 0x0a,
104 .instance_id = 0x00,
105});
106
107SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_cancel, {
108 .target_category = SSAM_SSH_TC_BAS,
109 .target_id = 0x01,
110 .command_id = 0x0b,
111 .instance_id = 0x00,
112});
113
114SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_base, struct ssam_bas_base_info, {
115 .target_category = SSAM_SSH_TC_BAS,
116 .target_id = 0x01,
117 .command_id = 0x0c,
118 .instance_id = 0x00,
119});
120
121SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_device_mode, u8, {
122 .target_category = SSAM_SSH_TC_BAS,
123 .target_id = 0x01,
124 .command_id = 0x0d,
125 .instance_id = 0x00,
126});
127
128SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_latch_status, u8, {
129 .target_category = SSAM_SSH_TC_BAS,
130 .target_id = 0x01,
131 .command_id = 0x11,
132 .instance_id = 0x00,
133});
134
135
136
137
138enum sdtx_device_state {
139 SDTX_DEVICE_SHUTDOWN_BIT = BIT(0),
140 SDTX_DEVICE_DIRTY_BASE_BIT = BIT(1),
141 SDTX_DEVICE_DIRTY_MODE_BIT = BIT(2),
142 SDTX_DEVICE_DIRTY_LATCH_BIT = BIT(3),
143};
144
145struct sdtx_device {
146 struct kref kref;
147 struct rw_semaphore lock;
148
149 struct device *dev;
150 struct ssam_controller *ctrl;
151 unsigned long flags;
152
153 struct miscdevice mdev;
154 wait_queue_head_t waitq;
155 struct mutex write_lock;
156 struct rw_semaphore client_lock;
157 struct list_head client_list;
158
159 struct delayed_work state_work;
160 struct {
161 struct ssam_bas_base_info base;
162 u8 device_mode;
163 u8 latch_status;
164 } state;
165
166 struct delayed_work mode_work;
167 struct input_dev *mode_switch;
168
169 struct ssam_event_notifier notif;
170};
171
172enum sdtx_client_state {
173 SDTX_CLIENT_EVENTS_ENABLED_BIT = BIT(0),
174};
175
176struct sdtx_client {
177 struct sdtx_device *ddev;
178 struct list_head node;
179 unsigned long flags;
180
181 struct fasync_struct *fasync;
182
183 struct mutex read_lock;
184 DECLARE_KFIFO(buffer, u8, 512);
185};
186
187static void __sdtx_device_release(struct kref *kref)
188{
189 struct sdtx_device *ddev = container_of(kref, struct sdtx_device, kref);
190
191 mutex_destroy(&ddev->write_lock);
192 kfree(ddev);
193}
194
195static struct sdtx_device *sdtx_device_get(struct sdtx_device *ddev)
196{
197 if (ddev)
198 kref_get(&ddev->kref);
199
200 return ddev;
201}
202
203static void sdtx_device_put(struct sdtx_device *ddev)
204{
205 if (ddev)
206 kref_put(&ddev->kref, __sdtx_device_release);
207}
208
209
210
211
212static u16 sdtx_translate_base_state(struct sdtx_device *ddev, u8 state)
213{
214 switch (state) {
215 case SSAM_BAS_BASE_STATE_ATTACHED:
216 return SDTX_BASE_ATTACHED;
217
218 case SSAM_BAS_BASE_STATE_DETACH_SUCCESS:
219 return SDTX_BASE_DETACHED;
220
221 case SSAM_BAS_BASE_STATE_NOT_FEASIBLE:
222 return SDTX_DETACH_NOT_FEASIBLE;
223
224 default:
225 dev_err(ddev->dev, "unknown base state: %#04x\n", state);
226 return SDTX_UNKNOWN(state);
227 }
228}
229
230static u16 sdtx_translate_latch_status(struct sdtx_device *ddev, u8 status)
231{
232 switch (status) {
233 case SSAM_BAS_LATCH_STATUS_CLOSED:
234 return SDTX_LATCH_CLOSED;
235
236 case SSAM_BAS_LATCH_STATUS_OPENED:
237 return SDTX_LATCH_OPENED;
238
239 case SSAM_BAS_LATCH_STATUS_FAILED_TO_OPEN:
240 return SDTX_ERR_FAILED_TO_OPEN;
241
242 case SSAM_BAS_LATCH_STATUS_FAILED_TO_REMAIN_OPEN:
243 return SDTX_ERR_FAILED_TO_REMAIN_OPEN;
244
245 case SSAM_BAS_LATCH_STATUS_FAILED_TO_CLOSE:
246 return SDTX_ERR_FAILED_TO_CLOSE;
247
248 default:
249 dev_err(ddev->dev, "unknown latch status: %#04x\n", status);
250 return SDTX_UNKNOWN(status);
251 }
252}
253
254static u16 sdtx_translate_cancel_reason(struct sdtx_device *ddev, u8 reason)
255{
256 switch (reason) {
257 case SSAM_BAS_CANCEL_REASON_NOT_FEASIBLE:
258 return SDTX_DETACH_NOT_FEASIBLE;
259
260 case SSAM_BAS_CANCEL_REASON_TIMEOUT:
261 return SDTX_DETACH_TIMEDOUT;
262
263 case SSAM_BAS_CANCEL_REASON_FAILED_TO_OPEN:
264 return SDTX_ERR_FAILED_TO_OPEN;
265
266 case SSAM_BAS_CANCEL_REASON_FAILED_TO_REMAIN_OPEN:
267 return SDTX_ERR_FAILED_TO_REMAIN_OPEN;
268
269 case SSAM_BAS_CANCEL_REASON_FAILED_TO_CLOSE:
270 return SDTX_ERR_FAILED_TO_CLOSE;
271
272 default:
273 dev_err(ddev->dev, "unknown cancel reason: %#04x\n", reason);
274 return SDTX_UNKNOWN(reason);
275 }
276}
277
278
279
280
281static int sdtx_ioctl_get_base_info(struct sdtx_device *ddev,
282 struct sdtx_base_info __user *buf)
283{
284 struct ssam_bas_base_info raw;
285 struct sdtx_base_info info;
286 int status;
287
288 lockdep_assert_held_read(&ddev->lock);
289
290 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &raw);
291 if (status < 0)
292 return status;
293
294 info.state = sdtx_translate_base_state(ddev, raw.state);
295 info.base_id = SDTX_BASE_TYPE_SSH(raw.base_id);
296
297 if (copy_to_user(buf, &info, sizeof(info)))
298 return -EFAULT;
299
300 return 0;
301}
302
303static int sdtx_ioctl_get_device_mode(struct sdtx_device *ddev, u16 __user *buf)
304{
305 u8 mode;
306 int status;
307
308 lockdep_assert_held_read(&ddev->lock);
309
310 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
311 if (status < 0)
312 return status;
313
314 return put_user(mode, buf);
315}
316
317static int sdtx_ioctl_get_latch_status(struct sdtx_device *ddev, u16 __user *buf)
318{
319 u8 latch;
320 int status;
321
322 lockdep_assert_held_read(&ddev->lock);
323
324 status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &latch);
325 if (status < 0)
326 return status;
327
328 return put_user(sdtx_translate_latch_status(ddev, latch), buf);
329}
330
331static long __surface_dtx_ioctl(struct sdtx_client *client, unsigned int cmd, unsigned long arg)
332{
333 struct sdtx_device *ddev = client->ddev;
334
335 lockdep_assert_held_read(&ddev->lock);
336
337 switch (cmd) {
338 case SDTX_IOCTL_EVENTS_ENABLE:
339 set_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags);
340 return 0;
341
342 case SDTX_IOCTL_EVENTS_DISABLE:
343 clear_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags);
344 return 0;
345
346 case SDTX_IOCTL_LATCH_LOCK:
347 return ssam_retry(ssam_bas_latch_lock, ddev->ctrl);
348
349 case SDTX_IOCTL_LATCH_UNLOCK:
350 return ssam_retry(ssam_bas_latch_unlock, ddev->ctrl);
351
352 case SDTX_IOCTL_LATCH_REQUEST:
353 return ssam_retry(ssam_bas_latch_request, ddev->ctrl);
354
355 case SDTX_IOCTL_LATCH_CONFIRM:
356 return ssam_retry(ssam_bas_latch_confirm, ddev->ctrl);
357
358 case SDTX_IOCTL_LATCH_HEARTBEAT:
359 return ssam_retry(ssam_bas_latch_heartbeat, ddev->ctrl);
360
361 case SDTX_IOCTL_LATCH_CANCEL:
362 return ssam_retry(ssam_bas_latch_cancel, ddev->ctrl);
363
364 case SDTX_IOCTL_GET_BASE_INFO:
365 return sdtx_ioctl_get_base_info(ddev, (struct sdtx_base_info __user *)arg);
366
367 case SDTX_IOCTL_GET_DEVICE_MODE:
368 return sdtx_ioctl_get_device_mode(ddev, (u16 __user *)arg);
369
370 case SDTX_IOCTL_GET_LATCH_STATUS:
371 return sdtx_ioctl_get_latch_status(ddev, (u16 __user *)arg);
372
373 default:
374 return -EINVAL;
375 }
376}
377
378static long surface_dtx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
379{
380 struct sdtx_client *client = file->private_data;
381 long status;
382
383 if (down_read_killable(&client->ddev->lock))
384 return -ERESTARTSYS;
385
386 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags)) {
387 up_read(&client->ddev->lock);
388 return -ENODEV;
389 }
390
391 status = __surface_dtx_ioctl(client, cmd, arg);
392
393 up_read(&client->ddev->lock);
394 return status;
395}
396
397
398
399
400static int surface_dtx_open(struct inode *inode, struct file *file)
401{
402 struct sdtx_device *ddev = container_of(file->private_data, struct sdtx_device, mdev);
403 struct sdtx_client *client;
404
405
406 client = kzalloc(sizeof(*client), GFP_KERNEL);
407 if (!client)
408 return -ENOMEM;
409
410 client->ddev = sdtx_device_get(ddev);
411
412 INIT_LIST_HEAD(&client->node);
413
414 mutex_init(&client->read_lock);
415 INIT_KFIFO(client->buffer);
416
417 file->private_data = client;
418
419
420 down_write(&ddev->client_lock);
421
422
423
424
425
426
427
428 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
429 up_write(&ddev->client_lock);
430 mutex_destroy(&client->read_lock);
431 sdtx_device_put(client->ddev);
432 kfree(client);
433 return -ENODEV;
434 }
435
436 list_add_tail(&client->node, &ddev->client_list);
437 up_write(&ddev->client_lock);
438
439 stream_open(inode, file);
440 return 0;
441}
442
443static int surface_dtx_release(struct inode *inode, struct file *file)
444{
445 struct sdtx_client *client = file->private_data;
446
447
448 down_write(&client->ddev->client_lock);
449 list_del(&client->node);
450 up_write(&client->ddev->client_lock);
451
452
453 sdtx_device_put(client->ddev);
454 mutex_destroy(&client->read_lock);
455 kfree(client);
456
457 return 0;
458}
459
460static ssize_t surface_dtx_read(struct file *file, char __user *buf, size_t count, loff_t *offs)
461{
462 struct sdtx_client *client = file->private_data;
463 struct sdtx_device *ddev = client->ddev;
464 unsigned int copied;
465 int status = 0;
466
467 if (down_read_killable(&ddev->lock))
468 return -ERESTARTSYS;
469
470
471 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
472 up_read(&ddev->lock);
473 return -ENODEV;
474 }
475
476 do {
477
478 if (kfifo_is_empty(&client->buffer)) {
479 up_read(&ddev->lock);
480
481 if (file->f_flags & O_NONBLOCK)
482 return -EAGAIN;
483
484 status = wait_event_interruptible(ddev->waitq,
485 !kfifo_is_empty(&client->buffer) ||
486 test_bit(SDTX_DEVICE_SHUTDOWN_BIT,
487 &ddev->flags));
488 if (status < 0)
489 return status;
490
491 if (down_read_killable(&ddev->lock))
492 return -ERESTARTSYS;
493
494
495 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
496 up_read(&ddev->lock);
497 return -ENODEV;
498 }
499 }
500
501
502 if (mutex_lock_interruptible(&client->read_lock)) {
503 up_read(&ddev->lock);
504 return -ERESTARTSYS;
505 }
506
507 status = kfifo_to_user(&client->buffer, buf, count, &copied);
508 mutex_unlock(&client->read_lock);
509
510 if (status < 0) {
511 up_read(&ddev->lock);
512 return status;
513 }
514
515
516 if (copied == 0 && (file->f_flags & O_NONBLOCK)) {
517 up_read(&ddev->lock);
518 return -EAGAIN;
519 }
520 } while (copied == 0);
521
522 up_read(&ddev->lock);
523 return copied;
524}
525
526static __poll_t surface_dtx_poll(struct file *file, struct poll_table_struct *pt)
527{
528 struct sdtx_client *client = file->private_data;
529 __poll_t events = 0;
530
531 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags))
532 return EPOLLHUP | EPOLLERR;
533
534 poll_wait(file, &client->ddev->waitq, pt);
535
536 if (!kfifo_is_empty(&client->buffer))
537 events |= EPOLLIN | EPOLLRDNORM;
538
539 return events;
540}
541
542static int surface_dtx_fasync(int fd, struct file *file, int on)
543{
544 struct sdtx_client *client = file->private_data;
545
546 return fasync_helper(fd, file, on, &client->fasync);
547}
548
549static const struct file_operations surface_dtx_fops = {
550 .owner = THIS_MODULE,
551 .open = surface_dtx_open,
552 .release = surface_dtx_release,
553 .read = surface_dtx_read,
554 .poll = surface_dtx_poll,
555 .fasync = surface_dtx_fasync,
556 .unlocked_ioctl = surface_dtx_ioctl,
557 .compat_ioctl = surface_dtx_ioctl,
558 .llseek = no_llseek,
559};
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575#define SDTX_DEVICE_MODE_DELAY_CONNECT msecs_to_jiffies(100)
576#define SDTX_DEVICE_MODE_DELAY_RECHECK msecs_to_jiffies(100)
577
578struct sdtx_status_event {
579 struct sdtx_event e;
580 __u16 v;
581} __packed;
582
583struct sdtx_base_info_event {
584 struct sdtx_event e;
585 struct sdtx_base_info v;
586} __packed;
587
588union sdtx_generic_event {
589 struct sdtx_event common;
590 struct sdtx_status_event status;
591 struct sdtx_base_info_event base;
592};
593
594static void sdtx_update_device_mode(struct sdtx_device *ddev, unsigned long delay);
595
596
597static void sdtx_push_event(struct sdtx_device *ddev, struct sdtx_event *evt)
598{
599 const size_t len = sizeof(struct sdtx_event) + evt->length;
600 struct sdtx_client *client;
601
602 lockdep_assert_held(&ddev->write_lock);
603
604 down_read(&ddev->client_lock);
605 list_for_each_entry(client, &ddev->client_list, node) {
606 if (!test_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags))
607 continue;
608
609 if (likely(kfifo_avail(&client->buffer) >= len))
610 kfifo_in(&client->buffer, (const u8 *)evt, len);
611 else
612 dev_warn(ddev->dev, "event buffer overrun\n");
613
614 kill_fasync(&client->fasync, SIGIO, POLL_IN);
615 }
616 up_read(&ddev->client_lock);
617
618 wake_up_interruptible(&ddev->waitq);
619}
620
621static u32 sdtx_notifier(struct ssam_event_notifier *nf, const struct ssam_event *in)
622{
623 struct sdtx_device *ddev = container_of(nf, struct sdtx_device, notif);
624 union sdtx_generic_event event;
625 size_t len;
626
627
628 switch (in->command_id) {
629 case SAM_EVENT_CID_DTX_CONNECTION:
630 len = 2 * sizeof(u8);
631 break;
632
633 case SAM_EVENT_CID_DTX_REQUEST:
634 len = 0;
635 break;
636
637 case SAM_EVENT_CID_DTX_CANCEL:
638 len = sizeof(u8);
639 break;
640
641 case SAM_EVENT_CID_DTX_LATCH_STATUS:
642 len = sizeof(u8);
643 break;
644
645 default:
646 return 0;
647 }
648
649 if (in->length != len) {
650 dev_err(ddev->dev,
651 "unexpected payload size for event %#04x: got %u, expected %zu\n",
652 in->command_id, in->length, len);
653 return 0;
654 }
655
656 mutex_lock(&ddev->write_lock);
657
658
659 switch (in->command_id) {
660 case SAM_EVENT_CID_DTX_CONNECTION:
661 clear_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags);
662
663
664 if (ddev->state.base.state == in->data[0] &&
665 ddev->state.base.base_id == in->data[1])
666 goto out;
667
668 ddev->state.base.state = in->data[0];
669 ddev->state.base.base_id = in->data[1];
670
671 event.base.e.length = sizeof(struct sdtx_base_info);
672 event.base.e.code = SDTX_EVENT_BASE_CONNECTION;
673 event.base.v.state = sdtx_translate_base_state(ddev, in->data[0]);
674 event.base.v.base_id = SDTX_BASE_TYPE_SSH(in->data[1]);
675 break;
676
677 case SAM_EVENT_CID_DTX_REQUEST:
678 event.common.code = SDTX_EVENT_REQUEST;
679 event.common.length = 0;
680 break;
681
682 case SAM_EVENT_CID_DTX_CANCEL:
683 event.status.e.length = sizeof(u16);
684 event.status.e.code = SDTX_EVENT_CANCEL;
685 event.status.v = sdtx_translate_cancel_reason(ddev, in->data[0]);
686 break;
687
688 case SAM_EVENT_CID_DTX_LATCH_STATUS:
689 clear_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags);
690
691
692 if (ddev->state.latch_status == in->data[0])
693 goto out;
694
695 ddev->state.latch_status = in->data[0];
696
697 event.status.e.length = sizeof(u16);
698 event.status.e.code = SDTX_EVENT_LATCH_STATUS;
699 event.status.v = sdtx_translate_latch_status(ddev, in->data[0]);
700 break;
701 }
702
703 sdtx_push_event(ddev, &event.common);
704
705
706 if (in->command_id == SAM_EVENT_CID_DTX_CONNECTION) {
707 unsigned long delay;
708
709 delay = in->data[0] ? SDTX_DEVICE_MODE_DELAY_CONNECT : 0;
710 sdtx_update_device_mode(ddev, delay);
711 }
712
713out:
714 mutex_unlock(&ddev->write_lock);
715 return SSAM_NOTIF_HANDLED;
716}
717
718
719
720
721static bool sdtx_device_mode_invalid(u8 mode, u8 base_state)
722{
723 return ((base_state == SSAM_BAS_BASE_STATE_ATTACHED) &&
724 (mode == SDTX_DEVICE_MODE_TABLET)) ||
725 ((base_state == SSAM_BAS_BASE_STATE_DETACH_SUCCESS) &&
726 (mode != SDTX_DEVICE_MODE_TABLET));
727}
728
729static void sdtx_device_mode_workfn(struct work_struct *work)
730{
731 struct sdtx_device *ddev = container_of(work, struct sdtx_device, mode_work.work);
732 struct sdtx_status_event event;
733 struct ssam_bas_base_info base;
734 int status, tablet;
735 u8 mode;
736
737
738 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
739 if (status) {
740 dev_err(ddev->dev, "failed to get device mode: %d\n", status);
741 return;
742 }
743
744
745 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &base);
746 if (status) {
747 dev_err(ddev->dev, "failed to get base info: %d\n", status);
748 return;
749 }
750
751
752
753
754
755
756
757 if (sdtx_device_mode_invalid(mode, base.state)) {
758 dev_dbg(ddev->dev, "device mode is invalid, trying again\n");
759 sdtx_update_device_mode(ddev, SDTX_DEVICE_MODE_DELAY_RECHECK);
760 return;
761 }
762
763 mutex_lock(&ddev->write_lock);
764 clear_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags);
765
766
767 if (ddev->state.device_mode == mode) {
768 mutex_unlock(&ddev->write_lock);
769 return;
770 }
771
772 ddev->state.device_mode = mode;
773
774 event.e.length = sizeof(u16);
775 event.e.code = SDTX_EVENT_DEVICE_MODE;
776 event.v = mode;
777
778 sdtx_push_event(ddev, &event.e);
779
780
781 tablet = mode != SDTX_DEVICE_MODE_LAPTOP;
782 input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet);
783 input_sync(ddev->mode_switch);
784
785 mutex_unlock(&ddev->write_lock);
786}
787
788static void sdtx_update_device_mode(struct sdtx_device *ddev, unsigned long delay)
789{
790 schedule_delayed_work(&ddev->mode_work, delay);
791}
792
793
794static void __sdtx_device_state_update_base(struct sdtx_device *ddev,
795 struct ssam_bas_base_info info)
796{
797 struct sdtx_base_info_event event;
798
799 lockdep_assert_held(&ddev->write_lock);
800
801
802 if (ddev->state.base.state == info.state &&
803 ddev->state.base.base_id == info.base_id)
804 return;
805
806 ddev->state.base = info;
807
808 event.e.length = sizeof(struct sdtx_base_info);
809 event.e.code = SDTX_EVENT_BASE_CONNECTION;
810 event.v.state = sdtx_translate_base_state(ddev, info.state);
811 event.v.base_id = SDTX_BASE_TYPE_SSH(info.base_id);
812
813 sdtx_push_event(ddev, &event.e);
814}
815
816
817static void __sdtx_device_state_update_mode(struct sdtx_device *ddev, u8 mode)
818{
819 struct sdtx_status_event event;
820 int tablet;
821
822
823
824
825
826
827
828 lockdep_assert_held(&ddev->write_lock);
829
830 if (sdtx_device_mode_invalid(mode, ddev->state.base.state)) {
831 dev_dbg(ddev->dev, "device mode is invalid, trying again\n");
832 sdtx_update_device_mode(ddev, SDTX_DEVICE_MODE_DELAY_RECHECK);
833 return;
834 }
835
836
837 if (ddev->state.device_mode == mode)
838 return;
839
840 ddev->state.device_mode = mode;
841
842
843 event.e.length = sizeof(u16);
844 event.e.code = SDTX_EVENT_DEVICE_MODE;
845 event.v = mode;
846
847 sdtx_push_event(ddev, &event.e);
848
849
850 tablet = mode != SDTX_DEVICE_MODE_LAPTOP;
851 input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet);
852 input_sync(ddev->mode_switch);
853}
854
855
856static void __sdtx_device_state_update_latch(struct sdtx_device *ddev, u8 status)
857{
858 struct sdtx_status_event event;
859
860 lockdep_assert_held(&ddev->write_lock);
861
862
863 if (ddev->state.latch_status == status)
864 return;
865
866 ddev->state.latch_status = status;
867
868 event.e.length = sizeof(struct sdtx_base_info);
869 event.e.code = SDTX_EVENT_BASE_CONNECTION;
870 event.v = sdtx_translate_latch_status(ddev, status);
871
872 sdtx_push_event(ddev, &event.e);
873}
874
875static void sdtx_device_state_workfn(struct work_struct *work)
876{
877 struct sdtx_device *ddev = container_of(work, struct sdtx_device, state_work.work);
878 struct ssam_bas_base_info base;
879 u8 mode, latch;
880 int status;
881
882
883 set_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags);
884 set_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags);
885 set_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags);
886
887
888
889
890
891
892
893 smp_mb__after_atomic();
894
895 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &base);
896 if (status) {
897 dev_err(ddev->dev, "failed to get base state: %d\n", status);
898 return;
899 }
900
901 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
902 if (status) {
903 dev_err(ddev->dev, "failed to get device mode: %d\n", status);
904 return;
905 }
906
907 status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &latch);
908 if (status) {
909 dev_err(ddev->dev, "failed to get latch status: %d\n", status);
910 return;
911 }
912
913 mutex_lock(&ddev->write_lock);
914
915
916
917
918
919
920
921
922
923 if (test_and_clear_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags))
924 __sdtx_device_state_update_base(ddev, base);
925
926 if (test_and_clear_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags))
927 __sdtx_device_state_update_mode(ddev, mode);
928
929 if (test_and_clear_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags))
930 __sdtx_device_state_update_latch(ddev, latch);
931
932 mutex_unlock(&ddev->write_lock);
933}
934
935static void sdtx_update_device_state(struct sdtx_device *ddev, unsigned long delay)
936{
937 schedule_delayed_work(&ddev->state_work, delay);
938}
939
940
941
942
943static int sdtx_device_init(struct sdtx_device *ddev, struct device *dev,
944 struct ssam_controller *ctrl)
945{
946 int status, tablet_mode;
947
948
949 kref_init(&ddev->kref);
950 init_rwsem(&ddev->lock);
951 ddev->dev = dev;
952 ddev->ctrl = ctrl;
953
954 ddev->mdev.minor = MISC_DYNAMIC_MINOR;
955 ddev->mdev.name = "surface_dtx";
956 ddev->mdev.nodename = "surface/dtx";
957 ddev->mdev.fops = &surface_dtx_fops;
958
959 ddev->notif.base.priority = 1;
960 ddev->notif.base.fn = sdtx_notifier;
961 ddev->notif.event.reg = SSAM_EVENT_REGISTRY_SAM;
962 ddev->notif.event.id.target_category = SSAM_SSH_TC_BAS;
963 ddev->notif.event.id.instance = 0;
964 ddev->notif.event.mask = SSAM_EVENT_MASK_NONE;
965 ddev->notif.event.flags = SSAM_EVENT_SEQUENCED;
966
967 init_waitqueue_head(&ddev->waitq);
968 mutex_init(&ddev->write_lock);
969 init_rwsem(&ddev->client_lock);
970 INIT_LIST_HEAD(&ddev->client_list);
971
972 INIT_DELAYED_WORK(&ddev->mode_work, sdtx_device_mode_workfn);
973 INIT_DELAYED_WORK(&ddev->state_work, sdtx_device_state_workfn);
974
975
976
977
978
979
980
981
982
983
984
985
986 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &ddev->state.base);
987 if (status)
988 return status;
989
990 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &ddev->state.device_mode);
991 if (status)
992 return status;
993
994 status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &ddev->state.latch_status);
995 if (status)
996 return status;
997
998
999 ddev->mode_switch = input_allocate_device();
1000 if (!ddev->mode_switch)
1001 return -ENOMEM;
1002
1003 ddev->mode_switch->name = "Microsoft Surface DTX Device Mode Switch";
1004 ddev->mode_switch->phys = "ssam/01:11:01:00:00/input0";
1005 ddev->mode_switch->id.bustype = BUS_HOST;
1006 ddev->mode_switch->dev.parent = ddev->dev;
1007
1008 tablet_mode = (ddev->state.device_mode != SDTX_DEVICE_MODE_LAPTOP);
1009 input_set_capability(ddev->mode_switch, EV_SW, SW_TABLET_MODE);
1010 input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet_mode);
1011
1012 status = input_register_device(ddev->mode_switch);
1013 if (status) {
1014 input_free_device(ddev->mode_switch);
1015 return status;
1016 }
1017
1018
1019 status = ssam_notifier_register(ddev->ctrl, &ddev->notif);
1020 if (status)
1021 goto err_notif;
1022
1023
1024 status = misc_register(&ddev->mdev);
1025 if (status)
1026 goto err_mdev;
1027
1028
1029
1030
1031
1032 sdtx_update_device_state(ddev, 0);
1033 return 0;
1034
1035err_notif:
1036 ssam_notifier_unregister(ddev->ctrl, &ddev->notif);
1037 cancel_delayed_work_sync(&ddev->mode_work);
1038err_mdev:
1039 input_unregister_device(ddev->mode_switch);
1040 return status;
1041}
1042
1043static struct sdtx_device *sdtx_device_create(struct device *dev, struct ssam_controller *ctrl)
1044{
1045 struct sdtx_device *ddev;
1046 int status;
1047
1048 ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
1049 if (!ddev)
1050 return ERR_PTR(-ENOMEM);
1051
1052 status = sdtx_device_init(ddev, dev, ctrl);
1053 if (status) {
1054 sdtx_device_put(ddev);
1055 return ERR_PTR(status);
1056 }
1057
1058 return ddev;
1059}
1060
1061static void sdtx_device_destroy(struct sdtx_device *ddev)
1062{
1063 struct sdtx_client *client;
1064
1065
1066
1067
1068
1069 set_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags);
1070
1071
1072 ssam_notifier_unregister(ddev->ctrl, &ddev->notif);
1073
1074
1075 cancel_delayed_work_sync(&ddev->mode_work);
1076
1077
1078 cancel_delayed_work_sync(&ddev->state_work);
1079
1080
1081 input_unregister_device(ddev->mode_switch);
1082
1083
1084 down_write(&ddev->client_lock);
1085 list_for_each_entry(client, &ddev->client_list, node) {
1086 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
1087 }
1088 up_write(&ddev->client_lock);
1089
1090
1091 wake_up_interruptible(&ddev->waitq);
1092
1093
1094
1095
1096
1097
1098 down_write(&ddev->lock);
1099 ddev->dev = NULL;
1100 ddev->ctrl = NULL;
1101 up_write(&ddev->lock);
1102
1103
1104 misc_deregister(&ddev->mdev);
1105
1106
1107
1108
1109
1110 sdtx_device_put(ddev);
1111}
1112
1113
1114
1115
1116#ifdef CONFIG_PM_SLEEP
1117
1118static void surface_dtx_pm_complete(struct device *dev)
1119{
1120 struct sdtx_device *ddev = dev_get_drvdata(dev);
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137 sdtx_update_device_state(ddev, msecs_to_jiffies(1000));
1138}
1139
1140static const struct dev_pm_ops surface_dtx_pm_ops = {
1141 .complete = surface_dtx_pm_complete,
1142};
1143
1144#else
1145
1146static const struct dev_pm_ops surface_dtx_pm_ops = {};
1147
1148#endif
1149
1150
1151
1152
1153static int surface_dtx_platform_probe(struct platform_device *pdev)
1154{
1155 struct ssam_controller *ctrl;
1156 struct sdtx_device *ddev;
1157
1158
1159 ctrl = ssam_client_bind(&pdev->dev);
1160 if (IS_ERR(ctrl))
1161 return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl);
1162
1163 ddev = sdtx_device_create(&pdev->dev, ctrl);
1164 if (IS_ERR(ddev))
1165 return PTR_ERR(ddev);
1166
1167 platform_set_drvdata(pdev, ddev);
1168 return 0;
1169}
1170
1171static int surface_dtx_platform_remove(struct platform_device *pdev)
1172{
1173 sdtx_device_destroy(platform_get_drvdata(pdev));
1174 return 0;
1175}
1176
1177static const struct acpi_device_id surface_dtx_acpi_match[] = {
1178 { "MSHW0133", 0 },
1179 { },
1180};
1181MODULE_DEVICE_TABLE(acpi, surface_dtx_acpi_match);
1182
1183static struct platform_driver surface_dtx_platform_driver = {
1184 .probe = surface_dtx_platform_probe,
1185 .remove = surface_dtx_platform_remove,
1186 .driver = {
1187 .name = "surface_dtx_pltf",
1188 .acpi_match_table = surface_dtx_acpi_match,
1189 .pm = &surface_dtx_pm_ops,
1190 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1191 },
1192};
1193
1194
1195
1196
1197#ifdef CONFIG_SURFACE_AGGREGATOR_BUS
1198
1199static int surface_dtx_ssam_probe(struct ssam_device *sdev)
1200{
1201 struct sdtx_device *ddev;
1202
1203 ddev = sdtx_device_create(&sdev->dev, sdev->ctrl);
1204 if (IS_ERR(ddev))
1205 return PTR_ERR(ddev);
1206
1207 ssam_device_set_drvdata(sdev, ddev);
1208 return 0;
1209}
1210
1211static void surface_dtx_ssam_remove(struct ssam_device *sdev)
1212{
1213 sdtx_device_destroy(ssam_device_get_drvdata(sdev));
1214}
1215
1216static const struct ssam_device_id surface_dtx_ssam_match[] = {
1217 { SSAM_SDEV(BAS, 0x01, 0x00, 0x00) },
1218 { },
1219};
1220MODULE_DEVICE_TABLE(ssam, surface_dtx_ssam_match);
1221
1222static struct ssam_device_driver surface_dtx_ssam_driver = {
1223 .probe = surface_dtx_ssam_probe,
1224 .remove = surface_dtx_ssam_remove,
1225 .match_table = surface_dtx_ssam_match,
1226 .driver = {
1227 .name = "surface_dtx",
1228 .pm = &surface_dtx_pm_ops,
1229 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1230 },
1231};
1232
1233static int ssam_dtx_driver_register(void)
1234{
1235 return ssam_device_driver_register(&surface_dtx_ssam_driver);
1236}
1237
1238static void ssam_dtx_driver_unregister(void)
1239{
1240 ssam_device_driver_unregister(&surface_dtx_ssam_driver);
1241}
1242
1243#else
1244
1245static int ssam_dtx_driver_register(void)
1246{
1247 return 0;
1248}
1249
1250static void ssam_dtx_driver_unregister(void)
1251{
1252}
1253
1254#endif
1255
1256
1257
1258
1259static int __init surface_dtx_init(void)
1260{
1261 int status;
1262
1263 status = ssam_dtx_driver_register();
1264 if (status)
1265 return status;
1266
1267 status = platform_driver_register(&surface_dtx_platform_driver);
1268 if (status)
1269 ssam_dtx_driver_unregister();
1270
1271 return status;
1272}
1273module_init(surface_dtx_init);
1274
1275static void __exit surface_dtx_exit(void)
1276{
1277 platform_driver_unregister(&surface_dtx_platform_driver);
1278 ssam_dtx_driver_unregister();
1279}
1280module_exit(surface_dtx_exit);
1281
1282MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
1283MODULE_DESCRIPTION("Detachment-system driver for Surface System Aggregator Module");
1284MODULE_LICENSE("GPL");
1285