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) 2000  Frodo Looijaard <frodol@dds.nl>,
^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)  *                      Mark D. Studebaker <mdsxyz123@yahoo.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *                      Dan Eaton <dan.eaton@rocketlogix.com> and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *                      Stephen Rousset <stephen.rousset@rocketlogix.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) */
^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)     This is the driver for the SMB Host controller on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)     Acer Labs Inc. (ALI) M1535 South Bridge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)     The M1535 is a South bridge for portable systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)     It is very similar to the M15x3 South bridges also produced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)     by Acer Labs Inc.  Some of the registers within the part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)     have moved and some have been redefined slightly. Additionally,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)     the sequencing of the SMBus transactions has been modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)     to be more consistent with the sequencing recommended by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)     the manufacturer and observed through testing.  These
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)     changes are reflected in this driver and can be identified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)     by comparing this driver to the i2c-ali15x3 driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)     For an overview of these chips see http://www.acerlabs.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)     The SMB controller is part of the 7101 device, which is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)     ACPI-compliant Power Management Unit (PMU).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)     The whole 7101 device has to be enabled for the SMB to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)     You can't just enable the SMB alone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)     The SMB and the ACPI have separate I/O spaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)     We make sure that the SMB is enabled. We leave the ACPI alone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)     This driver controls the SMB Host only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)     This driver does not use interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) */
^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) /* Note: we assume there can only be one ALI1535, with one SMBus interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include <linux/io.h>
^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) /* ALI1535 SMBus address offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define SMBHSTSTS	(0 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define SMBHSTTYP	(1 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define SMBHSTPORT	(2 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define SMBHSTCMD	(7 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define SMBHSTADD	(3 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define SMBHSTDAT0	(4 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define SMBHSTDAT1	(5 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define SMBBLKDAT	(6 + ali1535_smba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) /* PCI Address Constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define SMBCOM		0x004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define SMBREV		0x008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define SMBCFG		0x0D1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define SMBBA		0x0E2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define SMBHSTCFG	0x0F0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define SMBCLK		0x0F2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /* Other settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define MAX_TIMEOUT		500	/* times 1/100 sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define ALI1535_SMB_IOSIZE	32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define ALI1535_SMB_DEFAULTBASE	0x8040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) /* ALI1535 address lock bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define ALI1535_LOCK		0x06	/* dwe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /* ALI1535 command constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define ALI1535_QUICK		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define ALI1535_BYTE		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define ALI1535_BYTE_DATA	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define ALI1535_WORD_DATA	0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define ALI1535_BLOCK_DATA	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define ALI1535_I2C_READ	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define	ALI1535_DEV10B_EN	0x80	/* Enable 10-bit addressing in	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 					/*  I2C read			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define	ALI1535_T_OUT		0x08	/* Time-out Command (write)	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define	ALI1535_A_HIGH_BIT9	0x08	/* Bit 9 of 10-bit address in	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 					/* Alert-Response-Address	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 					/* (read)			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define	ALI1535_KILL		0x04	/* Kill Command (write)		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define	ALI1535_A_HIGH_BIT8	0x04	/* Bit 8 of 10-bit address in	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 					/*  Alert-Response-Address	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 					/*  (read)			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define	ALI1535_D_HI_MASK	0x03	/* Mask for isolating bits 9-8	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 					/*  of 10-bit address in I2C	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 					/*  Read Command		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* ALI1535 status register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ALI1535_STS_IDLE	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ALI1535_STS_BUSY	0x08	/* host busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ALI1535_STS_DONE	0x10	/* transaction complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define ALI1535_STS_DEV		0x20	/* device error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ALI1535_STS_BUSERR	0x40	/* bus error    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define ALI1535_STS_FAIL	0x80	/* failed bus transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ALI1535_STS_ERR		0xE0	/* all the bad error bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define ALI1535_BLOCK_CLR	0x04	/* reset block data index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* ALI1535 device address register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define	ALI1535_RD_ADDR		0x01	/* Read/Write Bit in Device	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 					/*  Address field		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 					/*  -> Write = 0		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 					/*  -> Read  = 1		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define	ALI1535_SMBIO_EN	0x04	/* SMB I/O Space enable		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static struct pci_driver ali1535_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static unsigned long ali1535_smba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static unsigned short ali1535_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Detect whether a ALI1535 can be found, and initialize it, where necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)    Note the differences between kernels with the old PCI BIOS interface and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)    newer kernels with the real PCI interface. In compat.h some things are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)    defined to make the transition easier. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int ali1535_setup(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	unsigned char temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	/* Check the following things:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		- SMB I/O address is initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		- Device is enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		- We can use the addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	retval = pci_enable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		dev_err(&dev->dev, "ALI1535_smb can't enable device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/* Determine the address of the SMBus area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	pci_read_config_word(dev, SMBBA, &ali1535_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (ali1535_offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		dev_warn(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			"ALI1535_smb region uninitialized - upgrade BIOS?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (pci_resource_flags(dev, 0) & IORESOURCE_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		ali1535_smba = ali1535_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				   ali1535_driver.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			    ali1535_driver.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			ali1535_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	/* check if whole device is enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	pci_read_config_byte(dev, SMBCFG, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if ((temp & ALI1535_SMBIO_EN) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		goto exit_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	/* Is SMB Host controller enabled? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	pci_read_config_byte(dev, SMBHSTCFG, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if ((temp & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		goto exit_free;
^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) 	/* set SMB clock to 74KHz as recommended in data sheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	pci_write_config_byte(dev, SMBCLK, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	  The interrupt routing for SMB is set up in register 0x77 in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	  1533 ISA Bridge device, NOT in the 7101 device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	  Don't bother with finding the 1533 device and reading the register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	if ((....... & 0x0F) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		dev_dbg(&dev->dev, "ALI1535 using Interrupt 9 for SMBus.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	pci_read_config_byte(dev, SMBREV, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) exit_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int ali1535_transaction(struct i2c_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	int timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		"CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* get status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	temp = inb_p(SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	/* Make sure the SMBus host is ready to start transmitting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	/* Check the busy bit first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (temp & ALI1535_STS_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		/* If the host controller is still busy, it may have timed out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		 * in the previous transaction, resulting in a "SMBus Timeout"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		 * printk.  I've tried the following to reset a stuck busy bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		 *   1. Reset the controller with an KILL command. (this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		 *      doesn't seem to clear the controller if an external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		 *      device is hung)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		 *   2. Reset the controller and the other SMBus devices with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		 *      T_OUT command. (this clears the host busy bit if an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		 *      external device is hung, but it comes back upon a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		 *      access to a device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		 *   3. Disable and reenable the controller in SMBHSTCFG. Worst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		 *      case, nothing seems to work except power reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		/* Try resetting entire SMB bus, including other devices - This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		 * may not work either - it clears the BUSY bit but then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		 * BUSY bit may come back on when you try and use the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		 * again.  If that's the case you are stuck.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		dev_info(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			"Resetting entire SMB Bus to clear busy condition (%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		outb_p(ALI1535_T_OUT, SMBHSTTYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		temp = inb_p(SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/* now check the error bits and the busy bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		/* do a clear-on-write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		outb_p(0xFF, SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		temp = inb_p(SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			/* This is probably going to be correctable only by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			 * power reset as one of the bits now appears to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			 * stuck */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			/* This may be a bus or device with electrical problems. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			dev_err(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				"SMBus reset failed! (0x%02x) - controller or "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				"device on bus is probably hung\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		/* check and clear done bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		if (temp & ALI1535_STS_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			outb_p(temp, SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	/* start the transaction by writing anything to the start register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	outb_p(0xFF, SMBHSTPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	/* We will always wait for a fraction of a second! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		temp = inb_p(SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	} while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		 && (timeout++ < MAX_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/* If the SMBus is still busy, we give up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (timeout > MAX_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		result = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		dev_err(&adap->dev, "SMBus Timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	if (temp & ALI1535_STS_FAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	/* Unfortunately the ALI SMB controller maps "no response" and "bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	 * collision" into a single bit. No response is the usual case so don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	 * do a printk.  This means that bus collisions go unreported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (temp & ALI1535_STS_BUSERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		result = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		dev_dbg(&adap->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			"Error: no response or bus collision ADD=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			inb_p(SMBHSTADD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	/* haven't ever seen this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (temp & ALI1535_STS_DEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		dev_err(&adap->dev, "Error: device error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	/* check to see if the "command complete" indication is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (!(temp & ALI1535_STS_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		result = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		dev_err(&adap->dev, "Error: command never completed\n");
^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) 	dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		"CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	/* take consequent actions for error conditions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (!(temp & ALI1535_STS_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		/* issue "kill" to reset host controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		outb_p(ALI1535_KILL, SMBHSTTYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		outb_p(0xFF, SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	} else if (temp & ALI1535_STS_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		/* issue "timeout" to reset all devices on bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		outb_p(ALI1535_T_OUT, SMBHSTTYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		outb_p(0xFF, SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* Return negative errno on error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			  unsigned short flags, char read_write, u8 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			  int size, union i2c_smbus_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	s32 result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	/* make sure SMBus is idle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	temp = inb_p(SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	for (timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	     (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	     timeout++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		temp = inb_p(SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (timeout >= MAX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	/* clear status register (clear-on-write) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	outb_p(0xFF, SMBHSTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	case I2C_SMBUS_QUICK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		size = ALI1535_QUICK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		outb_p(size, SMBHSTTYP);	/* output command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	case I2C_SMBUS_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		size = ALI1535_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		outb_p(size, SMBHSTTYP);	/* output command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		if (read_write == I2C_SMBUS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	case I2C_SMBUS_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		size = ALI1535_BYTE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		outb_p(size, SMBHSTTYP);	/* output command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		if (read_write == I2C_SMBUS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			outb_p(data->byte, SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case I2C_SMBUS_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		size = ALI1535_WORD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		outb_p(size, SMBHSTTYP);	/* output command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		if (read_write == I2C_SMBUS_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			outb_p(data->word & 0xff, SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	case I2C_SMBUS_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		       SMBHSTADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		size = ALI1535_BLOCK_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		outb_p(size, SMBHSTTYP);	/* output command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		outb_p(command, SMBHSTCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		if (read_write == I2C_SMBUS_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			len = data->block[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			if (len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 				len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 				data->block[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			if (len > 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 				len = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				data->block[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			outb_p(len, SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			/* Reset SMBBLKDAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			for (i = 1; i <= len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 				outb_p(data->block[i], SMBBLKDAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		result = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	result = ali1535_transaction(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	case ALI1535_BYTE:	/* Result put in SMBHSTDAT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		data->byte = inb_p(SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	case ALI1535_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		data->byte = inb_p(SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	case ALI1535_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	case ALI1535_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		len = inb_p(SMBHSTDAT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		if (len > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			len = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		data->block[0] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		/* Reset SMBBLKDAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		for (i = 1; i <= data->block[0]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			data->block[i] = inb_p(SMBBLKDAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				len, i, data->block[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^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) static u32 ali1535_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	    I2C_FUNC_SMBUS_BLOCK_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static const struct i2c_algorithm smbus_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	.smbus_xfer	= ali1535_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	.functionality	= ali1535_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static struct i2c_adapter ali1535_adapter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	.class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	.algo		= &smbus_algorithm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static const struct pci_device_id ali1535_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) MODULE_DEVICE_TABLE(pci, ali1535_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (ali1535_setup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		dev_warn(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 			"ALI1535 not detected, module not inserted.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	/* set up the sysfs linkage to our parent device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	ali1535_adapter.dev.parent = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		"SMBus ALI1535 adapter at %04x", ali1535_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	return i2c_add_adapter(&ali1535_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void ali1535_remove(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	i2c_del_adapter(&ali1535_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static struct pci_driver ali1535_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	.name		= "ali1535_smbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	.id_table	= ali1535_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	.probe		= ali1535_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	.remove		= ali1535_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) module_pci_driver(ali1535_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) MODULE_AUTHOR("Dan Eaton <dan.eaton@rocketlogix.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) MODULE_DESCRIPTION("ALI1535 SMBus driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) MODULE_LICENSE("GPL");