0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/fs.h>
0015 #include <linux/input.h>
0016 #include <linux/ioctl.h>
0017 #include <linux/kernel.h>
0018 #include <linux/kfifo.h>
0019 #include <linux/kref.h>
0020 #include <linux/miscdevice.h>
0021 #include <linux/module.h>
0022 #include <linux/mutex.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/poll.h>
0025 #include <linux/rwsem.h>
0026 #include <linux/slab.h>
0027 #include <linux/workqueue.h>
0028
0029 #include <linux/surface_aggregator/controller.h>
0030 #include <linux/surface_aggregator/device.h>
0031 #include <linux/surface_aggregator/dtx.h>
0032
0033
0034
0035
0036 enum sam_event_cid_bas {
0037 SAM_EVENT_CID_DTX_CONNECTION = 0x0c,
0038 SAM_EVENT_CID_DTX_REQUEST = 0x0e,
0039 SAM_EVENT_CID_DTX_CANCEL = 0x0f,
0040 SAM_EVENT_CID_DTX_LATCH_STATUS = 0x11,
0041 };
0042
0043 enum ssam_bas_base_state {
0044 SSAM_BAS_BASE_STATE_DETACH_SUCCESS = 0x00,
0045 SSAM_BAS_BASE_STATE_ATTACHED = 0x01,
0046 SSAM_BAS_BASE_STATE_NOT_FEASIBLE = 0x02,
0047 };
0048
0049 enum ssam_bas_latch_status {
0050 SSAM_BAS_LATCH_STATUS_CLOSED = 0x00,
0051 SSAM_BAS_LATCH_STATUS_OPENED = 0x01,
0052 SSAM_BAS_LATCH_STATUS_FAILED_TO_OPEN = 0x02,
0053 SSAM_BAS_LATCH_STATUS_FAILED_TO_REMAIN_OPEN = 0x03,
0054 SSAM_BAS_LATCH_STATUS_FAILED_TO_CLOSE = 0x04,
0055 };
0056
0057 enum ssam_bas_cancel_reason {
0058 SSAM_BAS_CANCEL_REASON_NOT_FEASIBLE = 0x00,
0059 SSAM_BAS_CANCEL_REASON_TIMEOUT = 0x02,
0060 SSAM_BAS_CANCEL_REASON_FAILED_TO_OPEN = 0x03,
0061 SSAM_BAS_CANCEL_REASON_FAILED_TO_REMAIN_OPEN = 0x04,
0062 SSAM_BAS_CANCEL_REASON_FAILED_TO_CLOSE = 0x05,
0063 };
0064
0065 struct ssam_bas_base_info {
0066 u8 state;
0067 u8 base_id;
0068 } __packed;
0069
0070 static_assert(sizeof(struct ssam_bas_base_info) == 2);
0071
0072 SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_lock, {
0073 .target_category = SSAM_SSH_TC_BAS,
0074 .target_id = 0x01,
0075 .command_id = 0x06,
0076 .instance_id = 0x00,
0077 });
0078
0079 SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_unlock, {
0080 .target_category = SSAM_SSH_TC_BAS,
0081 .target_id = 0x01,
0082 .command_id = 0x07,
0083 .instance_id = 0x00,
0084 });
0085
0086 SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_request, {
0087 .target_category = SSAM_SSH_TC_BAS,
0088 .target_id = 0x01,
0089 .command_id = 0x08,
0090 .instance_id = 0x00,
0091 });
0092
0093 SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_confirm, {
0094 .target_category = SSAM_SSH_TC_BAS,
0095 .target_id = 0x01,
0096 .command_id = 0x09,
0097 .instance_id = 0x00,
0098 });
0099
0100 SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_heartbeat, {
0101 .target_category = SSAM_SSH_TC_BAS,
0102 .target_id = 0x01,
0103 .command_id = 0x0a,
0104 .instance_id = 0x00,
0105 });
0106
0107 SSAM_DEFINE_SYNC_REQUEST_N(ssam_bas_latch_cancel, {
0108 .target_category = SSAM_SSH_TC_BAS,
0109 .target_id = 0x01,
0110 .command_id = 0x0b,
0111 .instance_id = 0x00,
0112 });
0113
0114 SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_base, struct ssam_bas_base_info, {
0115 .target_category = SSAM_SSH_TC_BAS,
0116 .target_id = 0x01,
0117 .command_id = 0x0c,
0118 .instance_id = 0x00,
0119 });
0120
0121 SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_device_mode, u8, {
0122 .target_category = SSAM_SSH_TC_BAS,
0123 .target_id = 0x01,
0124 .command_id = 0x0d,
0125 .instance_id = 0x00,
0126 });
0127
0128 SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_get_latch_status, u8, {
0129 .target_category = SSAM_SSH_TC_BAS,
0130 .target_id = 0x01,
0131 .command_id = 0x11,
0132 .instance_id = 0x00,
0133 });
0134
0135
0136
0137
0138 enum sdtx_device_state {
0139 SDTX_DEVICE_SHUTDOWN_BIT = BIT(0),
0140 SDTX_DEVICE_DIRTY_BASE_BIT = BIT(1),
0141 SDTX_DEVICE_DIRTY_MODE_BIT = BIT(2),
0142 SDTX_DEVICE_DIRTY_LATCH_BIT = BIT(3),
0143 };
0144
0145 struct sdtx_device {
0146 struct kref kref;
0147 struct rw_semaphore lock;
0148
0149 struct device *dev;
0150 struct ssam_controller *ctrl;
0151 unsigned long flags;
0152
0153 struct miscdevice mdev;
0154 wait_queue_head_t waitq;
0155 struct mutex write_lock;
0156 struct rw_semaphore client_lock;
0157 struct list_head client_list;
0158
0159 struct delayed_work state_work;
0160 struct {
0161 struct ssam_bas_base_info base;
0162 u8 device_mode;
0163 u8 latch_status;
0164 } state;
0165
0166 struct delayed_work mode_work;
0167 struct input_dev *mode_switch;
0168
0169 struct ssam_event_notifier notif;
0170 };
0171
0172 enum sdtx_client_state {
0173 SDTX_CLIENT_EVENTS_ENABLED_BIT = BIT(0),
0174 };
0175
0176 struct sdtx_client {
0177 struct sdtx_device *ddev;
0178 struct list_head node;
0179 unsigned long flags;
0180
0181 struct fasync_struct *fasync;
0182
0183 struct mutex read_lock;
0184 DECLARE_KFIFO(buffer, u8, 512);
0185 };
0186
0187 static void __sdtx_device_release(struct kref *kref)
0188 {
0189 struct sdtx_device *ddev = container_of(kref, struct sdtx_device, kref);
0190
0191 mutex_destroy(&ddev->write_lock);
0192 kfree(ddev);
0193 }
0194
0195 static struct sdtx_device *sdtx_device_get(struct sdtx_device *ddev)
0196 {
0197 if (ddev)
0198 kref_get(&ddev->kref);
0199
0200 return ddev;
0201 }
0202
0203 static void sdtx_device_put(struct sdtx_device *ddev)
0204 {
0205 if (ddev)
0206 kref_put(&ddev->kref, __sdtx_device_release);
0207 }
0208
0209
0210
0211
0212 static u16 sdtx_translate_base_state(struct sdtx_device *ddev, u8 state)
0213 {
0214 switch (state) {
0215 case SSAM_BAS_BASE_STATE_ATTACHED:
0216 return SDTX_BASE_ATTACHED;
0217
0218 case SSAM_BAS_BASE_STATE_DETACH_SUCCESS:
0219 return SDTX_BASE_DETACHED;
0220
0221 case SSAM_BAS_BASE_STATE_NOT_FEASIBLE:
0222 return SDTX_DETACH_NOT_FEASIBLE;
0223
0224 default:
0225 dev_err(ddev->dev, "unknown base state: %#04x\n", state);
0226 return SDTX_UNKNOWN(state);
0227 }
0228 }
0229
0230 static u16 sdtx_translate_latch_status(struct sdtx_device *ddev, u8 status)
0231 {
0232 switch (status) {
0233 case SSAM_BAS_LATCH_STATUS_CLOSED:
0234 return SDTX_LATCH_CLOSED;
0235
0236 case SSAM_BAS_LATCH_STATUS_OPENED:
0237 return SDTX_LATCH_OPENED;
0238
0239 case SSAM_BAS_LATCH_STATUS_FAILED_TO_OPEN:
0240 return SDTX_ERR_FAILED_TO_OPEN;
0241
0242 case SSAM_BAS_LATCH_STATUS_FAILED_TO_REMAIN_OPEN:
0243 return SDTX_ERR_FAILED_TO_REMAIN_OPEN;
0244
0245 case SSAM_BAS_LATCH_STATUS_FAILED_TO_CLOSE:
0246 return SDTX_ERR_FAILED_TO_CLOSE;
0247
0248 default:
0249 dev_err(ddev->dev, "unknown latch status: %#04x\n", status);
0250 return SDTX_UNKNOWN(status);
0251 }
0252 }
0253
0254 static u16 sdtx_translate_cancel_reason(struct sdtx_device *ddev, u8 reason)
0255 {
0256 switch (reason) {
0257 case SSAM_BAS_CANCEL_REASON_NOT_FEASIBLE:
0258 return SDTX_DETACH_NOT_FEASIBLE;
0259
0260 case SSAM_BAS_CANCEL_REASON_TIMEOUT:
0261 return SDTX_DETACH_TIMEDOUT;
0262
0263 case SSAM_BAS_CANCEL_REASON_FAILED_TO_OPEN:
0264 return SDTX_ERR_FAILED_TO_OPEN;
0265
0266 case SSAM_BAS_CANCEL_REASON_FAILED_TO_REMAIN_OPEN:
0267 return SDTX_ERR_FAILED_TO_REMAIN_OPEN;
0268
0269 case SSAM_BAS_CANCEL_REASON_FAILED_TO_CLOSE:
0270 return SDTX_ERR_FAILED_TO_CLOSE;
0271
0272 default:
0273 dev_err(ddev->dev, "unknown cancel reason: %#04x\n", reason);
0274 return SDTX_UNKNOWN(reason);
0275 }
0276 }
0277
0278
0279
0280
0281 static int sdtx_ioctl_get_base_info(struct sdtx_device *ddev,
0282 struct sdtx_base_info __user *buf)
0283 {
0284 struct ssam_bas_base_info raw;
0285 struct sdtx_base_info info;
0286 int status;
0287
0288 lockdep_assert_held_read(&ddev->lock);
0289
0290 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &raw);
0291 if (status < 0)
0292 return status;
0293
0294 info.state = sdtx_translate_base_state(ddev, raw.state);
0295 info.base_id = SDTX_BASE_TYPE_SSH(raw.base_id);
0296
0297 if (copy_to_user(buf, &info, sizeof(info)))
0298 return -EFAULT;
0299
0300 return 0;
0301 }
0302
0303 static int sdtx_ioctl_get_device_mode(struct sdtx_device *ddev, u16 __user *buf)
0304 {
0305 u8 mode;
0306 int status;
0307
0308 lockdep_assert_held_read(&ddev->lock);
0309
0310 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
0311 if (status < 0)
0312 return status;
0313
0314 return put_user(mode, buf);
0315 }
0316
0317 static int sdtx_ioctl_get_latch_status(struct sdtx_device *ddev, u16 __user *buf)
0318 {
0319 u8 latch;
0320 int status;
0321
0322 lockdep_assert_held_read(&ddev->lock);
0323
0324 status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &latch);
0325 if (status < 0)
0326 return status;
0327
0328 return put_user(sdtx_translate_latch_status(ddev, latch), buf);
0329 }
0330
0331 static long __surface_dtx_ioctl(struct sdtx_client *client, unsigned int cmd, unsigned long arg)
0332 {
0333 struct sdtx_device *ddev = client->ddev;
0334
0335 lockdep_assert_held_read(&ddev->lock);
0336
0337 switch (cmd) {
0338 case SDTX_IOCTL_EVENTS_ENABLE:
0339 set_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags);
0340 return 0;
0341
0342 case SDTX_IOCTL_EVENTS_DISABLE:
0343 clear_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags);
0344 return 0;
0345
0346 case SDTX_IOCTL_LATCH_LOCK:
0347 return ssam_retry(ssam_bas_latch_lock, ddev->ctrl);
0348
0349 case SDTX_IOCTL_LATCH_UNLOCK:
0350 return ssam_retry(ssam_bas_latch_unlock, ddev->ctrl);
0351
0352 case SDTX_IOCTL_LATCH_REQUEST:
0353 return ssam_retry(ssam_bas_latch_request, ddev->ctrl);
0354
0355 case SDTX_IOCTL_LATCH_CONFIRM:
0356 return ssam_retry(ssam_bas_latch_confirm, ddev->ctrl);
0357
0358 case SDTX_IOCTL_LATCH_HEARTBEAT:
0359 return ssam_retry(ssam_bas_latch_heartbeat, ddev->ctrl);
0360
0361 case SDTX_IOCTL_LATCH_CANCEL:
0362 return ssam_retry(ssam_bas_latch_cancel, ddev->ctrl);
0363
0364 case SDTX_IOCTL_GET_BASE_INFO:
0365 return sdtx_ioctl_get_base_info(ddev, (struct sdtx_base_info __user *)arg);
0366
0367 case SDTX_IOCTL_GET_DEVICE_MODE:
0368 return sdtx_ioctl_get_device_mode(ddev, (u16 __user *)arg);
0369
0370 case SDTX_IOCTL_GET_LATCH_STATUS:
0371 return sdtx_ioctl_get_latch_status(ddev, (u16 __user *)arg);
0372
0373 default:
0374 return -EINVAL;
0375 }
0376 }
0377
0378 static long surface_dtx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0379 {
0380 struct sdtx_client *client = file->private_data;
0381 long status;
0382
0383 if (down_read_killable(&client->ddev->lock))
0384 return -ERESTARTSYS;
0385
0386 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags)) {
0387 up_read(&client->ddev->lock);
0388 return -ENODEV;
0389 }
0390
0391 status = __surface_dtx_ioctl(client, cmd, arg);
0392
0393 up_read(&client->ddev->lock);
0394 return status;
0395 }
0396
0397
0398
0399
0400 static int surface_dtx_open(struct inode *inode, struct file *file)
0401 {
0402 struct sdtx_device *ddev = container_of(file->private_data, struct sdtx_device, mdev);
0403 struct sdtx_client *client;
0404
0405
0406 client = kzalloc(sizeof(*client), GFP_KERNEL);
0407 if (!client)
0408 return -ENOMEM;
0409
0410 client->ddev = sdtx_device_get(ddev);
0411
0412 INIT_LIST_HEAD(&client->node);
0413
0414 mutex_init(&client->read_lock);
0415 INIT_KFIFO(client->buffer);
0416
0417 file->private_data = client;
0418
0419
0420 down_write(&ddev->client_lock);
0421
0422
0423
0424
0425
0426
0427
0428 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
0429 up_write(&ddev->client_lock);
0430 mutex_destroy(&client->read_lock);
0431 sdtx_device_put(client->ddev);
0432 kfree(client);
0433 return -ENODEV;
0434 }
0435
0436 list_add_tail(&client->node, &ddev->client_list);
0437 up_write(&ddev->client_lock);
0438
0439 stream_open(inode, file);
0440 return 0;
0441 }
0442
0443 static int surface_dtx_release(struct inode *inode, struct file *file)
0444 {
0445 struct sdtx_client *client = file->private_data;
0446
0447
0448 down_write(&client->ddev->client_lock);
0449 list_del(&client->node);
0450 up_write(&client->ddev->client_lock);
0451
0452
0453 sdtx_device_put(client->ddev);
0454 mutex_destroy(&client->read_lock);
0455 kfree(client);
0456
0457 return 0;
0458 }
0459
0460 static ssize_t surface_dtx_read(struct file *file, char __user *buf, size_t count, loff_t *offs)
0461 {
0462 struct sdtx_client *client = file->private_data;
0463 struct sdtx_device *ddev = client->ddev;
0464 unsigned int copied;
0465 int status = 0;
0466
0467 if (down_read_killable(&ddev->lock))
0468 return -ERESTARTSYS;
0469
0470
0471 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
0472 up_read(&ddev->lock);
0473 return -ENODEV;
0474 }
0475
0476 do {
0477
0478 if (kfifo_is_empty(&client->buffer)) {
0479 up_read(&ddev->lock);
0480
0481 if (file->f_flags & O_NONBLOCK)
0482 return -EAGAIN;
0483
0484 status = wait_event_interruptible(ddev->waitq,
0485 !kfifo_is_empty(&client->buffer) ||
0486 test_bit(SDTX_DEVICE_SHUTDOWN_BIT,
0487 &ddev->flags));
0488 if (status < 0)
0489 return status;
0490
0491 if (down_read_killable(&ddev->lock))
0492 return -ERESTARTSYS;
0493
0494
0495 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &ddev->flags)) {
0496 up_read(&ddev->lock);
0497 return -ENODEV;
0498 }
0499 }
0500
0501
0502 if (mutex_lock_interruptible(&client->read_lock)) {
0503 up_read(&ddev->lock);
0504 return -ERESTARTSYS;
0505 }
0506
0507 status = kfifo_to_user(&client->buffer, buf, count, &copied);
0508 mutex_unlock(&client->read_lock);
0509
0510 if (status < 0) {
0511 up_read(&ddev->lock);
0512 return status;
0513 }
0514
0515
0516 if (copied == 0 && (file->f_flags & O_NONBLOCK)) {
0517 up_read(&ddev->lock);
0518 return -EAGAIN;
0519 }
0520 } while (copied == 0);
0521
0522 up_read(&ddev->lock);
0523 return copied;
0524 }
0525
0526 static __poll_t surface_dtx_poll(struct file *file, struct poll_table_struct *pt)
0527 {
0528 struct sdtx_client *client = file->private_data;
0529 __poll_t events = 0;
0530
0531 if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags))
0532 return EPOLLHUP | EPOLLERR;
0533
0534 poll_wait(file, &client->ddev->waitq, pt);
0535
0536 if (!kfifo_is_empty(&client->buffer))
0537 events |= EPOLLIN | EPOLLRDNORM;
0538
0539 return events;
0540 }
0541
0542 static int surface_dtx_fasync(int fd, struct file *file, int on)
0543 {
0544 struct sdtx_client *client = file->private_data;
0545
0546 return fasync_helper(fd, file, on, &client->fasync);
0547 }
0548
0549 static const struct file_operations surface_dtx_fops = {
0550 .owner = THIS_MODULE,
0551 .open = surface_dtx_open,
0552 .release = surface_dtx_release,
0553 .read = surface_dtx_read,
0554 .poll = surface_dtx_poll,
0555 .fasync = surface_dtx_fasync,
0556 .unlocked_ioctl = surface_dtx_ioctl,
0557 .compat_ioctl = surface_dtx_ioctl,
0558 .llseek = no_llseek,
0559 };
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575 #define SDTX_DEVICE_MODE_DELAY_CONNECT msecs_to_jiffies(100)
0576 #define SDTX_DEVICE_MODE_DELAY_RECHECK msecs_to_jiffies(100)
0577
0578 struct sdtx_status_event {
0579 struct sdtx_event e;
0580 __u16 v;
0581 } __packed;
0582
0583 struct sdtx_base_info_event {
0584 struct sdtx_event e;
0585 struct sdtx_base_info v;
0586 } __packed;
0587
0588 union sdtx_generic_event {
0589 struct sdtx_event common;
0590 struct sdtx_status_event status;
0591 struct sdtx_base_info_event base;
0592 };
0593
0594 static void sdtx_update_device_mode(struct sdtx_device *ddev, unsigned long delay);
0595
0596
0597 static void sdtx_push_event(struct sdtx_device *ddev, struct sdtx_event *evt)
0598 {
0599 const size_t len = sizeof(struct sdtx_event) + evt->length;
0600 struct sdtx_client *client;
0601
0602 lockdep_assert_held(&ddev->write_lock);
0603
0604 down_read(&ddev->client_lock);
0605 list_for_each_entry(client, &ddev->client_list, node) {
0606 if (!test_bit(SDTX_CLIENT_EVENTS_ENABLED_BIT, &client->flags))
0607 continue;
0608
0609 if (likely(kfifo_avail(&client->buffer) >= len))
0610 kfifo_in(&client->buffer, (const u8 *)evt, len);
0611 else
0612 dev_warn(ddev->dev, "event buffer overrun\n");
0613
0614 kill_fasync(&client->fasync, SIGIO, POLL_IN);
0615 }
0616 up_read(&ddev->client_lock);
0617
0618 wake_up_interruptible(&ddev->waitq);
0619 }
0620
0621 static u32 sdtx_notifier(struct ssam_event_notifier *nf, const struct ssam_event *in)
0622 {
0623 struct sdtx_device *ddev = container_of(nf, struct sdtx_device, notif);
0624 union sdtx_generic_event event;
0625 size_t len;
0626
0627
0628 switch (in->command_id) {
0629 case SAM_EVENT_CID_DTX_CONNECTION:
0630 len = 2 * sizeof(u8);
0631 break;
0632
0633 case SAM_EVENT_CID_DTX_REQUEST:
0634 len = 0;
0635 break;
0636
0637 case SAM_EVENT_CID_DTX_CANCEL:
0638 len = sizeof(u8);
0639 break;
0640
0641 case SAM_EVENT_CID_DTX_LATCH_STATUS:
0642 len = sizeof(u8);
0643 break;
0644
0645 default:
0646 return 0;
0647 }
0648
0649 if (in->length != len) {
0650 dev_err(ddev->dev,
0651 "unexpected payload size for event %#04x: got %u, expected %zu\n",
0652 in->command_id, in->length, len);
0653 return 0;
0654 }
0655
0656 mutex_lock(&ddev->write_lock);
0657
0658
0659 switch (in->command_id) {
0660 case SAM_EVENT_CID_DTX_CONNECTION:
0661 clear_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags);
0662
0663
0664 if (ddev->state.base.state == in->data[0] &&
0665 ddev->state.base.base_id == in->data[1])
0666 goto out;
0667
0668 ddev->state.base.state = in->data[0];
0669 ddev->state.base.base_id = in->data[1];
0670
0671 event.base.e.length = sizeof(struct sdtx_base_info);
0672 event.base.e.code = SDTX_EVENT_BASE_CONNECTION;
0673 event.base.v.state = sdtx_translate_base_state(ddev, in->data[0]);
0674 event.base.v.base_id = SDTX_BASE_TYPE_SSH(in->data[1]);
0675 break;
0676
0677 case SAM_EVENT_CID_DTX_REQUEST:
0678 event.common.code = SDTX_EVENT_REQUEST;
0679 event.common.length = 0;
0680 break;
0681
0682 case SAM_EVENT_CID_DTX_CANCEL:
0683 event.status.e.length = sizeof(u16);
0684 event.status.e.code = SDTX_EVENT_CANCEL;
0685 event.status.v = sdtx_translate_cancel_reason(ddev, in->data[0]);
0686 break;
0687
0688 case SAM_EVENT_CID_DTX_LATCH_STATUS:
0689 clear_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags);
0690
0691
0692 if (ddev->state.latch_status == in->data[0])
0693 goto out;
0694
0695 ddev->state.latch_status = in->data[0];
0696
0697 event.status.e.length = sizeof(u16);
0698 event.status.e.code = SDTX_EVENT_LATCH_STATUS;
0699 event.status.v = sdtx_translate_latch_status(ddev, in->data[0]);
0700 break;
0701 }
0702
0703 sdtx_push_event(ddev, &event.common);
0704
0705
0706 if (in->command_id == SAM_EVENT_CID_DTX_CONNECTION) {
0707 unsigned long delay;
0708
0709 delay = in->data[0] ? SDTX_DEVICE_MODE_DELAY_CONNECT : 0;
0710 sdtx_update_device_mode(ddev, delay);
0711 }
0712
0713 out:
0714 mutex_unlock(&ddev->write_lock);
0715 return SSAM_NOTIF_HANDLED;
0716 }
0717
0718
0719
0720
0721 static bool sdtx_device_mode_invalid(u8 mode, u8 base_state)
0722 {
0723 return ((base_state == SSAM_BAS_BASE_STATE_ATTACHED) &&
0724 (mode == SDTX_DEVICE_MODE_TABLET)) ||
0725 ((base_state == SSAM_BAS_BASE_STATE_DETACH_SUCCESS) &&
0726 (mode != SDTX_DEVICE_MODE_TABLET));
0727 }
0728
0729 static void sdtx_device_mode_workfn(struct work_struct *work)
0730 {
0731 struct sdtx_device *ddev = container_of(work, struct sdtx_device, mode_work.work);
0732 struct sdtx_status_event event;
0733 struct ssam_bas_base_info base;
0734 int status, tablet;
0735 u8 mode;
0736
0737
0738 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
0739 if (status) {
0740 dev_err(ddev->dev, "failed to get device mode: %d\n", status);
0741 return;
0742 }
0743
0744
0745 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &base);
0746 if (status) {
0747 dev_err(ddev->dev, "failed to get base info: %d\n", status);
0748 return;
0749 }
0750
0751
0752
0753
0754
0755
0756
0757 if (sdtx_device_mode_invalid(mode, base.state)) {
0758 dev_dbg(ddev->dev, "device mode is invalid, trying again\n");
0759 sdtx_update_device_mode(ddev, SDTX_DEVICE_MODE_DELAY_RECHECK);
0760 return;
0761 }
0762
0763 mutex_lock(&ddev->write_lock);
0764 clear_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags);
0765
0766
0767 if (ddev->state.device_mode == mode) {
0768 mutex_unlock(&ddev->write_lock);
0769 return;
0770 }
0771
0772 ddev->state.device_mode = mode;
0773
0774 event.e.length = sizeof(u16);
0775 event.e.code = SDTX_EVENT_DEVICE_MODE;
0776 event.v = mode;
0777
0778 sdtx_push_event(ddev, &event.e);
0779
0780
0781 tablet = mode != SDTX_DEVICE_MODE_LAPTOP;
0782 input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet);
0783 input_sync(ddev->mode_switch);
0784
0785 mutex_unlock(&ddev->write_lock);
0786 }
0787
0788 static void sdtx_update_device_mode(struct sdtx_device *ddev, unsigned long delay)
0789 {
0790 schedule_delayed_work(&ddev->mode_work, delay);
0791 }
0792
0793
0794 static void __sdtx_device_state_update_base(struct sdtx_device *ddev,
0795 struct ssam_bas_base_info info)
0796 {
0797 struct sdtx_base_info_event event;
0798
0799 lockdep_assert_held(&ddev->write_lock);
0800
0801
0802 if (ddev->state.base.state == info.state &&
0803 ddev->state.base.base_id == info.base_id)
0804 return;
0805
0806 ddev->state.base = info;
0807
0808 event.e.length = sizeof(struct sdtx_base_info);
0809 event.e.code = SDTX_EVENT_BASE_CONNECTION;
0810 event.v.state = sdtx_translate_base_state(ddev, info.state);
0811 event.v.base_id = SDTX_BASE_TYPE_SSH(info.base_id);
0812
0813 sdtx_push_event(ddev, &event.e);
0814 }
0815
0816
0817 static void __sdtx_device_state_update_mode(struct sdtx_device *ddev, u8 mode)
0818 {
0819 struct sdtx_status_event event;
0820 int tablet;
0821
0822
0823
0824
0825
0826
0827
0828 lockdep_assert_held(&ddev->write_lock);
0829
0830 if (sdtx_device_mode_invalid(mode, ddev->state.base.state)) {
0831 dev_dbg(ddev->dev, "device mode is invalid, trying again\n");
0832 sdtx_update_device_mode(ddev, SDTX_DEVICE_MODE_DELAY_RECHECK);
0833 return;
0834 }
0835
0836
0837 if (ddev->state.device_mode == mode)
0838 return;
0839
0840 ddev->state.device_mode = mode;
0841
0842
0843 event.e.length = sizeof(u16);
0844 event.e.code = SDTX_EVENT_DEVICE_MODE;
0845 event.v = mode;
0846
0847 sdtx_push_event(ddev, &event.e);
0848
0849
0850 tablet = mode != SDTX_DEVICE_MODE_LAPTOP;
0851 input_report_switch(ddev->mode_switch, SW_TABLET_MODE, tablet);
0852 input_sync(ddev->mode_switch);
0853 }
0854
0855
0856 static void __sdtx_device_state_update_latch(struct sdtx_device *ddev, u8 status)
0857 {
0858 struct sdtx_status_event event;
0859
0860 lockdep_assert_held(&ddev->write_lock);
0861
0862
0863 if (ddev->state.latch_status == status)
0864 return;
0865
0866 ddev->state.latch_status = status;
0867
0868 event.e.length = sizeof(struct sdtx_base_info);
0869 event.e.code = SDTX_EVENT_BASE_CONNECTION;
0870 event.v = sdtx_translate_latch_status(ddev, status);
0871
0872 sdtx_push_event(ddev, &event.e);
0873 }
0874
0875 static void sdtx_device_state_workfn(struct work_struct *work)
0876 {
0877 struct sdtx_device *ddev = container_of(work, struct sdtx_device, state_work.work);
0878 struct ssam_bas_base_info base;
0879 u8 mode, latch;
0880 int status;
0881
0882
0883 set_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags);
0884 set_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags);
0885 set_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags);
0886
0887
0888
0889
0890
0891
0892
0893 smp_mb__after_atomic();
0894
0895 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &base);
0896 if (status) {
0897 dev_err(ddev->dev, "failed to get base state: %d\n", status);
0898 return;
0899 }
0900
0901 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &mode);
0902 if (status) {
0903 dev_err(ddev->dev, "failed to get device mode: %d\n", status);
0904 return;
0905 }
0906
0907 status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &latch);
0908 if (status) {
0909 dev_err(ddev->dev, "failed to get latch status: %d\n", status);
0910 return;
0911 }
0912
0913 mutex_lock(&ddev->write_lock);
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923 if (test_and_clear_bit(SDTX_DEVICE_DIRTY_BASE_BIT, &ddev->flags))
0924 __sdtx_device_state_update_base(ddev, base);
0925
0926 if (test_and_clear_bit(SDTX_DEVICE_DIRTY_MODE_BIT, &ddev->flags))
0927 __sdtx_device_state_update_mode(ddev, mode);
0928
0929 if (test_and_clear_bit(SDTX_DEVICE_DIRTY_LATCH_BIT, &ddev->flags))
0930 __sdtx_device_state_update_latch(ddev, latch);
0931
0932 mutex_unlock(&ddev->write_lock);
0933 }
0934
0935 static void sdtx_update_device_state(struct sdtx_device *ddev, unsigned long delay)
0936 {
0937 schedule_delayed_work(&ddev->state_work, delay);
0938 }
0939
0940
0941
0942
0943 static int sdtx_device_init(struct sdtx_device *ddev, struct device *dev,
0944 struct ssam_controller *ctrl)
0945 {
0946 int status, tablet_mode;
0947
0948
0949 kref_init(&ddev->kref);
0950 init_rwsem(&ddev->lock);
0951 ddev->dev = dev;
0952 ddev->ctrl = ctrl;
0953
0954 ddev->mdev.minor = MISC_DYNAMIC_MINOR;
0955 ddev->mdev.name = "surface_dtx";
0956 ddev->mdev.nodename = "surface/dtx";
0957 ddev->mdev.fops = &surface_dtx_fops;
0958
0959 ddev->notif.base.priority = 1;
0960 ddev->notif.base.fn = sdtx_notifier;
0961 ddev->notif.event.reg = SSAM_EVENT_REGISTRY_SAM;
0962 ddev->notif.event.id.target_category = SSAM_SSH_TC_BAS;
0963 ddev->notif.event.id.instance = 0;
0964 ddev->notif.event.mask = SSAM_EVENT_MASK_NONE;
0965 ddev->notif.event.flags = SSAM_EVENT_SEQUENCED;
0966
0967 init_waitqueue_head(&ddev->waitq);
0968 mutex_init(&ddev->write_lock);
0969 init_rwsem(&ddev->client_lock);
0970 INIT_LIST_HEAD(&ddev->client_list);
0971
0972 INIT_DELAYED_WORK(&ddev->mode_work, sdtx_device_mode_workfn);
0973 INIT_DELAYED_WORK(&ddev->state_work, sdtx_device_state_workfn);
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986 status = ssam_retry(ssam_bas_get_base, ddev->ctrl, &ddev->state.base);
0987 if (status)
0988 return status;
0989
0990 status = ssam_retry(ssam_bas_get_device_mode, ddev->ctrl, &ddev->state.device_mode);
0991 if (status)
0992 return status;
0993
0994 status = ssam_retry(ssam_bas_get_latch_status, ddev->ctrl, &ddev->state.latch_status);
0995 if (status)
0996 return status;
0997
0998
0999 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
1035 err_notif:
1036 ssam_notifier_unregister(ddev->ctrl, &ddev->notif);
1037 cancel_delayed_work_sync(&ddev->mode_work);
1038 err_mdev:
1039 input_unregister_device(ddev->mode_switch);
1040 return status;
1041 }
1042
1043 static 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
1061 static 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
1118 static 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
1140 static const struct dev_pm_ops surface_dtx_pm_ops = {
1141 .complete = surface_dtx_pm_complete,
1142 };
1143
1144 #else
1145
1146 static const struct dev_pm_ops surface_dtx_pm_ops = {};
1147
1148 #endif
1149
1150
1151
1152
1153 static 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
1171 static int surface_dtx_platform_remove(struct platform_device *pdev)
1172 {
1173 sdtx_device_destroy(platform_get_drvdata(pdev));
1174 return 0;
1175 }
1176
1177 static const struct acpi_device_id surface_dtx_acpi_match[] = {
1178 { "MSHW0133", 0 },
1179 { },
1180 };
1181 MODULE_DEVICE_TABLE(acpi, surface_dtx_acpi_match);
1182
1183 static 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
1199 static 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
1211 static void surface_dtx_ssam_remove(struct ssam_device *sdev)
1212 {
1213 sdtx_device_destroy(ssam_device_get_drvdata(sdev));
1214 }
1215
1216 static const struct ssam_device_id surface_dtx_ssam_match[] = {
1217 { SSAM_SDEV(BAS, 0x01, 0x00, 0x00) },
1218 { },
1219 };
1220 MODULE_DEVICE_TABLE(ssam, surface_dtx_ssam_match);
1221
1222 static 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
1233 static int ssam_dtx_driver_register(void)
1234 {
1235 return ssam_device_driver_register(&surface_dtx_ssam_driver);
1236 }
1237
1238 static void ssam_dtx_driver_unregister(void)
1239 {
1240 ssam_device_driver_unregister(&surface_dtx_ssam_driver);
1241 }
1242
1243 #else
1244
1245 static int ssam_dtx_driver_register(void)
1246 {
1247 return 0;
1248 }
1249
1250 static void ssam_dtx_driver_unregister(void)
1251 {
1252 }
1253
1254 #endif
1255
1256
1257
1258
1259 static 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 }
1273 module_init(surface_dtx_init);
1274
1275 static void __exit surface_dtx_exit(void)
1276 {
1277 platform_driver_unregister(&surface_dtx_platform_driver);
1278 ssam_dtx_driver_unregister();
1279 }
1280 module_exit(surface_dtx_exit);
1281
1282 MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
1283 MODULE_DESCRIPTION("Detachment-system driver for Surface System Aggregator Module");
1284 MODULE_LICENSE("GPL");