root/drivers/gpib/agilent_82357a/agilent_82357a.h
/* SPDX-License-Identifier: GPL-2.0 */

/***************************************************************************
 *   copyright            : (C) 2004 by Frank Mori Hess                    *
 ***************************************************************************/

#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/usb.h>
#include <linux/timer.h>
#include <linux/compiler_attributes.h>
#include "gpibP.h"
#include "tms9914.h"

enum usb_vendor_ids {
        USB_VENDOR_ID_AGILENT = 0x0957
};

enum usb_device_ids {
        USB_DEVICE_ID_AGILENT_82357A = 0x0107,
        USB_DEVICE_ID_AGILENT_82357A_PREINIT = 0x0007,  // device id before firmware is loaded
        USB_DEVICE_ID_AGILENT_82357B = 0x0718,          // device id before firmware is loaded
        USB_DEVICE_ID_AGILENT_82357B_PREINIT = 0x0518,  // device id before firmware is loaded
};

enum endpoint_addresses {
        AGILENT_82357_CONTROL_ENDPOINT = 0x0,
        AGILENT_82357_BULK_IN_ENDPOINT = 0x2,
        AGILENT_82357A_BULK_OUT_ENDPOINT = 0x4,
        AGILENT_82357A_INTERRUPT_IN_ENDPOINT = 0x6,
        AGILENT_82357B_BULK_OUT_ENDPOINT = 0x6,
        AGILENT_82357B_INTERRUPT_IN_ENDPOINT = 0x8,
};

enum bulk_commands {
        DATA_PIPE_CMD_WRITE = 0x1,
        DATA_PIPE_CMD_READ = 0x3,
        DATA_PIPE_CMD_WR_REGS = 0x4,
        DATA_PIPE_CMD_RD_REGS = 0x5
};

enum agilent_82357a_read_flags {
        ARF_END_ON_EOI = 0x1,
        ARF_NO_ADDRESS = 0x2,
        ARF_END_ON_EOS_CHAR = 0x4,
        ARF_SPOLL = 0x8
};

enum agilent_82357a_trailing_read_flags {
        ATRF_EOI = 0x1,
        ATRF_ATN = 0x2,
        ATRF_IFC = 0x4,
        ATRF_EOS = 0x8,
        ATRF_ABORT = 0x10,
        ATRF_COUNT = 0x20,
        ATRF_DEAD_BUS = 0x40,
        ATRF_UNADDRESSED = 0x80
};

enum agilent_82357a_write_flags {
        AWF_SEND_EOI = 0x1,
        AWF_NO_FAST_TALKER_FIRST_BYTE = 0x2,
        AWF_NO_FAST_TALKER = 0x4,
        AWF_NO_ADDRESS = 0x8,
        AWF_ATN = 0x10,
        AWF_SEPARATE_HEADER = 0x80
};

enum agilent_82357a_interrupt_flag_bit_numbers {
        AIF_SRQ_BN = 0,
        AIF_WRITE_COMPLETE_BN = 1,
        AIF_READ_COMPLETE_BN = 2,
};

enum agilent_82357_error_codes {
        UGP_SUCCESS = 0,
        UGP_ERR_INVALID_CMD = 1,
        UGP_ERR_INVALID_PARAM = 2,
        UGP_ERR_INVALID_REG = 3,
        UGP_ERR_GPIB_READ = 4,
        UGP_ERR_GPIB_WRITE = 5,
        UGP_ERR_FLUSHING = 6,
        UGP_ERR_FLUSHING_ALREADY = 7,
        UGP_ERR_UNSUPPORTED = 8,
        UGP_ERR_OTHER  = 9
};

enum agilent_82357_control_values {
        XFER_ABORT = 0xa0,
        XFER_STATUS = 0xb0,
};

enum xfer_status_bits {
        XS_COMPLETED = 0x1,
        XS_READ = 0x2,
};

enum xfer_status_completion_bits {
        XSC_EOI = 0x1,
        XSC_ATN = 0x2,
        XSC_IFC = 0x4,
        XSC_EOS = 0x8,
        XSC_ABORT = 0x10,
        XSC_COUNT = 0x20,
        XSC_DEAD_BUS = 0x40,
        XSC_BUS_NOT_ADDRESSED = 0x80
};

enum xfer_abort_type {
        XA_FLUSH = 0x1
};

#define STATUS_DATA_LEN 8
#define INTERRUPT_BUF_LEN 8

struct agilent_82357a_urb_ctx {
        struct completion complete;
        unsigned timed_out : 1;
};

// struct which defines local data for each 82357 device
struct agilent_82357a_priv {
        struct usb_interface *bus_interface;
        unsigned short eos_char;
        unsigned short eos_mode;
        unsigned short hw_control_bits;
        unsigned long interrupt_flags;
        struct urb *bulk_urb;
        struct urb *interrupt_urb;
        u8 *interrupt_buffer;
        struct mutex bulk_transfer_lock;        // bulk transfer lock
        struct mutex bulk_alloc_lock;           // bulk transfer allocation lock
        struct mutex interrupt_alloc_lock;      // interrupt allocation lock
        struct mutex control_alloc_lock;        // control message allocation lock
        struct timer_list bulk_timer;
        struct agilent_82357a_urb_ctx context;
        unsigned int bulk_out_endpoint;
        unsigned int interrupt_in_endpoint;
        unsigned is_cic : 1;
        unsigned ren_state : 1;
};

struct agilent_82357a_register_pairlet {
        short address;
        unsigned short value;
};

enum firmware_registers {
        HW_CONTROL = 0xa,
        LED_CONTROL = 0xb,
        RESET_TO_POWERUP = 0xc,
        PROTOCOL_CONTROL = 0xd,
        FAST_TALKER_T1 = 0xe
};

enum hardware_control_bits {
        NOT_TI_RESET = 0x1,
        SYSTEM_CONTROLLER = 0x2,
        NOT_PARALLEL_POLL = 0x4,
        OSCILLATOR_5V_ON = 0x8,
        OUTPUT_5V_ON = 0x20,
        CPLD_3V_ON = 0x80,
};

enum led_control_bits {
        FIRMWARE_LED_CONTROL = 0x1,
        FAIL_LED_ON = 0x20,
        READY_LED_ON = 0x40,
        ACCESS_LED_ON = 0x80
};

enum reset_to_powerup_bits {
        RESET_SPACEBALL = 0x1,  // wait 2 millisec after sending
};

enum protocol_control_bits {
        WRITE_COMPLETE_INTERRUPT_EN = 0x1,
};

static const int agilent_82357a_control_request = 0x4;