Loading drivers/i2c/algos/i2c-algo-pca.c +166 −14 Original line number Diff line number Diff line Loading @@ -46,6 +46,14 @@ static int i2c_debug; #define pca_wait(adap) adap->wait_for_completion(adap->data) #define pca_reset(adap) adap->reset_chip(adap->data) static void pca9665_reset(void *pd) { struct i2c_algo_pca_data *adap = pd; pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); pca_outw(adap, I2C_PCA_IND, 0xA5); pca_outw(adap, I2C_PCA_IND, 0x5A); } /* * Generate a start condition on the i2c bus. * Loading Loading @@ -333,27 +341,171 @@ static const struct i2c_algorithm pca_algo = { .functionality = pca_func, }; static unsigned int pca_probe_chip(struct i2c_adapter *adap) { struct i2c_algo_pca_data *pca_data = adap->algo_data; /* The trick here is to check if there is an indirect register * available. If there is one, we will read the value we first * wrote on I2C_PCA_IADR. Otherwise, we will read the last value * we wrote on I2C_PCA_ADR */ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); pca_outw(pca_data, I2C_PCA_IND, 0xAA); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO); pca_outw(pca_data, I2C_PCA_IND, 0x00); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); return I2C_PCA_CHIP_9665; } else { printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); return I2C_PCA_CHIP_9564; } } static int pca_init(struct i2c_adapter *adap) { struct i2c_algo_pca_data *pca_data = adap->algo_data; adap->algo = &pca_algo; if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) { static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36}; int clock; struct i2c_algo_pca_data *pca_data = adap->algo_data; if (pca_data->i2c_clock > 7) { printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n", adap->name); switch (pca_data->i2c_clock) { case 330000: pca_data->i2c_clock = I2C_PCA_CON_330kHz; break; case 288000: pca_data->i2c_clock = I2C_PCA_CON_288kHz; break; case 217000: pca_data->i2c_clock = I2C_PCA_CON_217kHz; break; case 146000: pca_data->i2c_clock = I2C_PCA_CON_146kHz; break; case 88000: pca_data->i2c_clock = I2C_PCA_CON_88kHz; break; case 59000: pca_data->i2c_clock = I2C_PCA_CON_59kHz; break; case 44000: pca_data->i2c_clock = I2C_PCA_CON_44kHz; break; case 36000: pca_data->i2c_clock = I2C_PCA_CON_36kHz; break; default: printk(KERN_WARNING "%s: Invalid I2C clock speed selected." " Using default 59kHz.\n", adap->name); pca_data->i2c_clock = I2C_PCA_CON_59kHz; } adap->algo = &pca_algo; } else { printk(KERN_WARNING "%s: " "Choosing the clock frequency based on " "index is deprecated." " Use the nominal frequency.\n", adap->name); } pca_reset(pca_data); clock = pca_clock(pca_data); printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); } else { int clock; int mode; int tlow, thi; /* Values can be found on PCA9665 datasheet section 7.3.2.6 */ int min_tlow, min_thi; /* These values are the maximum raise and fall values allowed * by the I2C operation mode (Standard, Fast or Fast+) * They are used (added) below to calculate the clock dividers * of PCA9665. Note that they are slightly different of the * real maximum, to allow the change on mode exactly on the * maximum clock rate for each mode */ int raise_fall_time; struct i2c_algo_pca_data *pca_data = adap->algo_data; /* Ignore the reset function from the module, * we can use the parallel bus reset */ pca_data->reset_chip = pca9665_reset; if (pca_data->i2c_clock > 1265800) { printk(KERN_WARNING "%s: I2C clock speed too high." " Using 1265.8kHz.\n", adap->name); pca_data->i2c_clock = 1265800; } if (pca_data->i2c_clock < 60300) { printk(KERN_WARNING "%s: I2C clock speed too low." " Using 60.3kHz.\n", adap->name); pca_data->i2c_clock = 60300; } /* To avoid integer overflow, use clock/100 for calculations */ clock = pca_clock(pca_data) / 100; if (pca_data->i2c_clock > 10000) { mode = I2C_PCA_MODE_TURBO; min_tlow = 14; min_thi = 5; raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ } else if (pca_data->i2c_clock > 4000) { mode = I2C_PCA_MODE_FASTP; min_tlow = 17; min_thi = 9; raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ } else if (pca_data->i2c_clock > 1000) { mode = I2C_PCA_MODE_FAST; min_tlow = 44; min_thi = 20; raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */ } else { mode = I2C_PCA_MODE_STD; min_tlow = 157; min_thi = 134; raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */ } /* The minimum clock that respects the thi/tlow = 134/157 is * 64800 Hz. Below that, we have to fix the tlow to 255 and * calculate the thi factor. */ if (clock < 648) { tlow = 255; thi = 1000000 - clock * raise_fall_time; thi /= (I2C_PCA_OSC_PER * clock) - tlow; } else { tlow = (1000000 - clock * raise_fall_time) * min_tlow; tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow); thi = tlow * min_thi / min_tlow; } pca_reset(pca_data); printk(KERN_INFO "%s: Clock frequency is %dHz\n", adap->name, clock * 100); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE); pca_outw(pca_data, I2C_PCA_IND, mode); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL); pca_outw(pca_data, I2C_PCA_IND, tlow); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH); pca_outw(pca_data, I2C_PCA_IND, thi); pca_set_con(pca_data, I2C_PCA_CON_ENSIO); } udelay(500); /* 500 us for oscilator to stabilise */ return 0; Loading Loading @@ -388,7 +540,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus); MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, " "Wolfram Sang <w.sang@pengutronix.de>"); MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm"); MODULE_LICENSE("GPL"); module_param(i2c_debug, int, 0); drivers/i2c/busses/Kconfig +4 −4 Original line number Diff line number Diff line Loading @@ -617,12 +617,12 @@ config I2C_ELEKTOR will be called i2c-elektor. config I2C_PCA_ISA tristate "PCA9564 on an ISA bus" tristate "PCA9564/PCA9665 on an ISA bus" depends on ISA select I2C_ALGOPCA default n help This driver supports ISA boards using the Philips PCA9564 This driver supports ISA boards using the Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module Loading @@ -634,11 +634,11 @@ config I2C_PCA_ISA time). If unsure, say N. config I2C_PCA_PLATFORM tristate "PCA9564 as platform device" tristate "PCA9564/PCA9665 as platform device" select I2C_ALGOPCA default n help This driver supports a memory mapped Philips PCA9564 This driver supports a memory mapped Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module Loading drivers/i2c/busses/i2c-pca-isa.c +10 −4 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ static int irq = -1; /* Data sheet recommends 59kHz for 100kHz operation due to variation * in the actual clock rate */ static int clock = I2C_PCA_CON_59kHz; static int clock = 59000; static wait_queue_head_t pca_wait; Loading Loading @@ -103,7 +103,7 @@ static struct i2c_algo_pca_data pca_isa_data = { static struct i2c_adapter pca_isa_ops = { .owner = THIS_MODULE, .algo_data = &pca_isa_data, .name = "PCA9564 ISA Adapter", .name = "PCA9564/PCA9665 ISA Adapter", .timeout = 100, }; Loading Loading @@ -196,7 +196,7 @@ static void __exit pca_isa_exit(void) } MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>"); MODULE_DESCRIPTION("ISA base PCA9564 driver"); MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver"); MODULE_LICENSE("GPL"); module_param(base, ulong, 0); Loading @@ -205,7 +205,13 @@ MODULE_PARM_DESC(base, "I/O base address"); module_param(irq, int, 0); MODULE_PARM_DESC(irq, "IRQ"); module_param(clock, int, 0); MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet"); MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t" "For PCA9564: 330000,288000,217000,146000," "88000,59000,44000,36000\n" "\t\tFor PCA9665:\tStandard: 60300 - 100099\n" "\t\t\t\tFast: 100100 - 400099\n" "\t\t\t\tFast+: 400100 - 10000099\n" "\t\t\t\tTurbo: Up to 1265800"); module_init(pca_isa_init); module_exit(pca_isa_exit); drivers/i2c/busses/i2c-pca-platform.c +5 −4 Original line number Diff line number Diff line Loading @@ -172,7 +172,8 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0; i2c->adap.owner = THIS_MODULE; snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx", snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564/PCA9665 at 0x%08lx", (unsigned long) res->start); i2c->adap.algo_data = &i2c->algo_data; i2c->adap.dev.parent = &pdev->dev; Loading Loading @@ -246,7 +247,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) e_alloc: release_mem_region(res->start, res_len(res)); e_print: printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret); printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret); return ret; } Loading Loading @@ -290,7 +291,7 @@ static void __exit i2c_pca_pf_exit(void) } MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); MODULE_DESCRIPTION("I2C-PCA9564 platform driver"); MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver"); MODULE_LICENSE("GPL"); module_init(i2c_pca_pf_init); Loading include/linux/i2c-algo-pca.h +31 −2 Original line number Diff line number Diff line #ifndef _LINUX_I2C_ALGO_PCA_H #define _LINUX_I2C_ALGO_PCA_H /* Clock speeds for the bus */ /* Chips known to the pca algo */ #define I2C_PCA_CHIP_9564 0x00 #define I2C_PCA_CHIP_9665 0x01 /* Internal period for PCA9665 oscilator */ #define I2C_PCA_OSC_PER 3 /* e10-8s */ /* Clock speeds for the bus for PCA9564*/ #define I2C_PCA_CON_330kHz 0x00 #define I2C_PCA_CON_288kHz 0x01 #define I2C_PCA_CON_217kHz 0x02 Loading @@ -18,6 +25,26 @@ #define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */ #define I2C_PCA_CON 0x03 /* CONTROL Read/Write */ /* PCA9665 registers */ #define I2C_PCA_INDPTR 0x00 /* INDIRECT Pointer Write Only */ #define I2C_PCA_IND 0x02 /* INDIRECT Read/Write */ /* PCA9665 indirect registers */ #define I2C_PCA_ICOUNT 0x00 /* Byte Count for buffered mode */ #define I2C_PCA_IADR 0x01 /* OWN ADR */ #define I2C_PCA_ISCLL 0x02 /* SCL LOW period */ #define I2C_PCA_ISCLH 0x03 /* SCL HIGH period */ #define I2C_PCA_ITO 0x04 /* TIMEOUT */ #define I2C_PCA_IPRESET 0x05 /* Parallel bus reset */ #define I2C_PCA_IMODE 0x06 /* I2C Bus mode */ /* PCA9665 I2C bus mode */ #define I2C_PCA_MODE_STD 0x00 /* Standard mode */ #define I2C_PCA_MODE_FAST 0x01 /* Fast mode */ #define I2C_PCA_MODE_FASTP 0x02 /* Fast Plus mode */ #define I2C_PCA_MODE_TURBO 0x03 /* Turbo mode */ #define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */ #define I2C_PCA_CON_ENSIO 0x40 /* Enable */ #define I2C_PCA_CON_STA 0x20 /* Start */ Loading @@ -31,7 +58,9 @@ struct i2c_algo_pca_data { int (*read_byte) (void *data, int reg); int (*wait_for_completion) (void *data); void (*reset_chip) (void *data); /* i2c_clock values are defined in linux/i2c-algo-pca.h */ /* For PCA9564, use one of the predefined frequencies: * 330000, 288000, 217000, 146000, 88000, 59000, 44000, 36000 * For PCA9665, use the frequency you want here. */ unsigned int i2c_clock; }; Loading Loading
drivers/i2c/algos/i2c-algo-pca.c +166 −14 Original line number Diff line number Diff line Loading @@ -46,6 +46,14 @@ static int i2c_debug; #define pca_wait(adap) adap->wait_for_completion(adap->data) #define pca_reset(adap) adap->reset_chip(adap->data) static void pca9665_reset(void *pd) { struct i2c_algo_pca_data *adap = pd; pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); pca_outw(adap, I2C_PCA_IND, 0xA5); pca_outw(adap, I2C_PCA_IND, 0x5A); } /* * Generate a start condition on the i2c bus. * Loading Loading @@ -333,27 +341,171 @@ static const struct i2c_algorithm pca_algo = { .functionality = pca_func, }; static unsigned int pca_probe_chip(struct i2c_adapter *adap) { struct i2c_algo_pca_data *pca_data = adap->algo_data; /* The trick here is to check if there is an indirect register * available. If there is one, we will read the value we first * wrote on I2C_PCA_IADR. Otherwise, we will read the last value * we wrote on I2C_PCA_ADR */ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); pca_outw(pca_data, I2C_PCA_IND, 0xAA); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO); pca_outw(pca_data, I2C_PCA_IND, 0x00); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); return I2C_PCA_CHIP_9665; } else { printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); return I2C_PCA_CHIP_9564; } } static int pca_init(struct i2c_adapter *adap) { struct i2c_algo_pca_data *pca_data = adap->algo_data; adap->algo = &pca_algo; if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) { static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36}; int clock; struct i2c_algo_pca_data *pca_data = adap->algo_data; if (pca_data->i2c_clock > 7) { printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n", adap->name); switch (pca_data->i2c_clock) { case 330000: pca_data->i2c_clock = I2C_PCA_CON_330kHz; break; case 288000: pca_data->i2c_clock = I2C_PCA_CON_288kHz; break; case 217000: pca_data->i2c_clock = I2C_PCA_CON_217kHz; break; case 146000: pca_data->i2c_clock = I2C_PCA_CON_146kHz; break; case 88000: pca_data->i2c_clock = I2C_PCA_CON_88kHz; break; case 59000: pca_data->i2c_clock = I2C_PCA_CON_59kHz; break; case 44000: pca_data->i2c_clock = I2C_PCA_CON_44kHz; break; case 36000: pca_data->i2c_clock = I2C_PCA_CON_36kHz; break; default: printk(KERN_WARNING "%s: Invalid I2C clock speed selected." " Using default 59kHz.\n", adap->name); pca_data->i2c_clock = I2C_PCA_CON_59kHz; } adap->algo = &pca_algo; } else { printk(KERN_WARNING "%s: " "Choosing the clock frequency based on " "index is deprecated." " Use the nominal frequency.\n", adap->name); } pca_reset(pca_data); clock = pca_clock(pca_data); printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); } else { int clock; int mode; int tlow, thi; /* Values can be found on PCA9665 datasheet section 7.3.2.6 */ int min_tlow, min_thi; /* These values are the maximum raise and fall values allowed * by the I2C operation mode (Standard, Fast or Fast+) * They are used (added) below to calculate the clock dividers * of PCA9665. Note that they are slightly different of the * real maximum, to allow the change on mode exactly on the * maximum clock rate for each mode */ int raise_fall_time; struct i2c_algo_pca_data *pca_data = adap->algo_data; /* Ignore the reset function from the module, * we can use the parallel bus reset */ pca_data->reset_chip = pca9665_reset; if (pca_data->i2c_clock > 1265800) { printk(KERN_WARNING "%s: I2C clock speed too high." " Using 1265.8kHz.\n", adap->name); pca_data->i2c_clock = 1265800; } if (pca_data->i2c_clock < 60300) { printk(KERN_WARNING "%s: I2C clock speed too low." " Using 60.3kHz.\n", adap->name); pca_data->i2c_clock = 60300; } /* To avoid integer overflow, use clock/100 for calculations */ clock = pca_clock(pca_data) / 100; if (pca_data->i2c_clock > 10000) { mode = I2C_PCA_MODE_TURBO; min_tlow = 14; min_thi = 5; raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ } else if (pca_data->i2c_clock > 4000) { mode = I2C_PCA_MODE_FASTP; min_tlow = 17; min_thi = 9; raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ } else if (pca_data->i2c_clock > 1000) { mode = I2C_PCA_MODE_FAST; min_tlow = 44; min_thi = 20; raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */ } else { mode = I2C_PCA_MODE_STD; min_tlow = 157; min_thi = 134; raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */ } /* The minimum clock that respects the thi/tlow = 134/157 is * 64800 Hz. Below that, we have to fix the tlow to 255 and * calculate the thi factor. */ if (clock < 648) { tlow = 255; thi = 1000000 - clock * raise_fall_time; thi /= (I2C_PCA_OSC_PER * clock) - tlow; } else { tlow = (1000000 - clock * raise_fall_time) * min_tlow; tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow); thi = tlow * min_thi / min_tlow; } pca_reset(pca_data); printk(KERN_INFO "%s: Clock frequency is %dHz\n", adap->name, clock * 100); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE); pca_outw(pca_data, I2C_PCA_IND, mode); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL); pca_outw(pca_data, I2C_PCA_IND, tlow); pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH); pca_outw(pca_data, I2C_PCA_IND, thi); pca_set_con(pca_data, I2C_PCA_CON_ENSIO); } udelay(500); /* 500 us for oscilator to stabilise */ return 0; Loading Loading @@ -388,7 +540,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus); MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, " "Wolfram Sang <w.sang@pengutronix.de>"); MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm"); MODULE_LICENSE("GPL"); module_param(i2c_debug, int, 0);
drivers/i2c/busses/Kconfig +4 −4 Original line number Diff line number Diff line Loading @@ -617,12 +617,12 @@ config I2C_ELEKTOR will be called i2c-elektor. config I2C_PCA_ISA tristate "PCA9564 on an ISA bus" tristate "PCA9564/PCA9665 on an ISA bus" depends on ISA select I2C_ALGOPCA default n help This driver supports ISA boards using the Philips PCA9564 This driver supports ISA boards using the Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module Loading @@ -634,11 +634,11 @@ config I2C_PCA_ISA time). If unsure, say N. config I2C_PCA_PLATFORM tristate "PCA9564 as platform device" tristate "PCA9564/PCA9665 as platform device" select I2C_ALGOPCA default n help This driver supports a memory mapped Philips PCA9564 This driver supports a memory mapped Philips PCA9564/PCA9665 parallel bus to I2C bus controller. This driver can also be built as a module. If so, the module Loading
drivers/i2c/busses/i2c-pca-isa.c +10 −4 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ static int irq = -1; /* Data sheet recommends 59kHz for 100kHz operation due to variation * in the actual clock rate */ static int clock = I2C_PCA_CON_59kHz; static int clock = 59000; static wait_queue_head_t pca_wait; Loading Loading @@ -103,7 +103,7 @@ static struct i2c_algo_pca_data pca_isa_data = { static struct i2c_adapter pca_isa_ops = { .owner = THIS_MODULE, .algo_data = &pca_isa_data, .name = "PCA9564 ISA Adapter", .name = "PCA9564/PCA9665 ISA Adapter", .timeout = 100, }; Loading Loading @@ -196,7 +196,7 @@ static void __exit pca_isa_exit(void) } MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>"); MODULE_DESCRIPTION("ISA base PCA9564 driver"); MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver"); MODULE_LICENSE("GPL"); module_param(base, ulong, 0); Loading @@ -205,7 +205,13 @@ MODULE_PARM_DESC(base, "I/O base address"); module_param(irq, int, 0); MODULE_PARM_DESC(irq, "IRQ"); module_param(clock, int, 0); MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet"); MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t" "For PCA9564: 330000,288000,217000,146000," "88000,59000,44000,36000\n" "\t\tFor PCA9665:\tStandard: 60300 - 100099\n" "\t\t\t\tFast: 100100 - 400099\n" "\t\t\t\tFast+: 400100 - 10000099\n" "\t\t\t\tTurbo: Up to 1265800"); module_init(pca_isa_init); module_exit(pca_isa_exit);
drivers/i2c/busses/i2c-pca-platform.c +5 −4 Original line number Diff line number Diff line Loading @@ -172,7 +172,8 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0; i2c->adap.owner = THIS_MODULE; snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx", snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564/PCA9665 at 0x%08lx", (unsigned long) res->start); i2c->adap.algo_data = &i2c->algo_data; i2c->adap.dev.parent = &pdev->dev; Loading Loading @@ -246,7 +247,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) e_alloc: release_mem_region(res->start, res_len(res)); e_print: printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret); printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret); return ret; } Loading Loading @@ -290,7 +291,7 @@ static void __exit i2c_pca_pf_exit(void) } MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); MODULE_DESCRIPTION("I2C-PCA9564 platform driver"); MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver"); MODULE_LICENSE("GPL"); module_init(i2c_pca_pf_init); Loading
include/linux/i2c-algo-pca.h +31 −2 Original line number Diff line number Diff line #ifndef _LINUX_I2C_ALGO_PCA_H #define _LINUX_I2C_ALGO_PCA_H /* Clock speeds for the bus */ /* Chips known to the pca algo */ #define I2C_PCA_CHIP_9564 0x00 #define I2C_PCA_CHIP_9665 0x01 /* Internal period for PCA9665 oscilator */ #define I2C_PCA_OSC_PER 3 /* e10-8s */ /* Clock speeds for the bus for PCA9564*/ #define I2C_PCA_CON_330kHz 0x00 #define I2C_PCA_CON_288kHz 0x01 #define I2C_PCA_CON_217kHz 0x02 Loading @@ -18,6 +25,26 @@ #define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */ #define I2C_PCA_CON 0x03 /* CONTROL Read/Write */ /* PCA9665 registers */ #define I2C_PCA_INDPTR 0x00 /* INDIRECT Pointer Write Only */ #define I2C_PCA_IND 0x02 /* INDIRECT Read/Write */ /* PCA9665 indirect registers */ #define I2C_PCA_ICOUNT 0x00 /* Byte Count for buffered mode */ #define I2C_PCA_IADR 0x01 /* OWN ADR */ #define I2C_PCA_ISCLL 0x02 /* SCL LOW period */ #define I2C_PCA_ISCLH 0x03 /* SCL HIGH period */ #define I2C_PCA_ITO 0x04 /* TIMEOUT */ #define I2C_PCA_IPRESET 0x05 /* Parallel bus reset */ #define I2C_PCA_IMODE 0x06 /* I2C Bus mode */ /* PCA9665 I2C bus mode */ #define I2C_PCA_MODE_STD 0x00 /* Standard mode */ #define I2C_PCA_MODE_FAST 0x01 /* Fast mode */ #define I2C_PCA_MODE_FASTP 0x02 /* Fast Plus mode */ #define I2C_PCA_MODE_TURBO 0x03 /* Turbo mode */ #define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */ #define I2C_PCA_CON_ENSIO 0x40 /* Enable */ #define I2C_PCA_CON_STA 0x20 /* Start */ Loading @@ -31,7 +58,9 @@ struct i2c_algo_pca_data { int (*read_byte) (void *data, int reg); int (*wait_for_completion) (void *data); void (*reset_chip) (void *data); /* i2c_clock values are defined in linux/i2c-algo-pca.h */ /* For PCA9564, use one of the predefined frequencies: * 330000, 288000, 217000, 146000, 88000, 59000, 44000, 36000 * For PCA9665, use the frequency you want here. */ unsigned int i2c_clock; }; Loading