11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * i2c-pca-isa.c driver for PCA9564 on ISA boards 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 Arcom Control Systems 4c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang * Copyright (C) 2008 Pengutronix 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/moduleparam.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 262378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang#include <linux/jiffies.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/wait.h> 305cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare#include <linux/isa.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c-algo-pca.h> 332178218027e4da0608219fae1d02e5c88f4e560dH Hartley Sweeten#include <linux/io.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang#define DRIVER "i2c-pca-isa" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IO_SIZE 4 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Hermanstatic unsigned long base; 41ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Hermanstatic int irq = -1; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Data sheet recommends 59kHz for 100kHz operation due to variation 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in the actual clock rate */ 45eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costastatic int clock = 59000; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 472378bc09b91b0702fac7823828a614fd8016a29fWolfram Sangstatic struct i2c_adapter pca_isa_ops; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic wait_queue_head_t pca_wait; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 50c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sangstatic void pca_isa_writebyte(void *pd, int reg, int val) 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef DEBUG_IO 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static char *names[] = { "T/O", "DAT", "ADR", "CON" }; 54154d22b04ae1741c5fcfd5d747b813a9a279abffFrank Seidel printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg], 55154d22b04ae1741c5fcfd5d747b813a9a279abffFrank Seidel base+reg, val); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(val, base+reg); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sangstatic int pca_isa_readbyte(void *pd, int reg) 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res = inb(base+reg); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef DEBUG_IO 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 653d4382913f9a86f0d9ff47740feb427415fe7234Wolfram Sang static char *names[] = { "STA", "DAT", "ADR", "CON" }; 66154d22b04ae1741c5fcfd5d747b813a9a279abffFrank Seidel printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 72c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sangstatic int pca_isa_waitforcompletion(void *pd) 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 742378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang unsigned long timeout; 756abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov long ret; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq > -1) { 7822f8b2695eda496026623020811cae34590ee3d7Wolfram Sang ret = wait_event_timeout(pca_wait, 792378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang pca_isa_readbyte(pd, I2C_PCA_CON) 802378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang & I2C_PCA_CON_SI, pca_isa_ops.timeout); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 822378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang /* Do polling */ 832378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang timeout = jiffies + pca_isa_ops.timeout; 846abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov do { 856abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov ret = time_before(jiffies, timeout); 866abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov if (pca_isa_readbyte(pd, I2C_PCA_CON) 876abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov & I2C_PCA_CON_SI) 886abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov break; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(100); 906abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov } while (ret); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 926abb930af064fb1cf4177d32e2c7bfb89eee0fe5Yegor Yefremov 932378bc09b91b0702fac7823828a614fd8016a29fWolfram Sang return ret > 0; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 96c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sangstatic void pca_isa_resetchip(void *pd) 97c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang{ 98c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang /* apparently only an external reset will do it. not a lot can be done */ 99c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n"); 100c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang} 101c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang 1027d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t pca_handler(int this_irq, void *dev_id) { 10322f8b2695eda496026623020811cae34590ee3d7Wolfram Sang wake_up(&pca_wait); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct i2c_algo_pca_data pca_isa_data = { 108c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang /* .data intentionally left NULL, not needed with ISA */ 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write_byte = pca_isa_writebyte, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_byte = pca_isa_readbyte, 111c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang .wait_for_completion = pca_isa_waitforcompletion, 112c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang .reset_chip = pca_isa_resetchip, 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct i2c_adapter pca_isa_ops = { 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .algo_data = &pca_isa_data, 118eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa .name = "PCA9564/PCA9665 ISA Adapter", 1198e99ada8deaa9033600cd2c7d0a9366b0e99ab68Wolfram Sang .timeout = HZ, 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Hermanstatic int __devinit pca_isa_match(struct device *dev, unsigned int id) 123ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman{ 124ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman int match = base != 0; 125ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman 126ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman if (match) { 127ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman if (irq <= -1) 128ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman dev_warn(dev, "Using polling mode (specify irq)\n"); 129ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman } else 130ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman dev_err(dev, "Please specify I/O base\n"); 131ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman 132ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman return match; 133ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman} 134ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman 1355cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvarestatic int __devinit pca_isa_probe(struct device *dev, unsigned int id) 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&pca_wait); 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1395cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14168e1ee62f0f8e556642a59ebaf0c2cc2ac6ccfa6Kumar Gala#ifdef CONFIG_PPC 142104cb574feb3033299568483a3f68031f47e0d43Christian Krafft if (check_legacy_ioport(base)) { 143104cb574feb3033299568483a3f68031f47e0d43Christian Krafft dev_err(dev, "I/O address %#08lx is not available\n", base); 144104cb574feb3033299568483a3f68031f47e0d43Christian Krafft goto out; 145104cb574feb3033299568483a3f68031f47e0d43Christian Krafft } 146104cb574feb3033299568483a3f68031f47e0d43Christian Krafft#endif 147104cb574feb3033299568483a3f68031f47e0d43Christian Krafft 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(base, IO_SIZE, "i2c-pca-isa")) { 1495cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare dev_err(dev, "I/O address %#08lx is in use\n", base); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq > -1) { 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) { 1555cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare dev_err(dev, "Request irq%d failed\n", irq); 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_region; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 160c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang pca_isa_data.i2c_clock = clock; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i2c_pca_add_bus(&pca_isa_ops) < 0) { 1625cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare dev_err(dev, "Failed to add i2c bus\n"); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out_irq; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_irq: 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (irq > -1) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(irq, &pca_isa_ops); 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out_region: 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(base, IO_SIZE); 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds out: 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1775cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvarestatic int __devexit pca_isa_remove(struct device *dev, unsigned int id) 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1793269711b76ba27b78862c48398b0d313ccaa99c2Jean Delvare i2c_del_adapter(&pca_isa_ops); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman if (irq > -1) { 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disable_irq(irq); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(irq, &pca_isa_ops); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(base, IO_SIZE); 1865cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare 1875cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare return 0; 1885cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare} 1895cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare 1905cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvarestatic struct isa_driver pca_isa_driver = { 191ce5640330b10c6cecfbda50569b9f53c081d10c6Rene Herman .match = pca_isa_match, 1925cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare .probe = pca_isa_probe, 1935cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare .remove = __devexit_p(pca_isa_remove), 1945cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare .driver = { 1955cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare .owner = THIS_MODULE, 196c01b0831057381c7f6e0bfb3634bac8c5f7fb256Wolfram Sang .name = DRIVER, 1975cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare } 1985cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare}; 1995cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare 2005cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvarestatic int __init pca_isa_init(void) 2015cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare{ 2025cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare return isa_register_driver(&pca_isa_driver, 1); 2035cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare} 2045cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare 2055cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvarestatic void __exit pca_isa_exit(void) 2065cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare{ 2075cedb05db3c3084c9641403dd24c310a6b3ea19fJean Delvare isa_unregister_driver(&pca_isa_driver); 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>"); 211eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da CostaMODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver"); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(base, ulong, 0); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(base, "I/O base address"); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(irq, int, 0); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(irq, "IRQ"); 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(clock, int, 0); 220eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da CostaMODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t" 221eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa "For PCA9564: 330000,288000,217000,146000," 222eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa "88000,59000,44000,36000\n" 223eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa "\t\tFor PCA9665:\tStandard: 60300 - 100099\n" 224eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa "\t\t\t\tFast: 100100 - 400099\n" 225eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa "\t\t\t\tFast+: 400100 - 10000099\n" 226eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57Marco Aurelio da Costa "\t\t\t\tTurbo: Up to 1265800"); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(pca_isa_init); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(pca_isa_exit); 230