Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);