mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-11-07 16:01:34 +00:00
amd8111 support, patch from
+* Vojtech Pavlik <vojtech@suse.cz> git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1616 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
1 parent
d999488cd1
commit
3929e57a5b
11 files changed
+478
-9
No files matched your search
@@ -17,7 +17,7 @@ ask CVS about it:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
2.6.6 (20021???)
|
||||
2.6.6 (200211??)
|
||||
NOTE: Requires i2c-2.6.6 or newer.
|
||||
File doc/busses/i2c-ali1535: Add license, miscellaneous changes
|
||||
File doc/busses/i2c-ali15x3: Add license, miscellaneous changes
|
||||
@@ -37,7 +37,10 @@ ask CVS about it:
|
||||
kernel 2.5.43
|
||||
Module gl518sm: Iterate allowed only for rev 0x00
|
||||
Module i2c-amd756: Configure base address for nForce support;
|
||||
check for uninitialized base address
|
||||
check for uninitialized base address;
|
||||
add support for amd8111 (SMBus 1.0)
|
||||
Module i2c-amd8111: New (SMBus 2.0)
|
||||
Module i2c-ipmb: New
|
||||
Module i2c-ipmi: New
|
||||
Module i2c-sis630: Add support for SiS730
|
||||
Module i2c-sis645: Improve support for SiS645/961;
|
||||
@@ -58,7 +61,8 @@ ask CVS about it:
|
||||
Program sensors: Add support for MC1066, Rambus Rimms;
|
||||
fix w83781d temp3 alarm; fix gl518sm rev 0x00 recognition;
|
||||
initial support for Sony Vaio eeprom
|
||||
Program sensors-detect: Add support for MC1066, smart battery, 8235, IPMI;
|
||||
Program sensors-detect: Add support for MC1066, smart battery, 8235,
|
||||
IPMI, AMD8111;
|
||||
add ACPI method for IBM system detection;
|
||||
work with old Perl versions again;
|
||||
initial support for Sony Vaio eeprom
|
||||
|
||||
@@ -80,4 +80,7 @@ problems.
|
||||
* Jean Delvare <khali@linux-fr.org>
|
||||
Author of the decode-vaio.pl Vaio EEPROM decoder.
|
||||
Perl scripts maintainer, tester, dmidecode maintainer, bug fixer.
|
||||
* Vojtech Pavlik <vojtech@suse.cz>
|
||||
Author of the i2c-amd8111 bus driver.
|
||||
Added support for amd8111 SMBus 1.0 controller to i2c-amd756.
|
||||
|
||||
@@ -40,7 +40,8 @@ See the lm_sensors download page for guidance:
|
||||
|
||||
At least the following I2C/SMBus adapters are supported:
|
||||
Acer Labs M1533, M1535, and M1543C
|
||||
AMD 756, 766, and 768
|
||||
AMD 756, 766, 768 and 8111
|
||||
AMD 8111 SMBus 2.0
|
||||
Apple Hydra (used on some PPC machines)
|
||||
DEC 21272/21274 (Tsunami/Typhoon - on Alpha boards)
|
||||
Intel I801 ICH/ICH0/ICH2/ICH3 (used in Intel 810, 810E, 815E, 820, 840 chipsets)
|
||||
@@ -53,7 +54,7 @@ At least the following I2C/SMBus adapters are supported:
|
||||
SMSC Victory66
|
||||
3Dfx Voodoo 3 and Banshee
|
||||
VIA Technologies VT82C586B, VT82C596A/B, VT82C686A/B, VT8231,
|
||||
VT8233, and VT8233A.
|
||||
VT8233, VT8233A, and VT8235.
|
||||
|
||||
|
||||
At least the following hardware sensor chips are supported:
|
||||
|
||||
@@ -6,6 +6,7 @@ Supported adapters:
|
||||
* AMD 756
|
||||
* AMD 766
|
||||
* AMD 768
|
||||
* AMD 8111
|
||||
Datasheets: Publicly available on AMD website
|
||||
|
||||
* nVidia nForce
|
||||
@@ -21,4 +22,9 @@ Module Parameters
|
||||
Description
|
||||
-----------
|
||||
|
||||
This driver supports the AMD 756, 766, and 768 Peripheral Bus Controllers.
|
||||
This driver supports the AMD 756, 766, 768 and 8111 Peripheral Bus Controllers, and
|
||||
the nVidia nForce.
|
||||
|
||||
Note that for the 8111, there are two SMBus adapters. The SMBus 1.0 adapter is
|
||||
supported by this driver, and the SMBus 2.0 adapter is supported
|
||||
by the i2c-amd8111 driver.
|
||||
@@ -0,0 +1,44 @@
|
||||
Kernel driver `i2c-adm8111.o'
|
||||
|
||||
Status: Untested.
|
||||
|
||||
Supported adapters:
|
||||
* AMD-8111 SMBus 2.0 PCI interface
|
||||
* Possibly any other interface that implements the ACPI 2.0 EC interface
|
||||
Datasheets: Publicly available at AMD and ACPI websites
|
||||
|
||||
Author: Vojtech Pavlik <vojtech@suse.cz>
|
||||
|
||||
|
||||
Module Parameters
|
||||
-----------------
|
||||
|
||||
None.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
If you see something like this:
|
||||
|
||||
00:07.2 SMBus: Advanced Micro Devices [AMD] AMD-8111 SMBus 2.0 (rev 02)
|
||||
Subsystem: Advanced Micro Devices [AMD] AMD-8111 SMBus 2.0
|
||||
Flags: medium devsel, IRQ 19
|
||||
I/O ports at d400 [size=32]
|
||||
|
||||
in your 'lspci -v', then this driver is for your chipset.
|
||||
|
||||
Process Call Support
|
||||
--------------------
|
||||
|
||||
The chip supports it, but it's not implemented in the driver at the moment.
|
||||
|
||||
SMBus 2.0 Support
|
||||
-----------------
|
||||
|
||||
The chip supports SMBus 2.0, however the only extension the driver
|
||||
supports is PEC. Slave mode or host notification are not implemented.
|
||||
|
||||
|
||||
Note that for the 8111, there are two SMBus adapters. The SMBus 2.0 adapter is
|
||||
supported by this driver, and the SMBus 1.0 adapter is supported
|
||||
by the i2c-amd756 driver.
|
||||
@@ -69,7 +69,7 @@ applied to this code.
|
||||
|
||||
Thank Yous
|
||||
-----------
|
||||
Mark D. Studebaker <mds@paradyne.com>
|
||||
Mark D. Studebaker <mdsxyz123@yahoo.com>
|
||||
- design hints and bug fixes
|
||||
Alexander Maylsh <amalysh@web.de>
|
||||
- ditto, plus an important datasheet... almost the one I really wanted
|
||||
|
||||
@@ -26,6 +26,7 @@ KERNELBUSSESDIR := $(MODULE_DIR)
|
||||
# These targets are NOT included in 'mkpatch' ...
|
||||
KERNELBUSSESTARGETS :=
|
||||
ifeq ($(shell if grep -q '^CONFIG_IPMI_HANDLER=' $(LINUX)/.config; then echo 1; fi),1)
|
||||
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-ipmb.o
|
||||
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-ipmi.o
|
||||
endif
|
||||
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-sis630.o
|
||||
@@ -41,6 +42,9 @@ endif
|
||||
ifneq ($(shell if grep -q '^CONFIG_I2C_AMD756=y' $(LINUX)/.config; then echo 1; fi),1)
|
||||
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-amd756.o
|
||||
endif
|
||||
ifneq ($(shell if grep -q '^CONFIG_I2C_AMD8111=y' $(LINUX)/.config; then echo 1; fi),1)
|
||||
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-amd8111.o
|
||||
endif
|
||||
ifneq ($(shell if grep -q '^CONFIG_I2C_HYDRA=y' $(LINUX)/.config; then echo 1; fi),1)
|
||||
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-hydra.o
|
||||
endif
|
||||
|
||||
@@ -52,6 +52,12 @@
|
||||
#ifndef PCI_DEVICE_ID_AMD_766
|
||||
#define PCI_DEVICE_ID_AMD_766 0x7413
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_AMD_768_SMBUS
|
||||
#define PCI_DEVICE_ID_AMD_768_SMBUS 0x7443
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_AMD_8111_SMBUS
|
||||
#define PCI_DEVICE_ID_AMD_8111_SMBUS 0x746B
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS
|
||||
#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01B4
|
||||
#endif
|
||||
@@ -67,8 +73,9 @@ struct sd {
|
||||
static struct sd supported[] = {
|
||||
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_756, 3, "AMD756", 1},
|
||||
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_766, 3, "AMD766", 1},
|
||||
{PCI_VENDOR_ID_AMD, 0x7443, 3, "AMD768", 1},
|
||||
{PCI_VENDOR_ID_NVIDIA, 0x01B4, 1, "nVidia nForce", 0},
|
||||
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_768_SMBUS, 3, "AMD768", 1},
|
||||
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS, 3, "AMD8111", 1},
|
||||
{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS, 1, "nVidia nForce", 0},
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* SMBus 2.0 driver for AMD-8111 IO-Hub.
|
||||
*
|
||||
* Copyright (c) 2002 Vojtech Pavlik
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation version 2.
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include "version.h"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR ("Vojtech Pavlik <vojtech@suse.cz>");
|
||||
MODULE_DESCRIPTION("AMD8111 SMBus 2.0 driver");
|
||||
|
||||
struct amd_smbus {
|
||||
struct pci_dev *dev;
|
||||
struct i2c_adapter adapter;
|
||||
int base;
|
||||
int size;
|
||||
};
|
||||
|
||||
/*
|
||||
* AMD PCI control registers definitions.
|
||||
*/
|
||||
|
||||
#define AMD_PCI_MISC 0x48
|
||||
|
||||
#define AMD_PCI_MISC_SCI 0x04 /* deliver SCI */
|
||||
#define AMD_PCI_MISC_INT 0x02 /* deliver PCI IRQ */
|
||||
#define AMD_PCI_MISC_SPEEDUP 0x01 /* 16x clock speedup */
|
||||
|
||||
/*
|
||||
* ACPI 2.0 chapter 13 PCI interface definitions.
|
||||
*/
|
||||
|
||||
#define AMD_EC_DATA 0x00 /* data register */
|
||||
#define AMD_EC_SC 0x04 /* status of controller */
|
||||
#define AMD_EC_CMD 0x04 /* command register */
|
||||
#define AMD_EC_ICR 0x08 /* interrupt control register */
|
||||
|
||||
#define AMD_EC_SC_SMI 0x04 /* smi event pending */
|
||||
#define AMD_EC_SC_SCI 0x02 /* sci event pending */
|
||||
#define AMD_EC_SC_BURST 0x01 /* burst mode enabled */
|
||||
#define AMD_EC_SC_CMD 0x08 /* byte in data reg is command */
|
||||
#define AMD_EC_SC_IBF 0x02 /* data ready for embedded controller */
|
||||
#define AMD_EC_SC_OBF 0x01 /* data ready for host */
|
||||
|
||||
#define AMD_EC_CMD_RD 0x80 /* read EC */
|
||||
#define AMD_EC_CMD_WR 0x81 /* write EC */
|
||||
#define AMD_EC_CMD_BE 0x82 /* enable burst mode */
|
||||
#define AMD_EC_CMD_BD 0x83 /* disable burst mode */
|
||||
#define AMD_EC_CMD_QR 0x84 /* query EC */
|
||||
|
||||
/*
|
||||
* ACPI 2.0 chapter 13 access of registers of the EC
|
||||
*/
|
||||
|
||||
unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
|
||||
{
|
||||
int timeout = 500;
|
||||
|
||||
while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF))
|
||||
udelay(1);
|
||||
|
||||
if (!timeout) {
|
||||
printk(KERN_WARNING "i2c-amd811.c: Timeout while waiting for IBF to clear\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
|
||||
{
|
||||
int timeout = 500;
|
||||
|
||||
while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF))
|
||||
udelay(1);
|
||||
|
||||
if (!timeout) {
|
||||
printk(KERN_WARNING "i2c-amd8111.c: Timeout while waiting for OBF to set\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, unsigned char *data)
|
||||
{
|
||||
if (amd_ec_wait_write(smbus))
|
||||
return -1;
|
||||
outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
|
||||
|
||||
if (amd_ec_wait_write(smbus))
|
||||
return -1;
|
||||
outb(address, smbus->base + AMD_EC_DATA);
|
||||
|
||||
if (amd_ec_wait_read(smbus))
|
||||
return -1;
|
||||
*data = inb(smbus->base + AMD_EC_DATA);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, unsigned char data)
|
||||
{
|
||||
if (amd_ec_wait_write(smbus))
|
||||
return -1;
|
||||
outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
|
||||
|
||||
if (amd_ec_wait_write(smbus))
|
||||
return -1;
|
||||
outb(address, smbus->base + AMD_EC_DATA);
|
||||
|
||||
if (amd_ec_wait_write(smbus))
|
||||
return -1;
|
||||
outb(data, smbus->base + AMD_EC_DATA);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 2.0 chapter 13 SMBus 2.0 EC register model
|
||||
*/
|
||||
|
||||
#define AMD_SMB_PRTCL 0x00 /* protocol, PEC */
|
||||
#define AMD_SMB_STS 0x01 /* status */
|
||||
#define AMD_SMB_ADDR 0x02 /* address */
|
||||
#define AMD_SMB_CMD 0x03 /* command */
|
||||
#define AMD_SMB_DATA 0x04 /* 32 data registers */
|
||||
#define AMD_SMB_BCNT 0x24 /* number of data bytes */
|
||||
#define AMD_SMB_ALRM_A 0x25 /* alarm address */
|
||||
#define AMD_SMB_ALRM_D 0x26 /* 2 bytes alarm data */
|
||||
|
||||
#define AMD_SMB_STS_DONE 0x80
|
||||
#define AMD_SMB_STS_ALRM 0x40
|
||||
#define AMD_SMB_STS_RES 0x20
|
||||
#define AMD_SMB_STS_STATUS 0x1f
|
||||
|
||||
#define AMD_SMB_STATUS_OK 0x00
|
||||
#define AMD_SMB_STATUS_FAIL 0x07
|
||||
#define AMD_SMB_STATUS_DNAK 0x10
|
||||
#define AMD_SMB_STATUS_DERR 0x11
|
||||
#define AMD_SMB_STATUS_CMD_DENY 0x12
|
||||
#define AMD_SMB_STATUS_UNKNOWN 0x13
|
||||
#define AMD_SMB_STATUS_ACC_DENY 0x17
|
||||
#define AMD_SMB_STATUS_TIMEOUT 0x18
|
||||
#define AMD_SMB_STATUS_NOTSUP 0x19
|
||||
#define AMD_SMB_STATUS_BUSY 0x1A
|
||||
#define AMD_SMB_STATUS_PEC 0x1F
|
||||
|
||||
#define AMD_SMB_PRTCL_QUICK 0x02
|
||||
#define AMD_SMB_PRTCL_BYTE 0x04
|
||||
#define AMD_SMB_PRTCL_BYTE_DATA 0x06
|
||||
#define AMD_SMB_PRTCL_WORD_DATA 0x08
|
||||
#define AMD_SMB_PRTCL_BLOCK_DATA 0x0a
|
||||
#define AMD_SMB_PRTCL_PROC_CALL 0x0c
|
||||
#define AMD_SMB_PRTCL_BLOCK_PROC_CALL 0x0d
|
||||
#define AMD_SMB_PRTCL_I2C_BLOCK_DATA 0x4a
|
||||
#define AMD_SMB_PRTCL_PEC 0x80
|
||||
|
||||
|
||||
s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
|
||||
char read_write, u8 command, int size, union i2c_smbus_data * data)
|
||||
{
|
||||
struct amd_smbus *smbus = adap->algo_data;
|
||||
unsigned char protocol = read_write; /* 1 = read, 0 = write */
|
||||
unsigned char temp[2];
|
||||
int i, timeout = 5000;
|
||||
|
||||
switch (size) {
|
||||
|
||||
case I2C_SMBUS_QUICK:
|
||||
protocol |= AMD_SMB_PRTCL_QUICK;
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_BYTE:
|
||||
if (!read_write)
|
||||
amd_ec_write(smbus, AMD_SMB_DATA, data->byte);
|
||||
protocol |= AMD_SMB_PRTCL_BYTE;
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_BYTE_DATA:
|
||||
amd_ec_write(smbus, AMD_SMB_CMD, command);
|
||||
if (!read_write)
|
||||
amd_ec_write(smbus, AMD_SMB_DATA, data->byte);
|
||||
protocol |= AMD_SMB_PRTCL_BYTE_DATA;
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_WORD_DATA:
|
||||
amd_ec_write(smbus, AMD_SMB_CMD, command);
|
||||
if (!read_write) {
|
||||
amd_ec_write(smbus, AMD_SMB_DATA, data->byte);
|
||||
amd_ec_write(smbus, AMD_SMB_DATA + 1, data->byte >> 8);
|
||||
}
|
||||
protocol |= AMD_SMB_PRTCL_WORD_DATA;
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
case I2C_SMBUS_BLOCK_DATA_PEC:
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
amd_ec_write(smbus, AMD_SMB_CMD, command);
|
||||
if (!read_write)
|
||||
for (i = 0; i < data->block[0]; i++)
|
||||
amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
|
||||
switch (size) {
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
protocol |= AMD_SMB_PRTCL_BLOCK_DATA;
|
||||
break;
|
||||
case I2C_SMBUS_BLOCK_DATA_PEC:
|
||||
protocol |= AMD_SMB_PRTCL_BLOCK_DATA | AMD_SMB_PRTCL_PEC;
|
||||
break;
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_PROC_CALL: /* We don't support proc_call yet */
|
||||
default:
|
||||
printk(KERN_WARNING "i2c-amd8111.c: Unsupported transaction %d\n", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
|
||||
amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
|
||||
|
||||
amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
|
||||
|
||||
while (timeout && ~temp[0] & AMD_SMB_STS_DONE) {
|
||||
amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
|
||||
udelay(10);
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (!timeout)
|
||||
return -1;
|
||||
|
||||
if (~temp[0] & AMD_SMB_STS_DONE) {
|
||||
printk(KERN_WARNING "i2c-amd8111.c: Transaction completed with error %#x\n", temp[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!read_write) /* We're done, no values to return; */
|
||||
return 0;
|
||||
|
||||
switch (size) {
|
||||
|
||||
case I2C_SMBUS_BYTE:
|
||||
case I2C_SMBUS_BYTE_DATA:
|
||||
amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_WORD_DATA:
|
||||
amd_ec_read(smbus, AMD_SMB_DATA, temp + 0);
|
||||
amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1);
|
||||
data->word = (temp[1] << 8) | temp[0];
|
||||
break;
|
||||
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
case I2C_SMBUS_BLOCK_DATA_PEC:
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
for (i = 0; i < data->block[0]; i++)
|
||||
amd_ec_read(smbus, AMD_SMB_DATA + i, data->block + i + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void amd8111_inc(struct i2c_adapter *adapter)
|
||||
{
|
||||
MOD_INC_USE_COUNT;
|
||||
}
|
||||
|
||||
void amd8111_dec(struct i2c_adapter *adapter)
|
||||
{
|
||||
MOD_DEC_USE_COUNT;
|
||||
}
|
||||
|
||||
u32 amd8111_func(struct i2c_adapter *adapter)
|
||||
{
|
||||
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
|
||||
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
|
||||
I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
|
||||
I2C_FUNC_SMBUS_BLOCK_DATA_PEC | I2C_FUNC_SMBUS_HWPEC_CALC;
|
||||
}
|
||||
|
||||
static struct i2c_algorithm smbus_algorithm = {
|
||||
.name = "Non-I2C SMBus 2.0 adapter",
|
||||
.id = I2C_ALGO_SMBUS,
|
||||
.smbus_xfer = amd8111_access,
|
||||
.functionality = amd8111_func,
|
||||
};
|
||||
|
||||
static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
struct amd_smbus *smbus;
|
||||
|
||||
if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
|
||||
return -1;
|
||||
|
||||
if (!(smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL)))
|
||||
return -1;
|
||||
memset(smbus, 0, sizeof(struct amd_smbus));
|
||||
|
||||
pci_set_drvdata(dev, smbus);
|
||||
smbus->dev = dev;
|
||||
smbus->base = pci_resource_start(dev, 0);
|
||||
smbus->size = pci_resource_len(dev, 0);
|
||||
|
||||
if (!request_region(smbus->base, smbus->size, "amd81111 SMBus 2.0")) {
|
||||
kfree(smbus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(smbus->adapter.name, "SMBus2 AMD8111 adapter at %04x", smbus->base);
|
||||
smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
|
||||
smbus->adapter.algo = &smbus_algorithm;
|
||||
smbus->adapter.algo_data = smbus;
|
||||
smbus->adapter.inc_use = amd8111_inc;
|
||||
smbus->adapter.dec_use = amd8111_dec;
|
||||
|
||||
pci_write_config_dword(dev, AMD_PCI_MISC, 0);
|
||||
|
||||
if (i2c_add_adapter(&smbus->adapter)) {
|
||||
printk(KERN_WARNING "i2c-amd8111.c: Failed to register adapter.\n");
|
||||
release_region(smbus->base, smbus->size);
|
||||
kfree(smbus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "i2c-amd8111.c: AMD8111 SMBus 2.0 adapter at pci%s\n", dev->slot_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __devexit amd8111_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct amd_smbus *smbus = pci_get_drvdata(dev);
|
||||
if (i2c_del_adapter(&smbus->adapter)) {
|
||||
printk(KERN_WARNING "i2c-amd81111.c: Failed to unregister adapter.\n");
|
||||
return;
|
||||
}
|
||||
release_region(smbus->base, smbus->size);
|
||||
kfree(smbus);
|
||||
}
|
||||
|
||||
static struct pci_device_id amd8111_id_table[] __devinitdata =
|
||||
{{ 0x1022, 0x746a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
{ 0 }};
|
||||
|
||||
static struct pci_driver amd8111_driver = {
|
||||
.name = "amd8111 smbus 2.0",
|
||||
.id_table = amd8111_id_table,
|
||||
.probe = amd8111_probe,
|
||||
.remove = amd8111_remove,
|
||||
};
|
||||
|
||||
int __init amd8111_init(void)
|
||||
{
|
||||
return pci_module_init(&amd8111_driver);
|
||||
}
|
||||
|
||||
void __exit amd8111_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&amd8111_driver);
|
||||
}
|
||||
|
||||
module_init(amd8111_init);
|
||||
module_exit(amd8111_exit);
|
||||
@@ -3,6 +3,7 @@ kernel/busses/dmi_scan.h include/linux/dmi_scan.h
|
||||
kernel/busses/i2c-ali1535.c drivers/i2c/i2c-ali1535.c
|
||||
kernel/busses/i2c-ali15x3.c drivers/i2c/i2c-ali15x3.c
|
||||
kernel/busses/i2c-amd756.c drivers/i2c/i2c-amd756.c
|
||||
kernel/busses/i2c-amd8111.c drivers/i2c/i2c-amd8111.c
|
||||
kernel/busses/i2c-hydra.c drivers/i2c/i2c-hydra.c
|
||||
kernel/busses/i2c-i801.c drivers/i2c/i2c-i801.c
|
||||
kernel/busses/i2c-i810.c drivers/i2c/i2c-i810.c
|
||||
|
||||
@@ -303,6 +303,22 @@ use vars qw(@pci_adapters @chip_ids @undetectable_adapters @dmidecode);
|
||||
driver => "i2c-amd756",
|
||||
match => sub { $_[0] =~ /^SMBus AMD768 adapter at [0-9,a-f]{4}/ },
|
||||
},
|
||||
{
|
||||
vendid => 0x1022,
|
||||
devid => 0x746b,
|
||||
func => 3,
|
||||
procid => "AMD-8111 ACPI",
|
||||
driver => "i2c-amd756",
|
||||
match => sub { $_[0] =~ /^SMBus AMD8111 adapter at [0-9,a-f]{4}/ },
|
||||
},
|
||||
{
|
||||
vendid => 0x1022,
|
||||
devid => 0x746a,
|
||||
func => 2,
|
||||
procid => "AMD-8111 SMBus 2.0",
|
||||
driver => "i2c-amd8111",
|
||||
match => sub { $_[0] =~ /^SMBus2 AMD8111 adapter at [0-9,a-f]{4}/ },
|
||||
},
|
||||
{
|
||||
vendid => 0x102b,
|
||||
devid => 0x0519,
|
||||
|
||||
Reference in new issue
Block a user