1 // SPDX-License-Identifier: GPL-2.0 2 3 /*************************************************************************** 4 * copyright : (C) 2002 by Frank Mori Hess 5 ***************************************************************************/ 6 7 #include "cec.h" 8 #include <linux/pci.h> 9 #include <linux/io.h> 10 #include <linux/bitops.h> 11 #include <asm/dma.h> 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 15 MODULE_LICENSE("GPL"); 16 MODULE_DESCRIPTION("GPIB driver for CEC PCI and PCMCIA boards"); 17 18 /* 19 * GPIB interrupt service routines 20 */ 21 22 irqreturn_t cec_interrupt(int irq, void *arg) 23 { 24 gpib_board_t *board = arg; 25 struct cec_priv *priv = board->private_data; 26 unsigned long flags; 27 irqreturn_t retval; 28 29 spin_lock_irqsave(&board->spinlock, flags); 30 retval = nec7210_interrupt(board, &priv->nec7210_priv); 31 spin_unlock_irqrestore(&board->spinlock, flags); 32 return retval; 33 } 34 35 #define CEC_VENDOR_ID 0x12fc 36 #define CEC_DEV_ID 0x5cec 37 #define CEC_SUBID 0x9050 38 39 static int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config); 40 41 static void cec_pci_detach(gpib_board_t *board); 42 43 // wrappers for interface functions 44 int cec_read(gpib_board_t *board, uint8_t *buffer, size_t length, int *end, size_t *bytes_read) 45 { 46 struct cec_priv *priv = board->private_data; 47 48 return nec7210_read(board, &priv->nec7210_priv, buffer, length, end, bytes_read); 49 } 50 51 int cec_write(gpib_board_t *board, uint8_t *buffer, size_t length, int send_eoi, 52 size_t *bytes_written) 53 { 54 struct cec_priv *priv = board->private_data; 55 56 return nec7210_write(board, &priv->nec7210_priv, buffer, length, send_eoi, bytes_written); 57 } 58 59 int cec_command(gpib_board_t *board, uint8_t *buffer, size_t length, size_t *bytes_written) 60 { 61 struct cec_priv *priv = board->private_data; 62 63 return nec7210_command(board, &priv->nec7210_priv, buffer, length, bytes_written); 64 } 65 66 int cec_take_control(gpib_board_t *board, int synchronous) 67 { 68 struct cec_priv *priv = board->private_data; 69 70 return nec7210_take_control(board, &priv->nec7210_priv, synchronous); 71 } 72 73 int cec_go_to_standby(gpib_board_t *board) 74 { 75 struct cec_priv *priv = board->private_data; 76 77 return nec7210_go_to_standby(board, &priv->nec7210_priv); 78 } 79 80 void cec_request_system_control(gpib_board_t *board, int request_control) 81 { 82 struct cec_priv *priv = board->private_data; 83 84 nec7210_request_system_control(board, &priv->nec7210_priv, request_control); 85 } 86 87 void cec_interface_clear(gpib_board_t *board, int assert) 88 { 89 struct cec_priv *priv = board->private_data; 90 91 nec7210_interface_clear(board, &priv->nec7210_priv, assert); 92 } 93 94 void cec_remote_enable(gpib_board_t *board, int enable) 95 { 96 struct cec_priv *priv = board->private_data; 97 98 nec7210_remote_enable(board, &priv->nec7210_priv, enable); 99 } 100 101 int cec_enable_eos(gpib_board_t *board, uint8_t eos_byte, int compare_8_bits) 102 { 103 struct cec_priv *priv = board->private_data; 104 105 return nec7210_enable_eos(board, &priv->nec7210_priv, eos_byte, compare_8_bits); 106 } 107 108 void cec_disable_eos(gpib_board_t *board) 109 { 110 struct cec_priv *priv = board->private_data; 111 112 nec7210_disable_eos(board, &priv->nec7210_priv); 113 } 114 115 unsigned int cec_update_status(gpib_board_t *board, unsigned int clear_mask) 116 { 117 struct cec_priv *priv = board->private_data; 118 119 return nec7210_update_status(board, &priv->nec7210_priv, clear_mask); 120 } 121 122 int cec_primary_address(gpib_board_t *board, unsigned int address) 123 { 124 struct cec_priv *priv = board->private_data; 125 126 return nec7210_primary_address(board, &priv->nec7210_priv, address); 127 } 128 129 int cec_secondary_address(gpib_board_t *board, unsigned int address, int enable) 130 { 131 struct cec_priv *priv = board->private_data; 132 133 return nec7210_secondary_address(board, &priv->nec7210_priv, address, enable); 134 } 135 136 int cec_parallel_poll(gpib_board_t *board, uint8_t *result) 137 { 138 struct cec_priv *priv = board->private_data; 139 140 return nec7210_parallel_poll(board, &priv->nec7210_priv, result); 141 } 142 143 void cec_parallel_poll_configure(gpib_board_t *board, uint8_t config) 144 { 145 struct cec_priv *priv = board->private_data; 146 147 nec7210_parallel_poll_configure(board, &priv->nec7210_priv, config); 148 } 149 150 void cec_parallel_poll_response(gpib_board_t *board, int ist) 151 { 152 struct cec_priv *priv = board->private_data; 153 154 nec7210_parallel_poll_response(board, &priv->nec7210_priv, ist); 155 } 156 157 void cec_serial_poll_response(gpib_board_t *board, uint8_t status) 158 { 159 struct cec_priv *priv = board->private_data; 160 161 nec7210_serial_poll_response(board, &priv->nec7210_priv, status); 162 } 163 164 static uint8_t cec_serial_poll_status(gpib_board_t *board) 165 { 166 struct cec_priv *priv = board->private_data; 167 168 return nec7210_serial_poll_status(board, &priv->nec7210_priv); 169 } 170 171 static unsigned int cec_t1_delay(gpib_board_t *board, unsigned int nano_sec) 172 { 173 struct cec_priv *priv = board->private_data; 174 175 return nec7210_t1_delay(board, &priv->nec7210_priv, nano_sec); 176 } 177 178 void cec_return_to_local(gpib_board_t *board) 179 { 180 struct cec_priv *priv = board->private_data; 181 182 nec7210_return_to_local(board, &priv->nec7210_priv); 183 } 184 185 static gpib_interface_t cec_pci_interface = { 186 .name = "cec_pci", 187 .attach = cec_pci_attach, 188 .detach = cec_pci_detach, 189 .read = cec_read, 190 .write = cec_write, 191 .command = cec_command, 192 .take_control = cec_take_control, 193 .go_to_standby = cec_go_to_standby, 194 .request_system_control = cec_request_system_control, 195 .interface_clear = cec_interface_clear, 196 .remote_enable = cec_remote_enable, 197 .enable_eos = cec_enable_eos, 198 .disable_eos = cec_disable_eos, 199 .parallel_poll = cec_parallel_poll, 200 .parallel_poll_configure = cec_parallel_poll_configure, 201 .parallel_poll_response = cec_parallel_poll_response, 202 .local_parallel_poll_mode = NULL, // XXX 203 .line_status = NULL, //XXX 204 .update_status = cec_update_status, 205 .primary_address = cec_primary_address, 206 .secondary_address = cec_secondary_address, 207 .serial_poll_response = cec_serial_poll_response, 208 .serial_poll_status = cec_serial_poll_status, 209 .t1_delay = cec_t1_delay, 210 .return_to_local = cec_return_to_local, 211 }; 212 213 static int cec_allocate_private(gpib_board_t *board) 214 { 215 struct cec_priv *priv; 216 217 board->private_data = kmalloc(sizeof(struct cec_priv), GFP_KERNEL); 218 if (!board->private_data) 219 return -1; 220 priv = board->private_data; 221 memset(priv, 0, sizeof(struct cec_priv)); 222 init_nec7210_private(&priv->nec7210_priv); 223 return 0; 224 } 225 226 void cec_free_private(gpib_board_t *board) 227 { 228 kfree(board->private_data); 229 board->private_data = NULL; 230 } 231 232 int cec_generic_attach(gpib_board_t *board) 233 { 234 struct cec_priv *cec_priv; 235 struct nec7210_priv *nec_priv; 236 237 board->status = 0; 238 239 if (cec_allocate_private(board)) 240 return -ENOMEM; 241 cec_priv = board->private_data; 242 nec_priv = &cec_priv->nec7210_priv; 243 nec_priv->read_byte = nec7210_ioport_read_byte; 244 nec_priv->write_byte = nec7210_ioport_write_byte; 245 nec_priv->offset = cec_reg_offset; 246 nec_priv->type = NEC7210; // guess 247 return 0; 248 } 249 250 void cec_init(struct cec_priv *cec_priv, const gpib_board_t *board) 251 { 252 struct nec7210_priv *nec_priv = &cec_priv->nec7210_priv; 253 254 nec7210_board_reset(nec_priv, board); 255 256 /* set internal counter register for 8 MHz input clock */ 257 write_byte(nec_priv, ICR | 8, AUXMR); 258 259 nec7210_board_online(nec_priv, board); 260 } 261 262 int cec_pci_attach(gpib_board_t *board, const gpib_board_config_t *config) 263 { 264 struct cec_priv *cec_priv; 265 struct nec7210_priv *nec_priv; 266 int isr_flags = 0; 267 int retval; 268 269 retval = cec_generic_attach(board); 270 if (retval) 271 return retval; 272 273 cec_priv = board->private_data; 274 nec_priv = &cec_priv->nec7210_priv; 275 276 // find board 277 cec_priv->pci_device = NULL; 278 while ((cec_priv->pci_device = 279 gpib_pci_get_device(config, CEC_VENDOR_ID, 280 CEC_DEV_ID, cec_priv->pci_device))) { 281 // check for board with plx9050 controller 282 if (cec_priv->pci_device->subsystem_device == CEC_SUBID) 283 break; 284 } 285 if (!cec_priv->pci_device) { 286 pr_err("gpib: no cec PCI board found\n"); 287 return -1; 288 } 289 290 if (pci_enable_device(cec_priv->pci_device)) { 291 pr_err("error enabling pci device\n"); 292 return -1; 293 } 294 295 if (pci_request_regions(cec_priv->pci_device, "cec-gpib")) 296 return -1; 297 298 cec_priv->plx_iobase = pci_resource_start(cec_priv->pci_device, 1); 299 pr_info(" plx9050 base address 0x%lx\n", cec_priv->plx_iobase); 300 nec_priv->iobase = pci_resource_start(cec_priv->pci_device, 3); 301 pr_info(" nec7210 base address 0x%x\n", nec_priv->iobase); 302 303 isr_flags |= IRQF_SHARED; 304 if (request_irq(cec_priv->pci_device->irq, cec_interrupt, isr_flags, "pci-gpib", board)) { 305 pr_err("gpib: can't request IRQ %d\n", cec_priv->pci_device->irq); 306 return -1; 307 } 308 cec_priv->irq = cec_priv->pci_device->irq; 309 if (gpib_request_pseudo_irq(board, cec_interrupt)) { 310 pr_err("cec: failed to allocate pseudo irq\n"); 311 return -1; 312 } 313 cec_init(cec_priv, board); 314 315 // enable interrupts on plx chip 316 outl(PLX9050_LINTR1_EN_BIT | PLX9050_LINTR1_POLARITY_BIT | PLX9050_PCI_INTR_EN_BIT, 317 cec_priv->plx_iobase + PLX9050_INTCSR_REG); 318 319 return 0; 320 } 321 322 void cec_pci_detach(gpib_board_t *board) 323 { 324 struct cec_priv *cec_priv = board->private_data; 325 struct nec7210_priv *nec_priv; 326 327 if (cec_priv) { 328 nec_priv = &cec_priv->nec7210_priv; 329 gpib_free_pseudo_irq(board); 330 if (cec_priv->irq) { 331 // disable plx9050 interrupts 332 outl(0, cec_priv->plx_iobase + PLX9050_INTCSR_REG); 333 free_irq(cec_priv->irq, board); 334 } 335 if (nec_priv->iobase) { 336 nec7210_board_reset(nec_priv, board); 337 pci_release_regions(cec_priv->pci_device); 338 } 339 if (cec_priv->pci_device) 340 pci_dev_put(cec_priv->pci_device); 341 } 342 cec_free_private(board); 343 } 344 345 static int cec_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) 346 { 347 return 0; 348 } 349 350 static const struct pci_device_id cec_pci_table[] = { 351 {CEC_VENDOR_ID, CEC_DEV_ID, PCI_ANY_ID, CEC_SUBID, 0, 0, 0 }, 352 {0} 353 }; 354 MODULE_DEVICE_TABLE(pci, cec_pci_table); 355 356 static struct pci_driver cec_pci_driver = { 357 .name = "cec_gpib", 358 .id_table = cec_pci_table, 359 .probe = &cec_pci_probe 360 }; 361 362 static int __init cec_init_module(void) 363 { 364 int result; 365 366 result = pci_register_driver(&cec_pci_driver); 367 if (result) { 368 pr_err("cec_gpib: pci_register_driver failed: error = %d\n", result); 369 return result; 370 } 371 372 result = gpib_register_driver(&cec_pci_interface, THIS_MODULE); 373 if (result) { 374 pr_err("cec_gpib: gpib_register_driver failed: error = %d\n", result); 375 return result; 376 } 377 378 return 0; 379 } 380 381 static void cec_exit_module(void) 382 { 383 gpib_unregister_driver(&cec_pci_interface); 384 385 pci_unregister_driver(&cec_pci_driver); 386 } 387 388 module_init(cec_init_module); 389 module_exit(cec_exit_module); 390