1 /* 2 * Copyright (C) 2015-2016 Red Hat 3 * Copyright (C) 2015 Lyude Paul <thatslyude@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/slab.h> 12 #include <linux/serio.h> 13 #include <linux/notifier.h> 14 #include "rmi_driver.h" 15 16 #define RMI_F03_RX_DATA_OFB 0x01 17 #define RMI_F03_OB_SIZE 2 18 19 #define RMI_F03_OB_OFFSET 2 20 #define RMI_F03_OB_DATA_OFFSET 1 21 #define RMI_F03_OB_FLAG_TIMEOUT BIT(6) 22 #define RMI_F03_OB_FLAG_PARITY BIT(7) 23 24 #define RMI_F03_DEVICE_COUNT 0x07 25 #define RMI_F03_BYTES_PER_DEVICE 0x07 26 #define RMI_F03_BYTES_PER_DEVICE_SHIFT 4 27 #define RMI_F03_QUEUE_LENGTH 0x0F 28 29 struct f03_data { 30 struct rmi_function *fn; 31 32 struct serio *serio; 33 34 u8 device_count; 35 u8 rx_queue_length; 36 }; 37 38 static int rmi_f03_pt_write(struct serio *id, unsigned char val) 39 { 40 struct f03_data *f03 = id->port_data; 41 int error; 42 43 rmi_dbg(RMI_DEBUG_FN, &f03->fn->dev, 44 "%s: Wrote %.2hhx to PS/2 passthrough address", 45 __func__, val); 46 47 error = rmi_write(f03->fn->rmi_dev, f03->fn->fd.data_base_addr, val); 48 if (error) { 49 dev_err(&f03->fn->dev, 50 "%s: Failed to write to F03 TX register (%d).\n", 51 __func__, error); 52 return error; 53 } 54 55 return 0; 56 } 57 58 static int rmi_f03_initialize(struct f03_data *f03) 59 { 60 struct rmi_function *fn = f03->fn; 61 struct device *dev = &fn->dev; 62 int error; 63 u8 bytes_per_device; 64 u8 query1; 65 u8 query2[RMI_F03_DEVICE_COUNT * RMI_F03_BYTES_PER_DEVICE]; 66 size_t query2_len; 67 68 error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &query1); 69 if (error) { 70 dev_err(dev, "Failed to read query register (%d).\n", error); 71 return error; 72 } 73 74 f03->device_count = query1 & RMI_F03_DEVICE_COUNT; 75 bytes_per_device = (query1 >> RMI_F03_BYTES_PER_DEVICE_SHIFT) & 76 RMI_F03_BYTES_PER_DEVICE; 77 78 query2_len = f03->device_count * bytes_per_device; 79 80 /* 81 * The first generation of image sensors don't have a second part to 82 * their f03 query, as such we have to set some of these values manually 83 */ 84 if (query2_len < 1) { 85 f03->device_count = 1; 86 f03->rx_queue_length = 7; 87 } else { 88 error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr + 1, 89 query2, query2_len); 90 if (error) { 91 dev_err(dev, 92 "Failed to read second set of query registers (%d).\n", 93 error); 94 return error; 95 } 96 97 f03->rx_queue_length = query2[0] & RMI_F03_QUEUE_LENGTH; 98 } 99 100 return 0; 101 } 102 103 static int rmi_f03_register_pt(struct f03_data *f03) 104 { 105 struct serio *serio; 106 107 serio = kzalloc(sizeof(struct serio), GFP_KERNEL); 108 if (!serio) 109 return -ENOMEM; 110 111 serio->id.type = SERIO_8042; 112 serio->write = rmi_f03_pt_write; 113 serio->port_data = f03; 114 115 strlcpy(serio->name, "Synaptics RMI4 PS/2 pass-through", 116 sizeof(serio->name)); 117 strlcpy(serio->phys, "synaptics-rmi4-pt/serio1", 118 sizeof(serio->phys)); 119 serio->dev.parent = &f03->fn->dev; 120 121 f03->serio = serio; 122 123 serio_register_port(serio); 124 125 return 0; 126 } 127 128 static int rmi_f03_probe(struct rmi_function *fn) 129 { 130 struct device *dev = &fn->dev; 131 struct f03_data *f03; 132 int error; 133 134 f03 = devm_kzalloc(dev, sizeof(struct f03_data), GFP_KERNEL); 135 if (!f03) 136 return -ENOMEM; 137 138 f03->fn = fn; 139 140 error = rmi_f03_initialize(f03); 141 if (error < 0) 142 return error; 143 144 if (f03->device_count != 1) 145 dev_warn(dev, "found %d devices on PS/2 passthrough", 146 f03->device_count); 147 148 dev_set_drvdata(dev, f03); 149 150 error = rmi_f03_register_pt(f03); 151 if (error) 152 return error; 153 154 return 0; 155 } 156 157 static int rmi_f03_config(struct rmi_function *fn) 158 { 159 fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask); 160 161 return 0; 162 } 163 164 static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits) 165 { 166 struct rmi_device *rmi_dev = fn->rmi_dev; 167 struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); 168 struct f03_data *f03 = dev_get_drvdata(&fn->dev); 169 u16 data_addr = fn->fd.data_base_addr; 170 const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE; 171 u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE]; 172 u8 ob_status; 173 u8 ob_data; 174 unsigned int serio_flags; 175 int i; 176 int error; 177 178 if (!rmi_dev) 179 return -ENODEV; 180 181 if (drvdata->attn_data.data) { 182 /* First grab the data passed by the transport device */ 183 if (drvdata->attn_data.size < ob_len) { 184 dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n"); 185 return 0; 186 } 187 188 memcpy(obs, drvdata->attn_data.data, ob_len); 189 190 drvdata->attn_data.data += ob_len; 191 drvdata->attn_data.size -= ob_len; 192 } else { 193 /* Grab all of the data registers, and check them for data */ 194 error = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET, 195 &obs, ob_len); 196 if (error) { 197 dev_err(&fn->dev, 198 "%s: Failed to read F03 output buffers: %d\n", 199 __func__, error); 200 serio_interrupt(f03->serio, 0, SERIO_TIMEOUT); 201 return error; 202 } 203 } 204 205 for (i = 0; i < ob_len; i += RMI_F03_OB_SIZE) { 206 ob_status = obs[i]; 207 ob_data = obs[i + RMI_F03_OB_DATA_OFFSET]; 208 serio_flags = 0; 209 210 if (!(ob_status & RMI_F03_RX_DATA_OFB)) 211 continue; 212 213 if (ob_status & RMI_F03_OB_FLAG_TIMEOUT) 214 serio_flags |= SERIO_TIMEOUT; 215 if (ob_status & RMI_F03_OB_FLAG_PARITY) 216 serio_flags |= SERIO_PARITY; 217 218 rmi_dbg(RMI_DEBUG_FN, &fn->dev, 219 "%s: Received %.2hhx from PS2 guest T: %c P: %c\n", 220 __func__, ob_data, 221 serio_flags & SERIO_TIMEOUT ? 'Y' : 'N', 222 serio_flags & SERIO_PARITY ? 'Y' : 'N'); 223 224 serio_interrupt(f03->serio, ob_data, serio_flags); 225 } 226 227 return 0; 228 } 229 230 static void rmi_f03_remove(struct rmi_function *fn) 231 { 232 struct f03_data *f03 = dev_get_drvdata(&fn->dev); 233 234 serio_unregister_port(f03->serio); 235 } 236 237 struct rmi_function_handler rmi_f03_handler = { 238 .driver = { 239 .name = "rmi4_f03", 240 }, 241 .func = 0x03, 242 .probe = rmi_f03_probe, 243 .config = rmi_f03_config, 244 .attention = rmi_f03_attention, 245 .remove = rmi_f03_remove, 246 }; 247 248 MODULE_AUTHOR("Lyude Paul <thatslyude@gmail.com>"); 249 MODULE_DESCRIPTION("RMI F03 module"); 250 MODULE_LICENSE("GPL"); 251