^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) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Philip Edelbrock <phil@netroedge.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /* Note: we assume there can only be one SIS5595 with one SMBus interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) Note: all have mfr. ID 0x1039.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) SUPPORTED PCI ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 5595 0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) Note: these chips contain a 0008 device which is incompatible with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 5595. We recognize these by the presence of the listed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) "blacklist" PCI ID and refuse to load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) NOT SUPPORTED PCI ID BLACKLIST PCI ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 540 0008 0540
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 550 0008 0550
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 5513 0008 5511
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 5581 0008 5597
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 5582 0008 5597
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 5597 0008 5597
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 5598 0008 5597/5598
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 630 0008 0630
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 645 0008 0645
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 646 0008 0646
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 648 0008 0648
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 650 0008 0650
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 651 0008 0651
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 730 0008 0730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 735 0008 0735
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 745 0008 0745
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 746 0008 0746
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* TO DO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Add Block Transfers (ugly, but supported by the adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Add adapter resets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int blacklist[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) PCI_DEVICE_ID_SI_540,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) PCI_DEVICE_ID_SI_550,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) PCI_DEVICE_ID_SI_630,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) PCI_DEVICE_ID_SI_645,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) PCI_DEVICE_ID_SI_646,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) PCI_DEVICE_ID_SI_648,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) PCI_DEVICE_ID_SI_650,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) PCI_DEVICE_ID_SI_651,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) PCI_DEVICE_ID_SI_730,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) PCI_DEVICE_ID_SI_735,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) PCI_DEVICE_ID_SI_745,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) PCI_DEVICE_ID_SI_746,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but that ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) shows up in other chips so we use the 5511
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ID for recognition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) PCI_DEVICE_ID_SI_5597,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) PCI_DEVICE_ID_SI_5598,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 0, /* terminates the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Length of ISA address segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SIS5595_EXTENT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* SIS5595 SMBus registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SMB_STS_LO 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SMB_STS_HI 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SMB_CTL_LO 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define SMB_CTL_HI 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SMB_ADDR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SMB_CMD 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SMB_PCNT 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SMB_CNT 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SMB_BYTE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SMB_DEV 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define SMB_DB0 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SMB_DB1 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define SMB_HAA 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* PCI Address Constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SMB_INDEX 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SMB_DAT 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SIS5595_ENABLE_REG 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ACPI_BASE 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Other settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define MAX_TIMEOUT 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* SIS5595 constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SIS5595_QUICK 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define SIS5595_BYTE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define SIS5595_BYTE_DATA 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define SIS5595_WORD_DATA 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SIS5595_PROC_CALL 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define SIS5595_BLOCK_DATA 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* insmod parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* If force_addr is set to anything different from 0, we forcibly enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) the device at the given address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static u16 force_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) module_param_hw(force_addr, ushort, ioport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static struct pci_driver sis5595_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static unsigned short sis5595_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static struct pci_dev *sis5595_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static u8 sis5595_read(u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) outb(reg, sis5595_base + SMB_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return inb(sis5595_base + SMB_DAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void sis5595_write(u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) outb(reg, sis5595_base + SMB_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) outb(data, sis5595_base + SMB_DAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int sis5595_setup(struct pci_dev *SIS5595_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u16 a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int *i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Look for imposters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for (i = blacklist; *i != 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct pci_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) pci_dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Determine the address of the SMBus areas */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (sis5595_base == 0 && force_addr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (force_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* NB: We grab just the two SMBus registers here, but this may still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * interfere with ACPI :-( */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) retval = acpi_check_region(sis5595_base + SMB_INDEX, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) sis5595_driver.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!request_region(sis5595_base + SMB_INDEX, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) sis5595_driver.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (force_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) != PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) != PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* doesn't work for some chips! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) != PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if ((val & 0x80) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) != PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) != PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if ((val & 0x80) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* doesn't work for some chips? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Everything is happy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) release_region(sis5595_base + SMB_INDEX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -ENODEV;
^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 int sis5595_transaction(struct i2c_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Make sure the SMBus host is ready to start transmitting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (temp != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sis5595_write(SMB_STS_LO, temp & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sis5595_write(SMB_STS_HI, temp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_dbg(&adap->dev, "Successful!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* start the transaction by setting bit 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* We will always wait for a fraction of a second! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) temp = sis5595_read(SMB_STS_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) } while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* If the SMBus is still busy, we give up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (timeout > MAX_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) dev_dbg(&adap->dev, "SMBus Timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) result = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (temp & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) result = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (temp & 0x20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) "next hard reset (or not...)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Clock stops and slave is stuck in mid-transmission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (temp != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sis5595_write(SMB_STS_LO, temp & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) sis5595_write(SMB_STS_HI, temp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (temp != 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* Return negative errno on error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned short flags, char read_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u8 command, int size, union i2c_smbus_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case I2C_SMBUS_QUICK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) size = SIS5595_QUICK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case I2C_SMBUS_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (read_write == I2C_SMBUS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sis5595_write(SMB_CMD, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) size = SIS5595_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case I2C_SMBUS_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) sis5595_write(SMB_CMD, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (read_write == I2C_SMBUS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sis5595_write(SMB_BYTE, data->byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) size = SIS5595_BYTE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case I2C_SMBUS_PROC_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case I2C_SMBUS_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) sis5595_write(SMB_CMD, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (read_write == I2C_SMBUS_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) sis5595_write(SMB_BYTE, data->word & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sis5595_write(SMB_BYTE + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) (data->word & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) status = sis5595_transaction(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if ((size != SIS5595_PROC_CALL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case SIS5595_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case SIS5595_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) data->byte = sis5595_read(SMB_BYTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case SIS5595_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case SIS5595_PROC_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) data->word = sis5595_read(SMB_BYTE) + (sis5595_read(SMB_BYTE + 1) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static u32 sis5595_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) I2C_FUNC_SMBUS_PROC_CALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static const struct i2c_algorithm smbus_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .smbus_xfer = sis5595_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .functionality = sis5595_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static struct i2c_adapter sis5595_adapter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .algo = &smbus_algorithm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static const struct pci_device_id sis5595_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) MODULE_DEVICE_TABLE (pci, sis5595_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static int sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (sis5595_setup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* set up the sysfs linkage to our parent device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) sis5595_adapter.dev.parent = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) snprintf(sis5595_adapter.name, sizeof(sis5595_adapter.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) "SMBus SIS5595 adapter at %04x", sis5595_base + SMB_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) err = i2c_add_adapter(&sis5595_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) release_region(sis5595_base + SMB_INDEX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Always return failure here. This is to allow other drivers to bind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * to this pci device. We don't really want to have control over the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * pci device, we only wanted to read as few register values from it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) sis5595_pdev = pci_dev_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static struct pci_driver sis5595_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .name = "sis5595_smbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .id_table = sis5595_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .probe = sis5595_probe,
^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) static int __init i2c_sis5595_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return pci_register_driver(&sis5595_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void __exit i2c_sis5595_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) pci_unregister_driver(&sis5595_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (sis5595_pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) i2c_del_adapter(&sis5595_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) release_region(sis5595_base + SMB_INDEX, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pci_dev_put(sis5595_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) sis5595_pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) MODULE_DESCRIPTION("SIS5595 SMBus driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) module_init(i2c_sis5595_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) module_exit(i2c_sis5595_exit);