diff options
author | 2023-02-21 18:24:12 -0800 | |
---|---|---|
committer | 2023-02-21 18:24:12 -0800 | |
commit | 5b7c4cabbb65f5c469464da6c5f614cbd7f730f2 (patch) | |
tree | cc5c2d0a898769fd59549594fedb3ee6f84e59a0 /arch/m68k/atari/atakeyb.c | |
download | linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.tar.gz linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.zip |
Merge tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-nextgrafted
Pull networking updates from Jakub Kicinski:
"Core:
- Add dedicated kmem_cache for typical/small skb->head, avoid having
to access struct page at kfree time, and improve memory use.
- Introduce sysctl to set default RPS configuration for new netdevs.
- Define Netlink protocol specification format which can be used to
describe messages used by each family and auto-generate parsers.
Add tools for generating kernel data structures and uAPI headers.
- Expose all net/core sysctls inside netns.
- Remove 4s sleep in netpoll if carrier is instantly detected on
boot.
- Add configurable limit of MDB entries per port, and port-vlan.
- Continue populating drop reasons throughout the stack.
- Retire a handful of legacy Qdiscs and classifiers.
Protocols:
- Support IPv4 big TCP (TSO frames larger than 64kB).
- Add IP_LOCAL_PORT_RANGE socket option, to control local port range
on socket by socket basis.
- Track and report in procfs number of MPTCP sockets used.
- Support mixing IPv4 and IPv6 flows in the in-kernel MPTCP path
manager.
- IPv6: don't check net.ipv6.route.max_size and rely on garbage
collection to free memory (similarly to IPv4).
- Support Penultimate Segment Pop (PSP) flavor in SRv6 (RFC8986).
- ICMP: add per-rate limit counters.
- Add support for user scanning requests in ieee802154.
- Remove static WEP support.
- Support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate
reporting.
- WiFi 7 EHT channel puncturing support (client & AP).
BPF:
- Add a rbtree data structure following the "next-gen data structure"
precedent set by recently added linked list, that is, by using
kfunc + kptr instead of adding a new BPF map type.
- Expose XDP hints via kfuncs with initial support for RX hash and
timestamp metadata.
- Add BPF_F_NO_TUNNEL_KEY extension to bpf_skb_set_tunnel_key to
better support decap on GRE tunnel devices not operating in collect
metadata.
- Improve x86 JIT's codegen for PROBE_MEM runtime error checks.
- Remove the need for trace_printk_lock for bpf_trace_printk and
bpf_trace_vprintk helpers.
- Extend libbpf's bpf_tracing.h support for tracing arguments of
kprobes/uprobes and syscall as a special case.
- Significantly reduce the search time for module symbols by
livepatch and BPF.
- Enable cpumasks to be used as kptrs, which is useful for tracing
programs tracking which tasks end up running on which CPUs in
different time intervals.
- Add support for BPF trampoline on s390x and riscv64.
- Add capability to export the XDP features supported by the NIC.
- Add __bpf_kfunc tag for marking kernel functions as kfuncs.
- Add cgroup.memory=nobpf kernel parameter option to disable BPF
memory accounting for container environments.
Netfilter:
- Remove the CLUSTERIP target. It has been marked as obsolete for
years, and we still have WARN splats wrt races of the out-of-band
/proc interface installed by this target.
- Add 'destroy' commands to nf_tables. They are identical to the
existing 'delete' commands, but do not return an error if the
referenced object (set, chain, rule...) did not exist.
Driver API:
- Improve cpumask_local_spread() locality to help NICs set the right
IRQ affinity on AMD platforms.
- Separate C22 and C45 MDIO bus transactions more clearly.
- Introduce new DCB table to control DSCP rewrite on egress.
- Support configuration of Physical Layer Collision Avoidance (PLCA)
Reconciliation Sublayer (RS) (802.3cg-2019). Modern version of
shared medium Ethernet.
- Support for MAC Merge layer (IEEE 802.3-2018 clause 99). Allowing
preemption of low priority frames by high priority frames.
- Add support for controlling MACSec offload using netlink SET.
- Rework devlink instance refcounts to allow registration and
de-registration under the instance lock. Split the code into
multiple files, drop some of the unnecessarily granular locks and
factor out common parts of netlink operation handling.
- Add TX frame aggregation parameters (for USB drivers).
- Add a new attr TCA_EXT_WARN_MSG to report TC (offload) warning
messages with notifications for debug.
- Allow offloading of UDP NEW connections via act_ct.
- Add support for per action HW stats in TC.
- Support hardware miss to TC action (continue processing in SW from
a specific point in the action chain).
- Warn if old Wireless Extension user space interface is used with
modern cfg80211/mac80211 drivers. Do not support Wireless
Extensions for Wi-Fi 7 devices at all. Everyone should switch to
using nl80211 interface instead.
- Improve the CAN bit timing configuration. Use extack to return
error messages directly to user space, update the SJW handling,
including the definition of a new default value that will benefit
CAN-FD controllers, by increasing their oscillator tolerance.
New hardware / drivers:
- Ethernet:
- nVidia BlueField-3 support (control traffic driver)
- Ethernet support for imx93 SoCs
- Motorcomm yt8531 gigabit Ethernet PHY
- onsemi NCN26000 10BASE-T1S PHY (with support for PLCA)
- Microchip LAN8841 PHY (incl. cable diagnostics and PTP)
- Amlogic gxl MDIO mux
- WiFi:
- RealTek RTL8188EU (rtl8xxxu)
- Qualcomm Wi-Fi 7 devices (ath12k)
- CAN:
- Renesas R-Car V4H
Drivers:
- Bluetooth:
- Set Per Platform Antenna Gain (PPAG) for Intel controllers.
- Ethernet NICs:
- Intel (1G, igc):
- support TSN / Qbv / packet scheduling features of i226 model
- Intel (100G, ice):
- use GNSS subsystem instead of TTY
- multi-buffer XDP support
- extend support for GPIO pins to E823 devices
- nVidia/Mellanox:
- update the shared buffer configuration on PFC commands
- implement PTP adjphase function for HW offset control
- TC support for Geneve and GRE with VF tunnel offload
- more efficient crypto key management method
- multi-port eswitch support
- Netronome/Corigine:
- add DCB IEEE support
- support IPsec offloading for NFP3800
- Freescale/NXP (enetc):
- support XDP_REDIRECT for XDP non-linear buffers
- improve reconfig, avoid link flap and waiting for idle
- support MAC Merge layer
- Other NICs:
- sfc/ef100: add basic devlink support for ef100
- ionic: rx_push mode operation (writing descriptors via MMIO)
- bnxt: use the auxiliary bus abstraction for RDMA
- r8169: disable ASPM and reset bus in case of tx timeout
- cpsw: support QSGMII mode for J721e CPSW9G
- cpts: support pulse-per-second output
- ngbe: add an mdio bus driver
- usbnet: optimize usbnet_bh() by avoiding unnecessary queuing
- r8152: handle devices with FW with NCM support
- amd-xgbe: support 10Mbps, 2.5GbE speeds and rx-adaptation
- virtio-net: support multi buffer XDP
- virtio/vsock: replace virtio_vsock_pkt with sk_buff
- tsnep: XDP support
- Ethernet high-speed switches:
- nVidia/Mellanox (mlxsw):
- add support for latency TLV (in FW control messages)
- Microchip (sparx5):
- separate explicit and implicit traffic forwarding rules, make
the implicit rules always active
- add support for egress DSCP rewrite
- IS0 VCAP support (Ingress Classification)
- IS2 VCAP filters (protos, L3 addrs, L4 ports, flags, ToS
etc.)
- ES2 VCAP support (Egress Access Control)
- support for Per-Stream Filtering and Policing (802.1Q,
8.6.5.1)
- Ethernet embedded switches:
- Marvell (mv88e6xxx):
- add MAB (port auth) offload support
- enable PTP receive for mv88e6390
- NXP (ocelot):
- support MAC Merge layer
- support for the the vsc7512 internal copper phys
- Microchip:
- lan9303: convert to PHYLINK
- lan966x: support TC flower filter statistics
- lan937x: PTP support for KSZ9563/KSZ8563 and LAN937x
- lan937x: support Credit Based Shaper configuration
- ksz9477: support Energy Efficient Ethernet
- other:
- qca8k: convert to regmap read/write API, use bulk operations
- rswitch: Improve TX timestamp accuracy
- Intel WiFi (iwlwifi):
- EHT (Wi-Fi 7) rate reporting
- STEP equalizer support: transfer some STEP (connection to radio
on platforms with integrated wifi) related parameters from the
BIOS to the firmware.
- Qualcomm 802.11ax WiFi (ath11k):
- IPQ5018 support
- Fine Timing Measurement (FTM) responder role support
- channel 177 support
- MediaTek WiFi (mt76):
- per-PHY LED support
- mt7996: EHT (Wi-Fi 7) support
- Wireless Ethernet Dispatch (WED) reset support
- switch to using page pool allocator
- RealTek WiFi (rtw89):
- support new version of Bluetooth co-existance
- Mobile:
- rmnet: support TX aggregation"
* tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1872 commits)
page_pool: add a comment explaining the fragment counter usage
net: ethtool: fix __ethtool_dev_mm_supported() implementation
ethtool: pse-pd: Fix double word in comments
xsk: add linux/vmalloc.h to xsk.c
sefltests: netdevsim: wait for devlink instance after netns removal
selftest: fib_tests: Always cleanup before exit
net/mlx5e: Align IPsec ASO result memory to be as required by hardware
net/mlx5e: TC, Set CT miss to the specific ct action instance
net/mlx5e: Rename CHAIN_TO_REG to MAPPED_OBJ_TO_REG
net/mlx5: Refactor tc miss handling to a single function
net/mlx5: Kconfig: Make tc offload depend on tc skb extension
net/sched: flower: Support hardware miss to tc action
net/sched: flower: Move filter handle initialization earlier
net/sched: cls_api: Support hardware miss to tc action
net/sched: Rename user cookie and act cookie
sfc: fix builds without CONFIG_RTC_LIB
sfc: clean up some inconsistent indentings
net/mlx4_en: Introduce flexible array to silence overflow warning
net: lan966x: Fix possible deadlock inside PTP
net/ulp: Remove redundant ->clone() test in inet_clone_ulp().
...
Diffstat (limited to 'arch/m68k/atari/atakeyb.c')
-rw-r--r-- | arch/m68k/atari/atakeyb.c | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c new file mode 100644 index 000000000..5e0e682f9 --- /dev/null +++ b/arch/m68k/atari/atakeyb.c @@ -0,0 +1,570 @@ +/* + * Atari Keyboard driver for 680x0 Linux + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/* + * Atari support by Robert de Vries + * enhanced by Bjoern Brauel and Roman Hodek + * + * 2.6 and input cleanup (removed autorepeat stuff) for 2.6.21 + * 06/07 Michael Schmitz + */ + +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/errno.h> +#include <linux/keyboard.h> +#include <linux/delay.h> +#include <linux/timer.h> +#include <linux/kd.h> +#include <linux/random.h> +#include <linux/init.h> +#include <linux/kbd_kern.h> + +#include <asm/atariints.h> +#include <asm/atarihw.h> +#include <asm/atarikb.h> +#include <asm/atari_joystick.h> +#include <asm/irq.h> + + +/* Hook for MIDI serial driver */ +void (*atari_MIDI_interrupt_hook) (void); +/* Hook for keyboard inputdev driver */ +void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); +/* Hook for mouse inputdev driver */ +void (*atari_input_mouse_interrupt_hook) (char *); +EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook); +EXPORT_SYMBOL(atari_input_mouse_interrupt_hook); + +/* variables for IKBD self test: */ + +/* state: 0: off; >0: in progress; >1: 0xf1 received */ +static volatile int ikbd_self_test; +/* timestamp when last received a char */ +static volatile unsigned long self_test_last_rcv; +/* bitmap of keys reported as broken */ +static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, }; + +#define BREAK_MASK (0x80) + +/* + * ++roman: The following changes were applied manually: + * + * - The Alt (= Meta) key works in combination with Shift and + * Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends + * Meta-Ctrl-A (0x81) ... + * + * - The parentheses on the keypad send '(' and ')' with all + * modifiers (as would do e.g. keypad '+'), but they cannot be used as + * application keys (i.e. sending Esc O c). + * + * - HELP and UNDO are mapped to be F21 and F24, resp, that send the + * codes "\E[M" and "\E[P". (This is better than the old mapping to + * F11 and F12, because these codes are on Shift+F1/2 anyway.) This + * way, applications that allow their own keyboard mappings + * (e.g. tcsh, X Windows) can be configured to use them in the way + * the label suggests (providing help or undoing). + * + * - Console switching is done with Alt+Fx (consoles 1..10) and + * Shift+Alt+Fx (consoles 11..20). + * + * - The misc. special function implemented in the kernel are mapped + * to the following key combinations: + * + * ClrHome -> Home/Find + * Shift + ClrHome -> End/Select + * Shift + Up -> Page Up + * Shift + Down -> Page Down + * Alt + Help -> show system status + * Shift + Help -> show memory info + * Ctrl + Help -> show registers + * Ctrl + Alt + Del -> Reboot + * Alt + Undo -> switch to last console + * Shift + Undo -> send interrupt + * Alt + Insert -> stop/start output (same as ^S/^Q) + * Alt + Up -> Scroll back console (if implemented) + * Alt + Down -> Scroll forward console (if implemented) + * Alt + CapsLock -> NumLock + * + * ++Andreas: + * + * - Help mapped to K_HELP + * - Undo mapped to K_UNDO (= K_F246) + * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR] + */ + +typedef enum kb_state_t { + KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC +} KB_STATE_T; + +#define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb) + +typedef struct keyboard_state { + unsigned char buf[6]; + int len; + KB_STATE_T state; +} KEYBOARD_STATE; + +KEYBOARD_STATE kb_state; + +/* ++roman: If a keyboard overrun happened, we can't tell in general how much + * bytes have been lost and in which state of the packet structure we are now. + * This usually causes keyboards bytes to be interpreted as mouse movements + * and vice versa, which is very annoying. It seems better to throw away some + * bytes (that are usually mouse bytes) than to misinterpret them. Therefore I + * introduced the RESYNC state for IKBD data. In this state, the bytes up to + * one that really looks like a key event (0x04..0xf2) or the start of a mouse + * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least + * speeds up the resynchronization of the event structure, even if maybe a + * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03, + * it's really hard to decide whether they're mouse or keyboard bytes. Since + * overruns usually occur when moving the Atari mouse rapidly, they're seen as + * mouse bytes here. If this is wrong, only a make code of the keyboard gets + * lost, which isn't too bad. Losing a break code would be disastrous, + * because then the keyboard repeat strikes... + */ + +static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy) +{ + u_char acia_stat; + int scancode; + int break_flag; + +repeat: + if (acia.mid_ctrl & ACIA_IRQ) + if (atari_MIDI_interrupt_hook) + atari_MIDI_interrupt_hook(); + acia_stat = acia.key_ctrl; + /* check out if the interrupt came from this ACIA */ + if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ)) + return IRQ_HANDLED; + + if (acia_stat & ACIA_OVRN) { + /* a very fast typist or a slow system, give a warning */ + /* ...happens often if interrupts were disabled for too long */ + pr_debug("Keyboard overrun\n"); + scancode = acia.key_data; + if (ikbd_self_test) + /* During self test, don't do resyncing, just process the code */ + goto interpret_scancode; + else if (IS_SYNC_CODE(scancode)) { + /* This code seem already to be the start of a new packet or a + * single scancode */ + kb_state.state = KEYBOARD; + goto interpret_scancode; + } else { + /* Go to RESYNC state and skip this byte */ + kb_state.state = RESYNC; + kb_state.len = 1; /* skip max. 1 another byte */ + goto repeat; + } + } + + if (acia_stat & ACIA_RDRF) { + /* received a character */ + scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */ + interpret_scancode: + switch (kb_state.state) { + case KEYBOARD: + switch (scancode) { + case 0xF7: + kb_state.state = AMOUSE; + kb_state.len = 0; + break; + + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + kb_state.state = RMOUSE; + kb_state.len = 1; + kb_state.buf[0] = scancode; + break; + + case 0xFC: + kb_state.state = CLOCK; + kb_state.len = 0; + break; + + case 0xFE: + case 0xFF: + kb_state.state = JOYSTICK; + kb_state.len = 1; + kb_state.buf[0] = scancode; + break; + + case 0xF1: + /* during self-test, note that 0xf1 received */ + if (ikbd_self_test) { + ++ikbd_self_test; + self_test_last_rcv = jiffies; + break; + } + fallthrough; + + default: + break_flag = scancode & BREAK_MASK; + scancode &= ~BREAK_MASK; + if (ikbd_self_test) { + /* Scancodes sent during the self-test stand for broken + * keys (keys being down). The code *should* be a break + * code, but nevertheless some AT keyboard interfaces send + * make codes instead. Therefore, simply ignore + * break_flag... + */ + int keyval, keytyp; + + set_bit(scancode, broken_keys); + self_test_last_rcv = jiffies; + /* new Linux scancodes; approx. */ + keyval = scancode; + keytyp = KTYP(keyval) - 0xf0; + keyval = KVAL(keyval); + + pr_warn("Key with scancode %d ", scancode); + if (keytyp == KT_LATIN || keytyp == KT_LETTER) { + if (keyval < ' ') + pr_cont("('^%c') ", keyval + '@'); + else + pr_cont("('%c') ", keyval); + } + pr_cont("is broken -- will be ignored.\n"); + break; + } else if (test_bit(scancode, broken_keys)) + break; + + if (atari_input_keyboard_interrupt_hook) + atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag); + break; + } + break; + + case AMOUSE: + kb_state.buf[kb_state.len++] = scancode; + if (kb_state.len == 5) { + kb_state.state = KEYBOARD; + /* not yet used */ + /* wake up someone waiting for this */ + } + break; + + case RMOUSE: + kb_state.buf[kb_state.len++] = scancode; + if (kb_state.len == 3) { + kb_state.state = KEYBOARD; + if (atari_input_mouse_interrupt_hook) + atari_input_mouse_interrupt_hook(kb_state.buf); + } + break; + + case JOYSTICK: + kb_state.buf[1] = scancode; + kb_state.state = KEYBOARD; +#ifdef FIXED_ATARI_JOYSTICK + atari_joystick_interrupt(kb_state.buf); +#endif + break; + + case CLOCK: + kb_state.buf[kb_state.len++] = scancode; + if (kb_state.len == 6) { + kb_state.state = KEYBOARD; + /* wake up someone waiting for this. + But will this ever be used, as Linux keeps its own time. + Perhaps for synchronization purposes? */ + /* wake_up_interruptible(&clock_wait); */ + } + break; + + case RESYNC: + if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) { + kb_state.state = KEYBOARD; + goto interpret_scancode; + } + kb_state.len--; + break; + } + } + +#if 0 + if (acia_stat & ACIA_CTS) + /* cannot happen */; +#endif + + if (acia_stat & (ACIA_FE | ACIA_PE)) { + pr_err("Error in keyboard communication\n"); + } + + /* handle_scancode() can take a lot of time, so check again if + * some character arrived + */ + goto repeat; +} + +/* + * I write to the keyboard without using interrupts, I poll instead. + * This takes for the maximum length string allowed (7) at 7812.5 baud + * 8 data 1 start 1 stop bit: 9.0 ms + * If this takes too long for normal operation, interrupt driven writing + * is the solution. (I made a feeble attempt in that direction but I + * kept it simple for now.) + */ +void ikbd_write(const char *str, int len) +{ + u_char acia_stat; + + if ((len < 1) || (len > 7)) + panic("ikbd: maximum string length exceeded"); + while (len) { + acia_stat = acia.key_ctrl; + if (acia_stat & ACIA_TDRE) { + acia.key_data = *str++; + len--; + } + } +} + +/* Reset (without touching the clock) */ +void ikbd_reset(void) +{ + static const char cmd[2] = { 0x80, 0x01 }; + + ikbd_write(cmd, 2); + + /* + * if all's well code 0xF1 is returned, else the break codes of + * all keys making contact + */ +} + +/* Set mouse button action */ +void ikbd_mouse_button_action(int mode) +{ + char cmd[2] = { 0x07, mode }; + + ikbd_write(cmd, 2); +} + +/* Set relative mouse position reporting */ +void ikbd_mouse_rel_pos(void) +{ + static const char cmd[1] = { 0x08 }; + + ikbd_write(cmd, 1); +} +EXPORT_SYMBOL(ikbd_mouse_rel_pos); + +/* Set absolute mouse position reporting */ +void ikbd_mouse_abs_pos(int xmax, int ymax) +{ + char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF }; + + ikbd_write(cmd, 5); +} + +/* Set mouse keycode mode */ +void ikbd_mouse_kbd_mode(int dx, int dy) +{ + char cmd[3] = { 0x0A, dx, dy }; + + ikbd_write(cmd, 3); +} + +/* Set mouse threshold */ +void ikbd_mouse_thresh(int x, int y) +{ + char cmd[3] = { 0x0B, x, y }; + + ikbd_write(cmd, 3); +} +EXPORT_SYMBOL(ikbd_mouse_thresh); + +/* Set mouse scale */ +void ikbd_mouse_scale(int x, int y) +{ + char cmd[3] = { 0x0C, x, y }; + + ikbd_write(cmd, 3); +} + +/* Interrogate mouse position */ +void ikbd_mouse_pos_get(int *x, int *y) +{ + static const char cmd[1] = { 0x0D }; + + ikbd_write(cmd, 1); + + /* wait for returning bytes */ +} + +/* Load mouse position */ +void ikbd_mouse_pos_set(int x, int y) +{ + char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF }; + + ikbd_write(cmd, 6); +} + +/* Set Y=0 at bottom */ +void ikbd_mouse_y0_bot(void) +{ + static const char cmd[1] = { 0x0F }; + + ikbd_write(cmd, 1); +} + +/* Set Y=0 at top */ +void ikbd_mouse_y0_top(void) +{ + static const char cmd[1] = { 0x10 }; + + ikbd_write(cmd, 1); +} +EXPORT_SYMBOL(ikbd_mouse_y0_top); + +/* Disable mouse */ +void ikbd_mouse_disable(void) +{ + static const char cmd[1] = { 0x12 }; + + ikbd_write(cmd, 1); +} +EXPORT_SYMBOL(ikbd_mouse_disable); + +/* Set joystick event reporting */ +void ikbd_joystick_event_on(void) +{ + static const char cmd[1] = { 0x14 }; + + ikbd_write(cmd, 1); +} + +/* Set joystick interrogation mode */ +void ikbd_joystick_event_off(void) +{ + static const char cmd[1] = { 0x15 }; + + ikbd_write(cmd, 1); +} + +/* Joystick interrogation */ +void ikbd_joystick_get_state(void) +{ + static const char cmd[1] = { 0x16 }; + + ikbd_write(cmd, 1); +} + +#if 0 +/* This disables all other ikbd activities !!!! */ +/* Set joystick monitoring */ +void ikbd_joystick_monitor(int rate) +{ + static const char cmd[2] = { 0x17, rate }; + + ikbd_write(cmd, 2); + + kb_state.state = JOYSTICK_MONITOR; +} +#endif + +/* some joystick routines not in yet (0x18-0x19) */ + +/* Disable joysticks */ +void ikbd_joystick_disable(void) +{ + static const char cmd[1] = { 0x1A }; + + ikbd_write(cmd, 1); +} + +/* + * The original code sometimes left the interrupt line of + * the ACIAs low forever. I hope, it is fixed now. + * + * Martin Rogge, 20 Aug 1995 + */ + +static int atari_keyb_done = 0; + +int atari_keyb_init(void) +{ + int error; + + if (atari_keyb_done) + return 0; + + kb_state.state = KEYBOARD; + kb_state.len = 0; + + error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, 0, + "keyboard,mouse,MIDI", atari_keyboard_interrupt); + if (error) + return error; + + atari_turnoff_irq(IRQ_MFP_ACIA); + do { + /* reset IKBD ACIA */ + acia.key_ctrl = ACIA_RESET | + ((atari_switches & ATARI_SWITCH_IKBD) ? + ACIA_RHTID : 0); + (void)acia.key_ctrl; + (void)acia.key_data; + + /* reset MIDI ACIA */ + acia.mid_ctrl = ACIA_RESET | + ((atari_switches & ATARI_SWITCH_MIDI) ? + ACIA_RHTID : 0); + (void)acia.mid_ctrl; + (void)acia.mid_data; + + /* divide 500kHz by 64 gives 7812.5 baud */ + /* 8 data no parity 1 start 1 stop bit */ + /* receive interrupt enabled */ + /* RTS low (except if switch selected), transmit interrupt disabled */ + acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) | + ((atari_switches & ATARI_SWITCH_IKBD) ? + ACIA_RHTID : ACIA_RLTID); + + acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | + ((atari_switches & ATARI_SWITCH_MIDI) ? + ACIA_RHTID : 0); + + /* make sure the interrupt line is up */ + } while ((st_mfp.par_dt_reg & 0x10) == 0); + + /* enable ACIA Interrupts */ + st_mfp.active_edge &= ~0x10; + atari_turnon_irq(IRQ_MFP_ACIA); + + ikbd_self_test = 1; + ikbd_reset(); + /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's + * self-test is finished */ + self_test_last_rcv = jiffies; + while (time_before(jiffies, self_test_last_rcv + HZ/4)) + barrier(); + /* if not incremented: no 0xf1 received */ + if (ikbd_self_test == 1) + pr_err("Keyboard self test failed!\n"); + ikbd_self_test = 0; + + ikbd_mouse_disable(); + ikbd_joystick_disable(); + +#ifdef FIXED_ATARI_JOYSTICK + atari_joystick_init(); +#endif + + // flag init done + atari_keyb_done = 1; + return 0; +} +EXPORT_SYMBOL_GPL(atari_keyb_init); |