FILE
hp82335.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpib/hp_82335/hp82335.c
1// SPDX-License-Identifier: GPL-2.0 2 3/*************************************************************************** 4 * copyright : (C) 2002 by Frank Mori Hess * 5 ***************************************************************************/ 6 7/* 8 * should enable ATN interrupts (and update board->status on occurrence), 9 * implement recovery from bus errors (if necessary) 10 */ 11 12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define dev_fmt pr_fmt 14#define DRV_NAME KBUILD_MODNAME 15 16#include "hp82335.h" 17#include <linux/io.h> 18#include <linux/ioport.h> 19#include <linux/sched.h> 20#include <linux/module.h> 21#include <linux/slab.h> 22#include <linux/string.h> 23#include <linux/init.h> 24 25MODULE_LICENSE("GPL"); 26MODULE_DESCRIPTION("GPIB driver for HP 82335 interface cards"); 27 28static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config); 29static void hp82335_detach(struct gpib_board *board); 30static irqreturn_t hp82335_interrupt(int irq, void *arg); 31 32// wrappers for interface functions 33static int hp82335_read(struct gpib_board *board, u8 *buffer, size_t length, 34 int *end, size_t *bytes_read) 35{ 36 struct hp82335_priv *priv = board->private_data; 37 38 return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read); 39} 40 41static int hp82335_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi, 42 size_t *bytes_written) 43{ 44 struct hp82335_priv *priv = board->private_data; 45 46 return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written); 47} 48 49static int hp82335_command(struct gpib_board *board, u8 *buffer, size_t length, 50 size_t *bytes_written) 51{ 52 struct hp82335_priv *priv = board->private_data; 53 54 return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written); 55} 56 57static int hp82335_take_control(struct gpib_board *board, int synchronous) 58{ 59 struct hp82335_priv *priv = board->private_data; 60 61 return tms9914_take_control(board, &priv->tms9914_priv, synchronous); 62} 63 64static int hp82335_go_to_standby(struct gpib_board *board) 65{ 66 struct hp82335_priv *priv = board->private_data; 67 68 return tms9914_go_to_standby(board, &priv->tms9914_priv); 69} 70 71static int hp82335_request_system_control(struct gpib_board *board, int request_control) 72{ 73 struct hp82335_priv *priv = board->private_data; 74 75 return tms9914_request_system_control(board, &priv->tms9914_priv, request_control); 76} 77 78static void hp82335_interface_clear(struct gpib_board *board, int assert) 79{ 80 struct hp82335_priv *priv = board->private_data; 81 82 tms9914_interface_clear(board, &priv->tms9914_priv, assert); 83} 84 85static void hp82335_remote_enable(struct gpib_board *board, int enable) 86{ 87 struct hp82335_priv *priv = board->private_data; 88 89 tms9914_remote_enable(board, &priv->tms9914_priv, enable); 90} 91 92static int hp82335_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits) 93{ 94 struct hp82335_priv *priv = board->private_data; 95 96 return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits); 97} 98 99static void hp82335_disable_eos(struct gpib_board *board) 100{ 101 struct hp82335_priv *priv = board->private_data; 102 103 tms9914_disable_eos(board, &priv->tms9914_priv); 104} 105 106static unsigned int hp82335_update_status(struct gpib_board *board, unsigned int clear_mask) 107{ 108 struct hp82335_priv *priv = board->private_data; 109 110 return tms9914_update_status(board, &priv->tms9914_priv, clear_mask); 111} 112 113static int hp82335_primary_address(struct gpib_board *board, unsigned int address) 114{ 115 struct hp82335_priv *priv = board->private_data; 116 117 return tms9914_primary_address(board, &priv->tms9914_priv, address); 118} 119 120static int hp82335_secondary_address(struct gpib_board *board, unsigned int address, int enable) 121{ 122 struct hp82335_priv *priv = board->private_data; 123 124 return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable); 125} 126 127static int hp82335_parallel_poll(struct gpib_board *board, u8 *result) 128{ 129 struct hp82335_priv *priv = board->private_data; 130 131 return tms9914_parallel_poll(board, &priv->tms9914_priv, result); 132} 133 134static void hp82335_parallel_poll_configure(struct gpib_board *board, u8 config) 135{ 136 struct hp82335_priv *priv = board->private_data; 137 138 tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config); 139} 140 141static void hp82335_parallel_poll_response(struct gpib_board *board, int ist) 142{ 143 struct hp82335_priv *priv = board->private_data; 144 145 tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist); 146} 147 148static void hp82335_serial_poll_response(struct gpib_board *board, u8 status) 149{ 150 struct hp82335_priv *priv = board->private_data; 151 152 tms9914_serial_poll_response(board, &priv->tms9914_priv, status); 153} 154 155static u8 hp82335_serial_poll_status(struct gpib_board *board) 156{ 157 struct hp82335_priv *priv = board->private_data; 158 159 return tms9914_serial_poll_status(board, &priv->tms9914_priv); 160} 161 162static int hp82335_line_status(const struct gpib_board *board) 163{ 164 struct hp82335_priv *priv = board->private_data; 165 166 return tms9914_line_status(board, &priv->tms9914_priv); 167} 168 169static int hp82335_t1_delay(struct gpib_board *board, unsigned int nano_sec) 170{ 171 struct hp82335_priv *priv = board->private_data; 172 173 return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec); 174} 175 176static void hp82335_return_to_local(struct gpib_board *board) 177{ 178 struct hp82335_priv *priv = board->private_data; 179 180 tms9914_return_to_local(board, &priv->tms9914_priv); 181} 182 183static struct gpib_interface hp82335_interface = { 184 .name = "hp82335", 185 .attach = hp82335_attach, 186 .detach = hp82335_detach, 187 .read = hp82335_read, 188 .write = hp82335_write, 189 .command = hp82335_command, 190 .request_system_control = hp82335_request_system_control, 191 .take_control = hp82335_take_control, 192 .go_to_standby = hp82335_go_to_standby, 193 .interface_clear = hp82335_interface_clear, 194 .remote_enable = hp82335_remote_enable, 195 .enable_eos = hp82335_enable_eos, 196 .disable_eos = hp82335_disable_eos, 197 .parallel_poll = hp82335_parallel_poll, 198 .parallel_poll_configure = hp82335_parallel_poll_configure, 199 .parallel_poll_response = hp82335_parallel_poll_response, 200 .local_parallel_poll_mode = NULL, // XXX 201 .line_status = hp82335_line_status, 202 .update_status = hp82335_update_status, 203 .primary_address = hp82335_primary_address, 204 .secondary_address = hp82335_secondary_address, 205 .serial_poll_response = hp82335_serial_poll_response, 206 .serial_poll_status = hp82335_serial_poll_status, 207 .t1_delay = hp82335_t1_delay, 208 .return_to_local = hp82335_return_to_local, 209}; 210 211static int hp82335_allocate_private(struct gpib_board *board) 212{ 213 board->private_data = kzalloc(sizeof(struct hp82335_priv), GFP_KERNEL); 214 if (!board->private_data) 215 return -1; 216 return 0; 217} 218 219static void hp82335_free_private(struct gpib_board *board) 220{ 221 kfree(board->private_data); 222 board->private_data = NULL; 223} 224 225static inline unsigned int tms9914_to_hp82335_offset(unsigned int register_num) 226{ 227 return 0x1ff8 + register_num; 228} 229 230static u8 hp82335_read_byte(struct tms9914_priv *priv, unsigned int register_num) 231{ 232 return tms9914_iomem_read_byte(priv, tms9914_to_hp82335_offset(register_num)); 233} 234 235static void hp82335_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num) 236{ 237 tms9914_iomem_write_byte(priv, data, tms9914_to_hp82335_offset(register_num)); 238} 239 240static void hp82335_clear_interrupt(struct hp82335_priv *hp_priv) 241{ 242 struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv; 243 244 writeb(0, tms_priv->mmiobase + HPREG_INTR_CLEAR); 245} 246 247static int hp82335_attach(struct gpib_board *board, const struct gpib_board_config *config) 248{ 249 struct hp82335_priv *hp_priv; 250 struct tms9914_priv *tms_priv; 251 int retval; 252 const unsigned long upper_iomem_base = config->ibbase + hp82335_rom_size; 253 254 board->status = 0; 255 256 if (hp82335_allocate_private(board)) 257 return -ENOMEM; 258 hp_priv = board->private_data; 259 tms_priv = &hp_priv->tms9914_priv; 260 tms_priv->read_byte = hp82335_read_byte; 261 tms_priv->write_byte = hp82335_write_byte; 262 tms_priv->offset = 1; 263 264 switch (config->ibbase) { 265 case 0xc4000: 266 case 0xc8000: 267 case 0xcc000: 268 case 0xd0000: 269 case 0xd4000: 270 case 0xd8000: 271 case 0xdc000: 272 case 0xe0000: 273 case 0xe4000: 274 case 0xe8000: 275 case 0xec000: 276 case 0xf0000: 277 case 0xf4000: 278 case 0xf8000: 279 case 0xfc000: 280 break; 281 default: 282 dev_err(board->gpib_dev, "invalid base io address 0x%x\n", config->ibbase); 283 return -EINVAL; 284 } 285 if (!request_mem_region(upper_iomem_base, hp82335_upper_iomem_size, "hp82335")) { 286 dev_err(board->gpib_dev, "failed to allocate io memory region 0x%lx-0x%lx\n", 287 upper_iomem_base, upper_iomem_base + hp82335_upper_iomem_size - 1); 288 return -EBUSY; 289 } 290 hp_priv->raw_iobase = upper_iomem_base; 291 tms_priv->mmiobase = ioremap(upper_iomem_base, hp82335_upper_iomem_size); 292 293 retval = request_irq(config->ibirq, hp82335_interrupt, 0, DRV_NAME, board); 294 if (retval) { 295 dev_err(board->gpib_dev, "can't request IRQ %d\n", config->ibirq); 296 return retval; 297 } 298 hp_priv->irq = config->ibirq; 299 300 tms9914_board_reset(tms_priv); 301 302 hp82335_clear_interrupt(hp_priv); 303 304 writeb(INTR_ENABLE, tms_priv->mmiobase + HPREG_CCR); 305 306 tms9914_online(board, tms_priv); 307 308 return 0; 309} 310 311static void hp82335_detach(struct gpib_board *board) 312{ 313 struct hp82335_priv *hp_priv = board->private_data; 314 struct tms9914_priv *tms_priv; 315 316 if (hp_priv) { 317 tms_priv = &hp_priv->tms9914_priv; 318 if (hp_priv->irq) 319 free_irq(hp_priv->irq, board); 320 if (tms_priv->mmiobase) { 321 writeb(0, tms_priv->mmiobase + HPREG_CCR); 322 tms9914_board_reset(tms_priv); 323 iounmap(tms_priv->mmiobase); 324 } 325 if (hp_priv->raw_iobase) 326 release_mem_region(hp_priv->raw_iobase, hp82335_upper_iomem_size); 327 } 328 hp82335_free_private(board); 329} 330 331static int __init hp82335_init_module(void) 332{ 333 int result = gpib_register_driver(&hp82335_interface, THIS_MODULE); 334 335 if (result) { 336 pr_err("gpib_register_driver failed: error = %d\n", result); 337 return result; 338 } 339 340 return 0; 341} 342 343static void __exit hp82335_exit_module(void) 344{ 345 gpib_unregister_driver(&hp82335_interface); 346} 347 348module_init(hp82335_init_module); 349module_exit(hp82335_exit_module); 350 351/* 352 * GPIB interrupt service routines 353 */ 354 355static irqreturn_t hp82335_interrupt(int irq, void *arg) 356{ 357 int status1, status2; 358 struct gpib_board *board = arg; 359 struct hp82335_priv *priv = board->private_data; 360 unsigned long flags; 361 irqreturn_t retval; 362 363 spin_lock_irqsave(&board->spinlock, flags); 364 status1 = read_byte(&priv->tms9914_priv, ISR0); 365 status2 = read_byte(&priv->tms9914_priv, ISR1); 366 hp82335_clear_interrupt(priv); 367 retval = tms9914_interrupt_have_status(board, &priv->tms9914_priv, status1, status2); 368 spin_unlock_irqrestore(&board->spinlock, flags); 369 return retval; 370} 371
~/
Read-only file preview.