0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/pci.h>
0010 #include <linux/kernel.h>
0011 #include <linux/stddef.h>
0012 #include <linux/sched.h>
0013 #include <linux/i2c.h>
0014 #include <linux/delay.h>
0015 #include <linux/slab.h>
0016 #include <linux/io.h>
0017
0018 #include "i2c-pasemi-core.h"
0019
0020 #define CLK_100K_DIV 84
0021 #define CLK_400K_DIV 21
0022
0023 static struct pci_driver pasemi_smb_pci_driver;
0024
0025 static int pasemi_smb_pci_probe(struct pci_dev *dev,
0026 const struct pci_device_id *id)
0027 {
0028 struct pasemi_smbus *smbus;
0029 unsigned long base;
0030 int size;
0031 int error;
0032
0033 if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
0034 return -ENODEV;
0035
0036 smbus = devm_kzalloc(&dev->dev, sizeof(*smbus), GFP_KERNEL);
0037 if (!smbus)
0038 return -ENOMEM;
0039
0040 smbus->dev = &dev->dev;
0041 base = pci_resource_start(dev, 0);
0042 size = pci_resource_len(dev, 0);
0043 smbus->clk_div = CLK_100K_DIV;
0044
0045
0046
0047
0048
0049 smbus->hw_rev = PASEMI_HW_REV_PCI;
0050
0051 if (!devm_request_region(&dev->dev, base, size,
0052 pasemi_smb_pci_driver.name))
0053 return -EBUSY;
0054
0055 smbus->ioaddr = pcim_iomap(dev, 0, 0);
0056 if (!smbus->ioaddr)
0057 return -EBUSY;
0058
0059 smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
0060 error = pasemi_i2c_common_probe(smbus);
0061 if (error)
0062 return error;
0063
0064 pci_set_drvdata(dev, smbus);
0065
0066 return 0;
0067 }
0068
0069 static const struct pci_device_id pasemi_smb_pci_ids[] = {
0070 { PCI_DEVICE(0x1959, 0xa003) },
0071 { 0, }
0072 };
0073
0074 MODULE_DEVICE_TABLE(pci, pasemi_smb_pci_ids);
0075
0076 static struct pci_driver pasemi_smb_pci_driver = {
0077 .name = "i2c-pasemi",
0078 .id_table = pasemi_smb_pci_ids,
0079 .probe = pasemi_smb_pci_probe,
0080 };
0081
0082 module_pci_driver(pasemi_smb_pci_driver);
0083
0084 MODULE_LICENSE("GPL");
0085 MODULE_AUTHOR("Olof Johansson <olof@lixom.net>");
0086 MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");