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