1 /* 2 * i2c-pca-isa.c driver for PCA9564 on ISA boards 3 * Copyright (C) 2004 Arcom Control Systems 4 * Copyright (C) 2008 Pengutronix 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/ioport.h> 19 #include <linux/module.h> 20 #include <linux/moduleparam.h> 21 #include <linux/delay.h> 22 #include <linux/jiffies.h> 23 #include <linux/init.h> 24 #include <linux/interrupt.h> 25 #include <linux/wait.h> 26 #include <linux/isa.h> 27 #include <linux/i2c.h> 28 #include <linux/i2c-algo-pca.h> 29 #include <linux/io.h> 30 31 #include <asm/irq.h> 32 33 #define DRIVER "i2c-pca-isa" 34 #define IO_SIZE 4 35 36 static unsigned long base; 37 static int irq = -1; 38 39 /* Data sheet recommends 59kHz for 100kHz operation due to variation 40 * in the actual clock rate */ 41 static int clock = 59000; 42 43 static struct i2c_adapter pca_isa_ops; 44 static wait_queue_head_t pca_wait; 45 46 static void pca_isa_writebyte(void *pd, int reg, int val) 47 { 48 #ifdef DEBUG_IO 49 static char *names[] = { "T/O", "DAT", "ADR", "CON" }; 50 printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg], 51 base+reg, val); 52 #endif 53 outb(val, base+reg); 54 } 55 56 static int pca_isa_readbyte(void *pd, int reg) 57 { 58 int res = inb(base+reg); 59 #ifdef DEBUG_IO 60 { 61 static char *names[] = { "STA", "DAT", "ADR", "CON" }; 62 printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res); 63 } 64 #endif 65 return res; 66 } 67 68 static int pca_isa_waitforcompletion(void *pd) 69 { 70 unsigned long timeout; 71 long ret; 72 73 if (irq > -1) { 74 ret = wait_event_timeout(pca_wait, 75 pca_isa_readbyte(pd, I2C_PCA_CON) 76 & I2C_PCA_CON_SI, pca_isa_ops.timeout); 77 } else { 78 /* Do polling */ 79 timeout = jiffies + pca_isa_ops.timeout; 80 do { 81 ret = time_before(jiffies, timeout); 82 if (pca_isa_readbyte(pd, I2C_PCA_CON) 83 & I2C_PCA_CON_SI) 84 break; 85 udelay(100); 86 } while (ret); 87 } 88 89 return ret > 0; 90 } 91 92 static void pca_isa_resetchip(void *pd) 93 { 94 /* apparently only an external reset will do it. not a lot can be done */ 95 printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n"); 96 } 97 98 static irqreturn_t pca_handler(int this_irq, void *dev_id) { 99 wake_up(&pca_wait); 100 return IRQ_HANDLED; 101 } 102 103 static struct i2c_algo_pca_data pca_isa_data = { 104 /* .data intentionally left NULL, not needed with ISA */ 105 .write_byte = pca_isa_writebyte, 106 .read_byte = pca_isa_readbyte, 107 .wait_for_completion = pca_isa_waitforcompletion, 108 .reset_chip = pca_isa_resetchip, 109 }; 110 111 static struct i2c_adapter pca_isa_ops = { 112 .owner = THIS_MODULE, 113 .algo_data = &pca_isa_data, 114 .name = "PCA9564/PCA9665 ISA Adapter", 115 .timeout = HZ, 116 }; 117 118 static int pca_isa_match(struct device *dev, unsigned int id) 119 { 120 int match = base != 0; 121 122 if (match) { 123 if (irq <= -1) 124 dev_warn(dev, "Using polling mode (specify irq)\n"); 125 } else 126 dev_err(dev, "Please specify I/O base\n"); 127 128 return match; 129 } 130 131 static int pca_isa_probe(struct device *dev, unsigned int id) 132 { 133 init_waitqueue_head(&pca_wait); 134 135 dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq); 136 137 #ifdef CONFIG_PPC 138 if (check_legacy_ioport(base)) { 139 dev_err(dev, "I/O address %#08lx is not available\n", base); 140 goto out; 141 } 142 #endif 143 144 if (!request_region(base, IO_SIZE, "i2c-pca-isa")) { 145 dev_err(dev, "I/O address %#08lx is in use\n", base); 146 goto out; 147 } 148 149 if (irq > -1) { 150 if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) { 151 dev_err(dev, "Request irq%d failed\n", irq); 152 goto out_region; 153 } 154 } 155 156 pca_isa_data.i2c_clock = clock; 157 if (i2c_pca_add_bus(&pca_isa_ops) < 0) { 158 dev_err(dev, "Failed to add i2c bus\n"); 159 goto out_irq; 160 } 161 162 return 0; 163 164 out_irq: 165 if (irq > -1) 166 free_irq(irq, &pca_isa_ops); 167 out_region: 168 release_region(base, IO_SIZE); 169 out: 170 return -ENODEV; 171 } 172 173 static int pca_isa_remove(struct device *dev, unsigned int id) 174 { 175 i2c_del_adapter(&pca_isa_ops); 176 177 if (irq > -1) { 178 disable_irq(irq); 179 free_irq(irq, &pca_isa_ops); 180 } 181 release_region(base, IO_SIZE); 182 183 return 0; 184 } 185 186 static struct isa_driver pca_isa_driver = { 187 .match = pca_isa_match, 188 .probe = pca_isa_probe, 189 .remove = pca_isa_remove, 190 .driver = { 191 .owner = THIS_MODULE, 192 .name = DRIVER, 193 } 194 }; 195 196 MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>"); 197 MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver"); 198 MODULE_LICENSE("GPL"); 199 200 module_param(base, ulong, 0); 201 MODULE_PARM_DESC(base, "I/O base address"); 202 module_param(irq, int, 0); 203 MODULE_PARM_DESC(irq, "IRQ"); 204 module_param(clock, int, 0); 205 MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t" 206 "For PCA9564: 330000,288000,217000,146000," 207 "88000,59000,44000,36000\n" 208 "\t\tFor PCA9665:\tStandard: 60300 - 100099\n" 209 "\t\t\t\tFast: 100100 - 400099\n" 210 "\t\t\t\tFast+: 400100 - 10000099\n" 211 "\t\t\t\tTurbo: Up to 1265800"); 212 module_isa_driver(pca_isa_driver, 1); 213