From: Albert H. <he...@us...> - 2009-03-02 18:20:45
|
Update of /cvsroot/gc-linux/linux/drivers/i2c/busses In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv31728/drivers/i2c/busses Modified Files: Kconfig Makefile i2c-gpio.c Added Files: i2c-gpio-common.c i2c-gpio-common.h Log Message: [PATCH] i2c-gpio: split into i2c-gpio-common and i2c-gpio From: Albert Herranz <alb...@ya...> Date: Fri, 27 Feb 2009 20:17:53 +0100 Subject: [PATCH] i2c-gpio: split into i2c-gpio-common and i2c-gpio Extract the core code into a new helper module i2c-gpio-common. This will allow sharing code between the current driver (i2c-gpio) which uses platform bus bindings and a future driver (i2c-gpio-of) which will make use of of_platform bus bindings. Signed-off-by: Albert Herranz <alb...@ya...> Index: Kconfig =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/i2c/busses/Kconfig,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Kconfig 2 Mar 2009 18:18:55 -0000 1.1 --- Kconfig 2 Mar 2009 18:20:40 -0000 1.2 *************** *** 326,333 **** For details please see http://www.ti.com/davinci ! config I2C_GPIO ! tristate "GPIO-based bitbanging I2C" depends on GENERIC_GPIO select I2C_ALGOBIT help This is a very simple bitbanging I2C driver utilizing the --- 326,338 ---- For details please see http://www.ti.com/davinci ! config I2C_GPIO_COMMON ! tristate depends on GENERIC_GPIO select I2C_ALGOBIT + default n + + config I2C_GPIO + tristate "GPIO-based bitbanging I2C" + select I2C_GPIO_COMMON help This is a very simple bitbanging I2C driver utilizing the Index: Makefile =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/i2c/busses/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Makefile 2 Mar 2009 18:18:55 -0000 1.1 --- Makefile 2 Mar 2009 18:20:40 -0000 1.2 *************** *** 31,34 **** --- 31,35 ---- obj-$(CONFIG_I2C_CPM) += i2c-cpm.o obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o + obj-$(CONFIG_I2C_GPIO_COMMON) += i2c-gpio-common.o obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o --- NEW FILE: i2c-gpio-common.h --- /* * Bitbanging I2C bus driver using the GPIO API * * Copyright (C) 2007 Atmel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef __I2C_GPIO_COMMON_H #define __I2C_GPIO_COMMON_H #include <linux/i2c.h> #include <linux/i2c-gpio.h> #include <linux/module.h> #include <linux/device.h> int i2c_gpio_adapter_probe(struct i2c_adapter *adap, struct i2c_gpio_platform_data *pdata, struct device *parent, int id, struct module *owner); int i2c_gpio_adapter_remove(struct i2c_adapter *adap, struct i2c_gpio_platform_data *pdata); #endif /* __I2C_GPIO_COMMON_H */ --- NEW FILE: i2c-gpio-common.c --- /* * Core logic for the bitbanging I2C bus driver using the GPIO API * * Copyright (C) 2007 Atmel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include "i2c-gpio-common.h" #include <linux/i2c-algo-bit.h> #include <linux/gpio.h> /* Toggle SDA by changing the direction of the pin */ static void i2c_gpio_setsda_dir(void *data, int state) { struct i2c_gpio_platform_data *pdata = data; if (state) gpio_direction_input(pdata->sda_pin); else gpio_direction_output(pdata->sda_pin, 0); } /* * Toggle SDA by changing the output value of the pin. This is only * valid for pins configured as open drain (i.e. setting the value * high effectively turns off the output driver.) */ static void i2c_gpio_setsda_val(void *data, int state) { struct i2c_gpio_platform_data *pdata = data; gpio_set_value(pdata->sda_pin, state); } /* Toggle SCL by changing the direction of the pin. */ static void i2c_gpio_setscl_dir(void *data, int state) { struct i2c_gpio_platform_data *pdata = data; if (state) gpio_direction_input(pdata->scl_pin); else gpio_direction_output(pdata->scl_pin, 0); } /* * Toggle SCL by changing the output value of the pin. This is used * for pins that are configured as open drain and for output-only * pins. The latter case will break the i2c protocol, but it will * often work in practice. */ static void i2c_gpio_setscl_val(void *data, int state) { struct i2c_gpio_platform_data *pdata = data; gpio_set_value(pdata->scl_pin, state); } static int i2c_gpio_getsda(void *data) { struct i2c_gpio_platform_data *pdata = data; return gpio_get_value(pdata->sda_pin); } static int i2c_gpio_getscl(void *data) { struct i2c_gpio_platform_data *pdata = data; return gpio_get_value(pdata->scl_pin); } int i2c_gpio_adapter_probe(struct i2c_adapter *adap, struct i2c_gpio_platform_data *pdata, struct device *parent, int id, struct module *owner) { struct i2c_algo_bit_data *bit_data; int error; error = -ENOMEM; bit_data = kzalloc(sizeof(*bit_data), GFP_KERNEL); if (!bit_data) goto err_alloc_bit_data; error = gpio_request(pdata->sda_pin, "sda"); if (error) goto err_request_sda; error = gpio_request(pdata->scl_pin, "scl"); if (error) goto err_request_scl; if (pdata->sda_is_open_drain) { gpio_direction_output(pdata->sda_pin, 1); bit_data->setsda = i2c_gpio_setsda_val; } else { gpio_direction_input(pdata->sda_pin); bit_data->setsda = i2c_gpio_setsda_dir; } if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { gpio_direction_output(pdata->scl_pin, 1); bit_data->setscl = i2c_gpio_setscl_val; } else { gpio_direction_input(pdata->scl_pin); bit_data->setscl = i2c_gpio_setscl_dir; } if (!pdata->scl_is_output_only) bit_data->getscl = i2c_gpio_getscl; bit_data->getsda = i2c_gpio_getsda; if (pdata->udelay) bit_data->udelay = pdata->udelay; else if (pdata->scl_is_output_only) bit_data->udelay = 50; /* 10 kHz */ else bit_data->udelay = 5; /* 100 kHz */ if (pdata->timeout) bit_data->timeout = pdata->timeout; else bit_data->timeout = HZ / 10; /* 100 ms */ bit_data->data = pdata; adap->owner = owner; snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", id); adap->algo_data = bit_data; adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->dev.parent = parent; /* * If "id" is negative we consider it as zero. * The reason to do so is to avoid sysfs names that only make * sense when there are multiple adapters. */ adap->nr = (id != -1) ? id : 0; error = i2c_bit_add_numbered_bus(adap); if (error) goto err_add_bus; dev_info(parent, "using pins %u (SDA) and %u (SCL%s)\n", pdata->sda_pin, pdata->scl_pin, pdata->scl_is_output_only ? ", no clock stretching" : ""); return 0; err_add_bus: gpio_free(pdata->scl_pin); err_request_scl: gpio_free(pdata->sda_pin); err_request_sda: kfree(bit_data); err_alloc_bit_data: return error; } EXPORT_SYMBOL(i2c_gpio_adapter_probe); int i2c_gpio_adapter_remove(struct i2c_adapter *adap, struct i2c_gpio_platform_data *pdata) { i2c_del_adapter(adap); gpio_free(pdata->scl_pin); gpio_free(pdata->sda_pin); kfree(adap->algo_data); kfree(adap); return 0; } EXPORT_SYMBOL(i2c_gpio_adapter_remove); MODULE_AUTHOR("Haavard Skinnemoen <hsk...@at...>"); MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver common logic"); MODULE_LICENSE("GPL"); Index: i2c-gpio.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/i2c/busses/i2c-gpio.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** i2c-gpio.c 2 Mar 2009 18:18:55 -0000 1.1 --- i2c-gpio.c 2 Mar 2009 18:20:40 -0000 1.2 *************** *** 8,87 **** * published by the Free Software Foundation. */ - #include <linux/i2c.h> - #include <linux/i2c-algo-bit.h> - #include <linux/i2c-gpio.h> - #include <linux/init.h> - #include <linux/module.h> - #include <linux/platform_device.h> - - #include <asm/gpio.h> - - /* Toggle SDA by changing the direction of the pin */ - static void i2c_gpio_setsda_dir(void *data, int state) - { - struct i2c_gpio_platform_data *pdata = data; - - if (state) - gpio_direction_input(pdata->sda_pin); - else - gpio_direction_output(pdata->sda_pin, 0); - } - - /* - * Toggle SDA by changing the output value of the pin. This is only - * valid for pins configured as open drain (i.e. setting the value - * high effectively turns off the output driver.) - */ - static void i2c_gpio_setsda_val(void *data, int state) - { - struct i2c_gpio_platform_data *pdata = data; ! gpio_set_value(pdata->sda_pin, state); ! } ! ! /* Toggle SCL by changing the direction of the pin. */ ! static void i2c_gpio_setscl_dir(void *data, int state) ! { ! struct i2c_gpio_platform_data *pdata = data; ! if (state) ! gpio_direction_input(pdata->scl_pin); ! else ! gpio_direction_output(pdata->scl_pin, 0); ! } /* ! * Toggle SCL by changing the output value of the pin. This is used ! * for pins that are configured as open drain and for output-only ! * pins. The latter case will break the i2c protocol, but it will ! * often work in practice. */ - static void i2c_gpio_setscl_val(void *data, int state) - { - struct i2c_gpio_platform_data *pdata = data; - - gpio_set_value(pdata->scl_pin, state); - } - - static int i2c_gpio_getsda(void *data) - { - struct i2c_gpio_platform_data *pdata = data; - - return gpio_get_value(pdata->sda_pin); - } - - static int i2c_gpio_getscl(void *data) - { - struct i2c_gpio_platform_data *pdata = data; - - return gpio_get_value(pdata->scl_pin); - } static int __devinit i2c_gpio_probe(struct platform_device *pdev) { struct i2c_gpio_platform_data *pdata; - struct i2c_algo_bit_data *bit_data; struct i2c_adapter *adap; ! int ret; pdata = pdev->dev.platform_data; --- 8,27 ---- * published by the Free Software Foundation. */ ! #include "i2c-gpio-common.h" ! #include <linux/init.h> ! #include <linux/platform_device.h> /* ! * Platform bindings. ! * */ static int __devinit i2c_gpio_probe(struct platform_device *pdev) { struct i2c_gpio_platform_data *pdata; struct i2c_adapter *adap; ! int error; pdata = pdev->dev.platform_data; *************** *** 89,192 **** return -ENXIO; ! ret = -ENOMEM; ! adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); if (!adap) goto err_alloc_adap; ! bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL); ! if (!bit_data) ! goto err_alloc_bit_data; ! ! ret = gpio_request(pdata->sda_pin, "sda"); ! if (ret) ! goto err_request_sda; ! ret = gpio_request(pdata->scl_pin, "scl"); ! if (ret) ! goto err_request_scl; ! ! if (pdata->sda_is_open_drain) { ! gpio_direction_output(pdata->sda_pin, 1); ! bit_data->setsda = i2c_gpio_setsda_val; ! } else { ! gpio_direction_input(pdata->sda_pin); ! bit_data->setsda = i2c_gpio_setsda_dir; ! } ! ! if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { ! gpio_direction_output(pdata->scl_pin, 1); ! bit_data->setscl = i2c_gpio_setscl_val; ! } else { ! gpio_direction_input(pdata->scl_pin); ! bit_data->setscl = i2c_gpio_setscl_dir; ! } ! ! if (!pdata->scl_is_output_only) ! bit_data->getscl = i2c_gpio_getscl; ! bit_data->getsda = i2c_gpio_getsda; ! ! if (pdata->udelay) ! bit_data->udelay = pdata->udelay; ! else if (pdata->scl_is_output_only) ! bit_data->udelay = 50; /* 10 kHz */ ! else ! bit_data->udelay = 5; /* 100 kHz */ ! ! if (pdata->timeout) ! bit_data->timeout = pdata->timeout; ! else ! bit_data->timeout = HZ / 10; /* 100 ms */ ! ! bit_data->data = pdata; ! ! adap->owner = THIS_MODULE; ! snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); ! adap->algo_data = bit_data; ! adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; ! adap->dev.parent = &pdev->dev; ! ! /* ! * If "dev->id" is negative we consider it as zero. ! * The reason to do so is to avoid sysfs names that only make ! * sense when there are multiple adapters. ! */ ! adap->nr = (pdev->id != -1) ? pdev->id : 0; ! ret = i2c_bit_add_numbered_bus(adap); ! if (ret) ! goto err_add_bus; platform_set_drvdata(pdev, adap); - dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", - pdata->sda_pin, pdata->scl_pin, - pdata->scl_is_output_only - ? ", no clock stretching" : ""); - return 0; ! err_add_bus: ! gpio_free(pdata->scl_pin); ! err_request_scl: ! gpio_free(pdata->sda_pin); ! err_request_sda: ! kfree(bit_data); ! err_alloc_bit_data: kfree(adap); err_alloc_adap: ! return ret; } static int __devexit i2c_gpio_remove(struct platform_device *pdev) { - struct i2c_gpio_platform_data *pdata; struct i2c_adapter *adap; adap = platform_get_drvdata(pdev); pdata = pdev->dev.platform_data; ! i2c_del_adapter(adap); ! gpio_free(pdata->scl_pin); ! gpio_free(pdata->sda_pin); ! kfree(adap->algo_data); kfree(adap); - return 0; } --- 29,61 ---- return -ENXIO; ! error = -ENOMEM; ! adap = kzalloc(sizeof(*adap), GFP_KERNEL); if (!adap) goto err_alloc_adap; ! error = i2c_gpio_adapter_probe(adap, pdata, &pdev->dev, pdev->id, ! THIS_MODULE); ! if (error) ! goto err_probe; platform_set_drvdata(pdev, adap); return 0; ! err_probe: kfree(adap); err_alloc_adap: ! return error; } static int __devexit i2c_gpio_remove(struct platform_device *pdev) { struct i2c_adapter *adap; + struct i2c_gpio_platform_data *pdata; adap = platform_get_drvdata(pdev); pdata = pdev->dev.platform_data; ! i2c_gpio_adapter_remove(adap, pdata); kfree(adap); return 0; } *************** *** 203,213 **** static int __init i2c_gpio_init(void) { ! int ret; ! ret = platform_driver_register(&i2c_gpio_driver); ! if (ret) ! printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); ! return ret; } module_init(i2c_gpio_init); --- 72,82 ---- static int __init i2c_gpio_init(void) { ! int error; ! error = platform_driver_register(&i2c_gpio_driver); ! if (error) ! printk(KERN_ERR "i2c-gpio: registration failed (%d)\n", error); ! return error; } module_init(i2c_gpio_init); |