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