Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Embedded Planet RPX Lite MPC8xx CPM I2C interface. |
| 3 | * Copyright (c) 1999 Dan Malek (dmalek@jlc.net). |
| 4 | * |
| 5 | * moved into proper i2c interface; |
| 6 | * Brad Parker (brad@heeltoe.com) |
| 7 | * |
| 8 | * RPX lite specific parts of the i2c interface |
| 9 | * Update: There actually isn't anything RPXLite-specific about this module. |
| 10 | * This should work for most any 8xx board. The console messages have been |
| 11 | * changed to eliminate RPXLite references. |
| 12 | */ |
| 13 | |
| 14 | #include <linux/config.h> |
| 15 | #include <linux/kernel.h> |
| 16 | #include <linux/module.h> |
| 17 | #include <linux/init.h> |
| 18 | #include <linux/stddef.h> |
| 19 | #include <linux/i2c.h> |
| 20 | #include <linux/i2c-algo-8xx.h> |
| 21 | #include <asm/mpc8xx.h> |
| 22 | #include <asm/commproc.h> |
| 23 | |
| 24 | |
| 25 | static void |
| 26 | rpx_iic_init(struct i2c_algo_8xx_data *data) |
| 27 | { |
| 28 | volatile cpm8xx_t *cp; |
| 29 | volatile immap_t *immap; |
| 30 | |
| 31 | cp = cpmp; /* Get pointer to Communication Processor */ |
| 32 | immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ |
| 33 | |
| 34 | data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; |
| 35 | |
| 36 | /* Check for and use a microcode relocation patch. |
| 37 | */ |
| 38 | if ((data->reloc = data->iip->iic_rpbase)) |
| 39 | data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase]; |
| 40 | |
| 41 | data->i2c = (i2c8xx_t *)&(immap->im_i2c); |
| 42 | data->cp = cp; |
| 43 | |
| 44 | /* Initialize Port B IIC pins. |
| 45 | */ |
| 46 | cp->cp_pbpar |= 0x00000030; |
| 47 | cp->cp_pbdir |= 0x00000030; |
| 48 | cp->cp_pbodr |= 0x00000030; |
| 49 | |
| 50 | /* Allocate space for two transmit and two receive buffer |
| 51 | * descriptors in the DP ram. |
| 52 | */ |
| 53 | data->dp_addr = cpm_dpalloc(sizeof(cbd_t) * 4, 8); |
| 54 | |
| 55 | /* ptr to i2c area */ |
| 56 | data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c); |
| 57 | } |
| 58 | |
| 59 | static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data) |
| 60 | { |
| 61 | /* install interrupt handler */ |
| 62 | cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data); |
| 63 | |
| 64 | return 0; |
| 65 | } |
| 66 | |
| 67 | static struct i2c_algo_8xx_data rpx_data = { |
| 68 | .setisr = rpx_install_isr |
| 69 | }; |
| 70 | |
| 71 | static struct i2c_adapter rpx_ops = { |
| 72 | .owner = THIS_MODULE, |
| 73 | .name = "m8xx", |
| 74 | .id = I2C_HW_MPC8XX_EPON, |
| 75 | .algo_data = &rpx_data, |
| 76 | }; |
| 77 | |
| 78 | int __init i2c_rpx_init(void) |
| 79 | { |
| 80 | printk(KERN_INFO "i2c-rpx: i2c MPC8xx driver\n"); |
| 81 | |
| 82 | /* reset hardware to sane state */ |
| 83 | rpx_iic_init(&rpx_data); |
| 84 | |
| 85 | if (i2c_8xx_add_bus(&rpx_ops) < 0) { |
| 86 | printk(KERN_ERR "i2c-rpx: Unable to register with I2C\n"); |
| 87 | return -ENODEV; |
| 88 | } |
| 89 | |
| 90 | return 0; |
| 91 | } |
| 92 | |
| 93 | void __exit i2c_rpx_exit(void) |
| 94 | { |
| 95 | i2c_8xx_del_bus(&rpx_ops); |
| 96 | } |
| 97 | |
| 98 | MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>"); |
| 99 | MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards"); |
| 100 | |
| 101 | module_init(i2c_rpx_init); |
| 102 | module_exit(i2c_rpx_exit); |