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