From: Alan Cox Date: Tue, 5 Jul 2011 14:43:07 +0000 (+0100) Subject: gma500: move the i2c code X-Git-Tag: MMI-PSA29.97-13-9~18845^2~389 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=72786d5fb1a6a680126853bfda1e762bd62b329a;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git gma500: move the i2c code This again is similar to upstream so give it a sensible name ready to look at any merging or synchronization Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile index d4a87c07e177..961a60c1afe9 100644 --- a/drivers/staging/gma500/Makefile +++ b/drivers/staging/gma500/Makefile @@ -10,12 +10,12 @@ psb_gfx-y += gem_glue.o \ gem.o \ gtt.o \ intel_bios.o \ + intel_i2c.o \ intel_opregion.o \ mmu.o \ power.o \ psb_drv.o \ psb_intel_display.o \ - psb_intel_i2c.o \ psb_intel_lvds.o \ psb_intel_modes.o \ psb_intel_sdvo.o \ diff --git a/drivers/staging/gma500/intel_i2c.c b/drivers/staging/gma500/intel_i2c.c new file mode 100644 index 000000000000..e33432df510c --- /dev/null +++ b/drivers/staging/gma500/intel_i2c.c @@ -0,0 +1,169 @@ +/* + * Copyright © 2006-2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#include +#include + +#include "psb_drv.h" +#include "psb_intel_reg.h" + +/* + * Intel GPIO access functions + */ + +#define I2C_RISEFALL_TIME 20 + +static int get_clock(void *data) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 val; + + val = REG_READ(chan->reg); + return (val & GPIO_CLOCK_VAL_IN) != 0; +} + +static int get_data(void *data) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 val; + + val = REG_READ(chan->reg); + return (val & GPIO_DATA_VAL_IN) != 0; +} + +static void set_clock(void *data, int state_high) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 reserved = 0, clock_bits; + + /* On most chips, these bits must be preserved in software. */ + reserved = + REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | + GPIO_CLOCK_PULLUP_DISABLE); + + if (state_high) + clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; + else + clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | + GPIO_CLOCK_VAL_MASK; + REG_WRITE(chan->reg, reserved | clock_bits); + udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ +} + +static void set_data(void *data, int state_high) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 reserved = 0, data_bits; + + /* On most chips, these bits must be preserved in software. */ + reserved = + REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | + GPIO_CLOCK_PULLUP_DISABLE); + + if (state_high) + data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; + else + data_bits = + GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | + GPIO_DATA_VAL_MASK; + + REG_WRITE(chan->reg, reserved | data_bits); + udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ +} + +/** + * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg + * @dev: DRM device + * @output: driver specific output device + * @reg: GPIO reg to use + * @name: name for this bus + * + * Creates and registers a new i2c bus with the Linux i2c layer, for use + * in output probing and control (e.g. DDC or SDVO control functions). + * + * Possible values for @reg include: + * %GPIOA + * %GPIOB + * %GPIOC + * %GPIOD + * %GPIOE + * %GPIOF + * %GPIOG + * %GPIOH + * see PRM for details on how these different busses are used. + */ +struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, + const u32 reg, const char *name) +{ + struct psb_intel_i2c_chan *chan; + + chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL); + if (!chan) + goto out_free; + + chan->drm_dev = dev; + chan->reg = reg; + snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); + chan->adapter.owner = THIS_MODULE; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &dev->pdev->dev; + chan->algo.setsda = set_data; + chan->algo.setscl = set_clock; + chan->algo.getsda = get_data; + chan->algo.getscl = get_clock; + chan->algo.udelay = 20; + chan->algo.timeout = usecs_to_jiffies(2200); + chan->algo.data = chan; + + i2c_set_adapdata(&chan->adapter, chan); + + if (i2c_bit_add_bus(&chan->adapter)) + goto out_free; + + /* JJJ: raise SCL and SDA? */ + set_data(chan, 1); + set_clock(chan, 1); + udelay(20); + + return chan; + +out_free: + kfree(chan); + return NULL; +} + +/** + * psb_intel_i2c_destroy - unregister and free i2c bus resources + * @output: channel to free + * + * Unregister the adapter from the i2c layer, then free the structure. + */ +void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan) +{ + if (!chan) + return; + + i2c_del_adapter(&chan->adapter); + kfree(chan); +} diff --git a/drivers/staging/gma500/psb_intel_i2c.c b/drivers/staging/gma500/psb_intel_i2c.c deleted file mode 100644 index e33432df510c..000000000000 --- a/drivers/staging/gma500/psb_intel_i2c.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - */ - -#include -#include - -#include "psb_drv.h" -#include "psb_intel_reg.h" - -/* - * Intel GPIO access functions - */ - -#define I2C_RISEFALL_TIME 20 - -static int get_clock(void *data) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 val; - - val = REG_READ(chan->reg); - return (val & GPIO_CLOCK_VAL_IN) != 0; -} - -static int get_data(void *data) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 val; - - val = REG_READ(chan->reg); - return (val & GPIO_DATA_VAL_IN) != 0; -} - -static void set_clock(void *data, int state_high) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 reserved = 0, clock_bits; - - /* On most chips, these bits must be preserved in software. */ - reserved = - REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - if (state_high) - clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; - else - clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | - GPIO_CLOCK_VAL_MASK; - REG_WRITE(chan->reg, reserved | clock_bits); - udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ -} - -static void set_data(void *data, int state_high) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 reserved = 0, data_bits; - - /* On most chips, these bits must be preserved in software. */ - reserved = - REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - if (state_high) - data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; - else - data_bits = - GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | - GPIO_DATA_VAL_MASK; - - REG_WRITE(chan->reg, reserved | data_bits); - udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ -} - -/** - * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg - * @dev: DRM device - * @output: driver specific output device - * @reg: GPIO reg to use - * @name: name for this bus - * - * Creates and registers a new i2c bus with the Linux i2c layer, for use - * in output probing and control (e.g. DDC or SDVO control functions). - * - * Possible values for @reg include: - * %GPIOA - * %GPIOB - * %GPIOC - * %GPIOD - * %GPIOE - * %GPIOF - * %GPIOG - * %GPIOH - * see PRM for details on how these different busses are used. - */ -struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, - const u32 reg, const char *name) -{ - struct psb_intel_i2c_chan *chan; - - chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL); - if (!chan) - goto out_free; - - chan->drm_dev = dev; - chan->reg = reg; - snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); - chan->adapter.owner = THIS_MODULE; - chan->adapter.algo_data = &chan->algo; - chan->adapter.dev.parent = &dev->pdev->dev; - chan->algo.setsda = set_data; - chan->algo.setscl = set_clock; - chan->algo.getsda = get_data; - chan->algo.getscl = get_clock; - chan->algo.udelay = 20; - chan->algo.timeout = usecs_to_jiffies(2200); - chan->algo.data = chan; - - i2c_set_adapdata(&chan->adapter, chan); - - if (i2c_bit_add_bus(&chan->adapter)) - goto out_free; - - /* JJJ: raise SCL and SDA? */ - set_data(chan, 1); - set_clock(chan, 1); - udelay(20); - - return chan; - -out_free: - kfree(chan); - return NULL; -} - -/** - * psb_intel_i2c_destroy - unregister and free i2c bus resources - * @output: channel to free - * - * Unregister the adapter from the i2c layer, then free the structure. - */ -void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan) -{ - if (!chan) - return; - - i2c_del_adapter(&chan->adapter); - kfree(chan); -}