0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/pci.h>
0015 #include <linux/types.h>
0016 #include <linux/i2c.h>
0017 #include <linux/i2c-algo-bit.h>
0018 #include <linux/io.h>
0019 #include <asm/hydra.h>
0020
0021
0022 #define HYDRA_CPD_PD0 0x00000001
0023 #define HYDRA_CPD_PD1 0x00000002
0024 #define HYDRA_CPD_PD2 0x00000004
0025 #define HYDRA_CPD_PD3 0x00000008
0026
0027 #define HYDRA_SCLK HYDRA_CPD_PD0
0028 #define HYDRA_SDAT HYDRA_CPD_PD1
0029 #define HYDRA_SCLK_OE 0x00000010
0030 #define HYDRA_SDAT_OE 0x00000020
0031
0032 static inline void pdregw(void *data, u32 val)
0033 {
0034 struct Hydra *hydra = (struct Hydra *)data;
0035 writel(val, &hydra->CachePD);
0036 }
0037
0038 static inline u32 pdregr(void *data)
0039 {
0040 struct Hydra *hydra = (struct Hydra *)data;
0041 return readl(&hydra->CachePD);
0042 }
0043
0044 static void hydra_bit_setscl(void *data, int state)
0045 {
0046 u32 val = pdregr(data);
0047 if (state)
0048 val &= ~HYDRA_SCLK_OE;
0049 else {
0050 val &= ~HYDRA_SCLK;
0051 val |= HYDRA_SCLK_OE;
0052 }
0053 pdregw(data, val);
0054 }
0055
0056 static void hydra_bit_setsda(void *data, int state)
0057 {
0058 u32 val = pdregr(data);
0059 if (state)
0060 val &= ~HYDRA_SDAT_OE;
0061 else {
0062 val &= ~HYDRA_SDAT;
0063 val |= HYDRA_SDAT_OE;
0064 }
0065 pdregw(data, val);
0066 }
0067
0068 static int hydra_bit_getscl(void *data)
0069 {
0070 return (pdregr(data) & HYDRA_SCLK) != 0;
0071 }
0072
0073 static int hydra_bit_getsda(void *data)
0074 {
0075 return (pdregr(data) & HYDRA_SDAT) != 0;
0076 }
0077
0078
0079
0080 static struct i2c_algo_bit_data hydra_bit_data = {
0081 .setsda = hydra_bit_setsda,
0082 .setscl = hydra_bit_setscl,
0083 .getsda = hydra_bit_getsda,
0084 .getscl = hydra_bit_getscl,
0085 .udelay = 5,
0086 .timeout = HZ
0087 };
0088
0089 static struct i2c_adapter hydra_adap = {
0090 .owner = THIS_MODULE,
0091 .name = "Hydra i2c",
0092 .algo_data = &hydra_bit_data,
0093 };
0094
0095 static const struct pci_device_id hydra_ids[] = {
0096 { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
0097 { 0, }
0098 };
0099
0100 MODULE_DEVICE_TABLE (pci, hydra_ids);
0101
0102 static int hydra_probe(struct pci_dev *dev,
0103 const struct pci_device_id *id)
0104 {
0105 unsigned long base = pci_resource_start(dev, 0);
0106 int res;
0107
0108 if (!request_mem_region(base+offsetof(struct Hydra, CachePD), 4,
0109 hydra_adap.name))
0110 return -EBUSY;
0111
0112 hydra_bit_data.data = pci_ioremap_bar(dev, 0);
0113 if (hydra_bit_data.data == NULL) {
0114 release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
0115 return -ENODEV;
0116 }
0117
0118 pdregw(hydra_bit_data.data, 0);
0119 hydra_adap.dev.parent = &dev->dev;
0120 res = i2c_bit_add_bus(&hydra_adap);
0121 if (res < 0) {
0122 iounmap(hydra_bit_data.data);
0123 release_mem_region(base+offsetof(struct Hydra, CachePD), 4);
0124 return res;
0125 }
0126 return 0;
0127 }
0128
0129 static void hydra_remove(struct pci_dev *dev)
0130 {
0131 pdregw(hydra_bit_data.data, 0);
0132 i2c_del_adapter(&hydra_adap);
0133 iounmap(hydra_bit_data.data);
0134 release_mem_region(pci_resource_start(dev, 0)+
0135 offsetof(struct Hydra, CachePD), 4);
0136 }
0137
0138
0139 static struct pci_driver hydra_driver = {
0140 .name = "hydra_smbus",
0141 .id_table = hydra_ids,
0142 .probe = hydra_probe,
0143 .remove = hydra_remove,
0144 };
0145
0146 module_pci_driver(hydra_driver);
0147
0148 MODULE_AUTHOR("Geert Uytterhoeven <geert@linux-m68k.org>");
0149 MODULE_DESCRIPTION("i2c for Apple Hydra Mac I/O");
0150 MODULE_LICENSE("GPL");