^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) National Semiconductor SCx200 ACCESS.bus support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) Also supports the AMD CS5535 and AMD CS5536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) Based on i2c-keywest.c which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/scx200.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MODULE_ALIAS("platform:cs5535-smb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MAX_DEVICES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int base[MAX_DEVICES] = { 0x820, 0x840 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) module_param_hw_array(base, int, ioport, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define POLL_TIMEOUT (HZ/5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) enum scx200_acb_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) state_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) state_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) state_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) state_repeat_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) state_quick,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) state_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) state_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static const char *scx200_acb_state_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) "idle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "address",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "command",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "repeat_start",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "quick",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "read",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "write",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Physical interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct scx200_acb_iface {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct scx200_acb_iface *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct i2c_adapter adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* State machine data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) enum scx200_acb_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u8 address_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) char needs_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Register Definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define ACBSDA (iface->base + 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define ACBST (iface->base + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define ACBST_SDAST 0x40 /* SDA Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ACBST_BER 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define ACBST_NEGACK 0x10 /* Negative Acknowledge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define ACBST_STASTR 0x08 /* Stall After Start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define ACBST_MASTER 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ACBCST (iface->base + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ACBCST_BB 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define ACBCTL1 (iface->base + 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define ACBCTL1_STASTRE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define ACBCTL1_NMINTE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define ACBCTL1_ACK 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ACBCTL1_STOP 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define ACBCTL1_START 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define ACBADDR (iface->base + 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ACBCTL2 (iface->base + 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define ACBCTL2_ENABLE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) const char *errmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) scx200_acb_state_name[iface->state], status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (status & ACBST_BER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) errmsg = "bus error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (!(status & ACBST_MASTER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) errmsg = "not master";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (status & ACBST_NEGACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dev_dbg(&iface->adapter.dev, "negative ack in state %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) scx200_acb_state_name[iface->state]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) iface->state = state_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) iface->result = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Reset the status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) outb(0, ACBST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) switch (iface->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) case state_idle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case state_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* Do a pointer write first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) outb(iface->address_byte & ~1, ACBSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) iface->state = state_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case state_command:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) outb(iface->command, ACBSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (iface->address_byte & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) iface->state = state_repeat_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) iface->state = state_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case state_repeat_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case state_quick:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (iface->address_byte & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (iface->len == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) outb(iface->address_byte, ACBSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) iface->state = state_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) outb(iface->address_byte, ACBSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) iface->state = state_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case state_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Set ACK if _next_ byte will be the last one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (iface->len == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (iface->len == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) iface->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) iface->state = state_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *iface->ptr++ = inb(ACBSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) --iface->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case state_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (iface->len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) iface->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) iface->state = state_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) outb(*iface->ptr++, ACBSDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) --iface->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) dev_err(&iface->adapter.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) "%s in state %s (addr=0x%02x, len=%d, status=0x%02x)\n", errmsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) scx200_acb_state_name[iface->state], iface->address_byte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) iface->len, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) iface->state = state_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) iface->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) iface->needs_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static void scx200_acb_poll(struct scx200_acb_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) timeout = jiffies + POLL_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) status = inb(ACBST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* Reset the status register to avoid the hang */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) outb(0, ACBST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) scx200_acb_machine(iface, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (time_after(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dev_err(&iface->adapter.dev, "timeout in state %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) scx200_acb_state_name[iface->state]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) iface->state = state_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) iface->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) iface->needs_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void scx200_acb_reset(struct scx200_acb_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Disable the ACCESS.bus device and Configure the SCL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) frequency: 16 clock cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) outb(0x70, ACBCTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Polling mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) outb(0, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* Disable slave address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) outb(0, ACBADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* Enable the ACCESS.bus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* Free STALL after START */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Send a STOP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Clear BER, NEGACK and STASTR bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Clear BB bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) outb(inb(ACBCST) | ACBCST_BB, ACBCST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u16 address, unsigned short flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) char rw, u8 command, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) union i2c_smbus_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u8 *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u16 cur_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case I2C_SMBUS_QUICK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case I2C_SMBUS_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) buffer = rw ? &data->byte : &command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case I2C_SMBUS_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) buffer = &data->byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case I2C_SMBUS_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) cur_word = cpu_to_le16(data->word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) buffer = (u8 *)&cur_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case I2C_SMBUS_I2C_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) len = data->block[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) buffer = &data->block[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) size, address, command, len, rw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!len && rw == I2C_SMBUS_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dev_dbg(&adapter->dev, "zero length read\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mutex_lock(&iface->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) iface->address_byte = (address << 1) | rw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) iface->command = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) iface->ptr = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) iface->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) iface->result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) iface->needs_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) iface->state = state_quick;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) iface->state = state_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) while (iface->state != state_idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) scx200_acb_poll(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (iface->needs_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) scx200_acb_reset(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) rc = iface->result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mutex_unlock(&iface->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) data->word = le16_to_cpu(cur_word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev_dbg(&adapter->dev, "transfer done, result: %d", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) printk(" data:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) for (i = 0; i < len; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) printk(" %02x", buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static u32 scx200_acb_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) I2C_FUNC_SMBUS_I2C_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* For now, we only handle combined mode (smbus) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static const struct i2c_algorithm scx200_acb_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .smbus_xfer = scx200_acb_smbus_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .functionality = scx200_acb_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static struct scx200_acb_iface *scx200_acb_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static DEFINE_MUTEX(scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int scx200_acb_probe(struct scx200_acb_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* Disable the ACCESS.bus device and Configure the SCL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) frequency: 16 clock cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) outb(0x70, ACBCTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (inb(ACBCTL2) != 0x70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pr_debug("ACBCTL2 readback failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) val = inb(ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pr_debug("disabled, but ACBCTL1=0x%02x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) val = inb(ACBCTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pr_debug("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static struct scx200_acb_iface *scx200_create_iface(const char *text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct device *dev, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct scx200_acb_iface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct i2c_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) iface = kzalloc(sizeof(*iface), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) adapter = &iface->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) i2c_set_adapdata(adapter, iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) adapter->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) adapter->algo = &scx200_acb_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) adapter->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) mutex_init(&iface->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int scx200_acb_create(struct scx200_acb_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct i2c_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) adapter = &iface->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) rc = scx200_acb_probe(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) pr_warn("probe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) scx200_acb_reset(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (i2c_add_adapter(adapter) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) pr_err("failed to register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!adapter->dev.parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* If there's no dev, we're tracking (ISA) ifaces manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) mutex_lock(&scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) iface->next = scx200_acb_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) scx200_acb_list = iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mutex_unlock(&scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static struct scx200_acb_iface *scx200_create_dev(const char *text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) unsigned long base, int index, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct scx200_acb_iface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) iface = scx200_create_iface(text, dev, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (iface == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!request_region(base, 8, iface->adapter.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pr_err("can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) goto errout_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) iface->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) rc = scx200_acb_create(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) release_region(base, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) errout_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) kfree(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int scx200_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct scx200_acb_iface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) res = platform_get_resource(pdev, IORESOURCE_IO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) dev_err(&pdev->dev, "can't fetch device resource info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) iface = scx200_create_dev("CS5535", res->start, 0, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_info(&pdev->dev, "SCx200 device '%s' registered\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) iface->adapter.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) platform_set_drvdata(pdev, iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static void scx200_cleanup_iface(struct scx200_acb_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) i2c_del_adapter(&iface->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) release_region(iface->base, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) kfree(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int scx200_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct scx200_acb_iface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) iface = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) scx200_cleanup_iface(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static struct platform_driver scx200_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .name = "cs5535-smb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .probe = scx200_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .remove = scx200_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static const struct pci_device_id scx200_isa[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static __init void scx200_scan_isa(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (!pci_dev_present(scx200_isa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) for (i = 0; i < MAX_DEVICES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (base[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* XXX: should we care about failures? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) scx200_create_dev("SCx200", base[i], i, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int __init scx200_acb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) pr_debug("NatSemi SCx200 ACCESS.bus Driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* First scan for ISA-based devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) scx200_scan_isa(); /* XXX: should we care about errors? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* If at least one bus was created, init must succeed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (scx200_acb_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* No ISA devices; register the platform driver for PCI-based devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return platform_driver_register(&scx200_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static void __exit scx200_acb_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct scx200_acb_iface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) platform_driver_unregister(&scx200_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) mutex_lock(&scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) while ((iface = scx200_acb_list) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) scx200_acb_list = iface->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) mutex_unlock(&scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) scx200_cleanup_iface(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) mutex_lock(&scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mutex_unlock(&scx200_acb_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) module_init(scx200_acb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) module_exit(scx200_acb_cleanup);