Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     i2c Support for the Apple `Hydra' Mac I/O
0004 
0005     Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
0006 
0007     Based on i2c Support for Via Technologies 82C586B South Bridge
0008     Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
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  /* CachePD lines */
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);     /* clear SCLK_OE and SDAT_OE */
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);     /* clear SCLK_OE and SDAT_OE */
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");