1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * UCSI debugfs interface 4 * 5 * Copyright (C) 2023 Intel Corporation 6 * 7 * Authors: Rajaram Regupathy <rajaram.regupathy@intel.com> 8 * Gopal Saranya <saranya.gopal@intel.com> 9 */ 10 #include <linux/debugfs.h> 11 #include <linux/slab.h> 12 #include <linux/string.h> 13 #include <linux/types.h> 14 #include <linux/usb.h> 15 16 #include <asm/errno.h> 17 18 #include "ucsi.h" 19 20 static struct dentry *ucsi_debugfs_root; 21 22 static int ucsi_cmd(void *data, u64 val) 23 { 24 struct ucsi *ucsi = data; 25 int ret; 26 27 memset(&ucsi->debugfs->response, 0, sizeof(ucsi->debugfs->response)); 28 ucsi->debugfs->status = 0; 29 30 switch (UCSI_COMMAND(val)) { 31 case UCSI_SET_CCOM: 32 case UCSI_SET_UOR: 33 case UCSI_SET_PDR: 34 case UCSI_CONNECTOR_RESET: 35 case UCSI_SET_SINK_PATH: 36 case UCSI_SET_NEW_CAM: 37 case UCSI_SET_USB: 38 ret = ucsi_send_command(ucsi, val, NULL, 0); 39 break; 40 case UCSI_GET_CAPABILITY: 41 case UCSI_GET_CONNECTOR_CAPABILITY: 42 case UCSI_GET_ALTERNATE_MODES: 43 case UCSI_GET_CAM_SUPPORTED: 44 case UCSI_GET_CURRENT_CAM: 45 case UCSI_GET_PDOS: 46 case UCSI_GET_CABLE_PROPERTY: 47 case UCSI_GET_CONNECTOR_STATUS: 48 case UCSI_GET_ERROR_STATUS: 49 case UCSI_GET_PD_MESSAGE: 50 case UCSI_GET_ATTENTION_VDO: 51 case UCSI_GET_CAM_CS: 52 case UCSI_GET_LPM_PPM_INFO: 53 ret = ucsi_send_command(ucsi, val, 54 &ucsi->debugfs->response, 55 sizeof(ucsi->debugfs->response)); 56 break; 57 default: 58 ret = -EOPNOTSUPP; 59 } 60 61 if (ret < 0) { 62 ucsi->debugfs->status = ret; 63 return ret; 64 } 65 66 return 0; 67 } 68 DEFINE_DEBUGFS_ATTRIBUTE(ucsi_cmd_fops, NULL, ucsi_cmd, "0x%llx\n"); 69 70 static int ucsi_resp_show(struct seq_file *s, void *not_used) 71 { 72 struct ucsi *ucsi = s->private; 73 74 if (ucsi->debugfs->status) 75 return ucsi->debugfs->status; 76 77 seq_printf(s, "0x%016llx%016llx\n", ucsi->debugfs->response.high, 78 ucsi->debugfs->response.low); 79 return 0; 80 } 81 DEFINE_SHOW_ATTRIBUTE(ucsi_resp); 82 83 void ucsi_debugfs_register(struct ucsi *ucsi) 84 { 85 ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL); 86 if (!ucsi->debugfs) 87 return; 88 89 ucsi->debugfs->dentry = debugfs_create_dir(dev_name(ucsi->dev), ucsi_debugfs_root); 90 debugfs_create_file("command", 0200, ucsi->debugfs->dentry, ucsi, &ucsi_cmd_fops); 91 debugfs_create_file("response", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_resp_fops); 92 } 93 94 void ucsi_debugfs_unregister(struct ucsi *ucsi) 95 { 96 if (IS_ERR_OR_NULL(ucsi) || !ucsi->debugfs) 97 return; 98 99 debugfs_remove_recursive(ucsi->debugfs->dentry); 100 kfree(ucsi->debugfs); 101 } 102 103 void ucsi_debugfs_init(void) 104 { 105 ucsi_debugfs_root = debugfs_create_dir("ucsi", usb_debug_root); 106 } 107 108 void ucsi_debugfs_exit(void) 109 { 110 debugfs_remove(ucsi_debugfs_root); 111 } 112