This patch re-writes the sibyte i2c adapter driver with 2.6.x style binding model. Signed-off-by: Mark Zhan <rongkai.zhan@xxxxxxxxxxxxx> --- drivers/i2c/busses/i2c-sibyte.c | 150 ++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 95 deletions(-) --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2007 Wind River Inc. Mark Zhan <rongkai.zhan@xxxxxxxxxxxxx> * Copyright (C) 2004 Steven J. Hill * Copyright (C) 2001,2002,2003 Broadcom Corporation * Copyright (C) 1995-2000 Simon G. Vogl @@ -22,34 +23,18 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/i2c.h> -#include <asm/io.h> +#include <linux/io.h> +#include <linux/platform_device.h> #include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_smbus.h> +#define SMB_REG_BASE(p_adap) (CKSEG1 + A_SMB_BASE(p_adap->nr)) +#define SMB_CSR(p_adap,r) ((long)(SMB_REG_BASE(p_adap) + r)) -struct i2c_algo_sibyte_data { - void *data; /* private data */ - int bus; /* which bus */ - void *reg_base; /* CSR base */ -}; - -/* ----- global defines ----------------------------------------------- */ -#define SMB_CSR(a,r) ((long)(a->reg_base + r)) - -/* ----- global variables --------------------------------------------- */ - -/* module parameters: - */ -static int bit_scan; /* have a look at what's hanging 'round */ -module_param(bit_scan, int, 0); -MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); - - -static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data * data) +static int sibyte_smbus_xfer(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data * data) { - struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; int data_bytes = 0; int error; @@ -93,11 +78,9 @@ static int smbus_xfer(struct i2c_adapter SMB_CSR(adap, R_SMB_START)); data_bytes = 2; } else { - csr_out32(V_SMB_LB(data->word & 0xff), - SMB_CSR(adap, R_SMB_DATA)); - csr_out32(V_SMB_MB(data->word >> 8), + csr_out32(V_SMB_LB(data->word & 0xff) | V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA)); - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR3BYTE), SMB_CSR(adap, R_SMB_START)); } break; @@ -123,99 +106,76 @@ static int smbus_xfer(struct i2c_adapter return 0; } -static u32 bit_func(struct i2c_adapter *adap) +static u32 sibyte_functionality(struct i2c_adapter *adap) { return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA); } - -/* -----exported algorithm data: ------------------------------------- */ - -static const struct i2c_algorithm i2c_sibyte_algo = { - .smbus_xfer = smbus_xfer, - .functionality = bit_func, +static const struct i2c_algorithm sibyte_i2c_algo = { + .smbus_xfer = sibyte_smbus_xfer, + .functionality = sibyte_functionality, }; -/* - * registering functions to load algorithms at runtime - */ -int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) +static int __devinit sibyte_i2c_probe(struct platform_device *pdev) { - int i; - struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; + struct i2c_adapter *adap; - /* register new adapter to i2c module... */ - i2c_adap->algo = &i2c_sibyte_algo; + adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); + if (!adap) + return -ENOMEM; + + memcpy(adap->name, pdev->name, strlen(pdev->name)); + adap->id = I2C_HW_SIBYTE; + adap->class = I2C_CLASS_HWMON; + adap->owner = THIS_MODULE; + adap->nr = pdev->id; + adap->algo = &sibyte_i2c_algo; + adap->algo_data = NULL; - /* Set the frequency to 100 kHz */ - csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); - csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); + platform_set_drvdata(pdev, adap); - /* scan bus */ - if (bit_scan) { - union i2c_smbus_data data; - int rc; - printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n", - i2c_adap->name); - for (i = 0x00; i < 0x7f; i++) { - /* XXXKW is this a realistic probe? */ - rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0, - I2C_SMBUS_BYTE_DATA, &data); - if (!rc) { - printk("(%02x)",i); - } else - printk("."); - } - printk("\n"); - } + /* Set the frequency to 100 kHz */ + if (adap->nr == 0) + csr_out32(K_SMB_FREQ_100KHZ, SMB_CSR(adap, R_SMB_FREQ)); + else + csr_out32(K_SMB_FREQ_400KHZ, SMB_CSR(adap, R_SMB_FREQ)); + csr_out32(0, SMB_CSR(adap, R_SMB_CONTROL)); - return i2c_add_adapter(i2c_adap); + pr_debug("%s %d registered\n", adap->name, adap->nr); + return i2c_add_numbered_adapter(adap); } +static int __devexit sibyte_i2c_remove(struct platform_device *pdev) +{ + struct i2c_adapter *adap = platform_get_drvdata(pdev); -static struct i2c_algo_sibyte_data sibyte_board_data[2] = { - { NULL, 0, (void *) (CKSEG1+A_SMB_BASE(0)) }, - { NULL, 1, (void *) (CKSEG1+A_SMB_BASE(1)) } -}; + platform_set_drvdata(pdev, NULL); + i2c_del_adapter(adap); + return 0; +} -static struct i2c_adapter sibyte_board_adapter[2] = { - { - .owner = THIS_MODULE, - .id = I2C_HW_SIBYTE, - .class = I2C_CLASS_HWMON, - .algo = NULL, - .algo_data = &sibyte_board_data[0], - .name = "SiByte SMBus 0", - }, - { - .owner = THIS_MODULE, - .id = I2C_HW_SIBYTE, - .class = I2C_CLASS_HWMON, - .algo = NULL, - .algo_data = &sibyte_board_data[1], - .name = "SiByte SMBus 1", +static struct platform_driver sibyte_i2c_driver = { + .probe = sibyte_i2c_probe, + .remove = __devexit_p(sibyte_i2c_remove), + .driver = { + .name = "i2c-sibyte", + .owner = THIS_MODULE, }, }; -static int __init i2c_sibyte_init(void) +static int __init sibyte_i2c_init(void) { - printk("i2c-swarm.o: i2c SMBus adapter module for SiByte board\n"); - if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0) - return -ENODEV; - if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], K_SMB_FREQ_400KHZ) < 0) - return -ENODEV; - return 0; + return platform_driver_register(&sibyte_i2c_driver); } -static void __exit i2c_sibyte_exit(void) +static void __exit sibyte_i2c_exit(void) { - i2c_del_adapter(&sibyte_board_adapter[0]); - i2c_del_adapter(&sibyte_board_adapter[1]); + platform_driver_unregister(&sibyte_i2c_driver); } -module_init(i2c_sibyte_init); -module_exit(i2c_sibyte_exit); +module_init(sibyte_i2c_init); +module_exit(sibyte_i2c_exit); MODULE_AUTHOR("Kip Walker (Broadcom Corp.), Steven J. Hill <sjhill@xxxxxxxxxxxxxxxxxx>"); MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards");