[PATCH] ep93xx: update i2c support
H Hartley Sweeten
hartleys at visionengravers.com
Wed Sep 30 16:18:43 EDT 2009
On Wednesday, September 30, 2009 1:10 PM, Ryan Mallon wrote:
> H Hartley Sweeten wrote:
>> Update the ep93xx i2c support to allow the platform init to configure
>> the sda and scl pins as open drain or normal cmos drivers. Also allow
>> the platform to set the udelay and timeout for the i2c-gpio driver.
>>
>> Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
>>
>> ---
>>
>> V2 - __raw_write should be __raw_writel
>>
>>
>> diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
>> index 16b92c3..49e74b6 100644
>> --- a/arch/arm/mach-ep93xx/core.c
>> +++ b/arch/arm/mach-ep93xx/core.c
>> @@ -549,12 +549,13 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
>> platform_device_register(&ep93xx_eth_device);
>> }
>>
>> +
>> +/*************************************************************************
>> + * EP93xx i2c peripheral handling
>> + *************************************************************************/
>> static struct i2c_gpio_platform_data ep93xx_i2c_data = {
>> .sda_pin = EP93XX_GPIO_LINE_EEDAT,
>> - .sda_is_open_drain = 0,
>> .scl_pin = EP93XX_GPIO_LINE_EECLK,
>> - .scl_is_open_drain = 0,
>> - .udelay = 2,
>> };
>>
>> static struct platform_device ep93xx_i2c_device = {
>> @@ -563,8 +564,32 @@ static struct platform_device ep93xx_i2c_device = {
>> .dev.platform_data = &ep93xx_i2c_data,
>> };
>>
>> -void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
>> +void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num,
>> + int sda_is_open_drain, int scl_is_open_drain,
>> + int udelay, int timeout)
>> {
>> + /*
>> + * Set the EEPROM interface pin drive type control.
>> + * Defines the driver type for the EECLK and EEDAT pins as either
>> + * open drain, which will require an external pull-up, or a normal
>> + * CMOS driver.
>> + */
>> + ep93xx_i2c_data.sda_is_open_drain = sda_is_open_drain;
>> + ep93xx_i2c_data.scl_is_open_drain = scl_is_open_drain;
>> +
>> + __raw_writel((sda_is_open_drain<<1) | (scl_is_open_drain<<0)),
>> + EP93XX_GPIO_EEDRIVE);
>> +
>> + /*
>> + * udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz
>> + * == 0 will default to 5 (100 khz)
>> + * timeout: clock stretching timeout in jiffies. If the slave keeps
>> + * SCL low for longer than this, the transfer will time out.
>> + * == 0 will default to HZ / 10 (100 ms)
>> + */
>> + ep93xx_i2c_data.udelay = udelay;
>> + ep93xx_i2c_data.timeout = timeout;
>> +
>> i2c_register_board_info(0, devices, num);
>> platform_device_register(&ep93xx_i2c_device);
>> }
>>
>>
> I find this a bit ugly since you basically use the register_i2c function
> to fill in the struct elements. Why not just let each board fill in the
> i2c platform data itself. This is more consistent with the other device
> registration functions and also allows boards to use other gpio pins for
> i2c if they want, ie (untested):
>
> diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
> index 681bd68..a5bf12d 100644
> --- a/arch/arm/mach-ep93xx/core.c
> +++ b/arch/arm/mach-ep93xx/core.c
> @@ -550,13 +550,7 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
> platform_device_register(&ep93xx_eth_device);
> }
>
> -static struct i2c_gpio_platform_data ep93xx_i2c_data = {
> - .sda_pin = EP93XX_GPIO_LINE_EEDAT,
> - .sda_is_open_drain = 0,
> - .scl_pin = EP93XX_GPIO_LINE_EECLK,
> - .scl_is_open_drain = 0,
> - .udelay = 2,
> -};
> +static struct i2c_gpio_platform_data ep93xx_i2c_data;
>
> static struct platform_device ep93xx_i2c_device = {
> .name = "i2c-gpio",
> @@ -564,8 +558,13 @@ static struct platform_device ep93xx_i2c_device = {
> .dev.platform_data = &ep93xx_i2c_data,
> };
>
> -void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
> +void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *pdata,
> + struct i2c_board_info *devices, int num)
> {
> + ep93xx_i2c_data = *pdata;
> + __raw_writel((ep9xx_i2c_data.sda_is_open_drain << 1) |
> + (ep9xx_i2c_data.scl_is_open_drain << 0),
> + EP93XX_GPIO_EEDRIVE);
> i2c_register_board_info(0, devices, num);
> platform_device_register(&ep93xx_i2c_device);
> }
>
> Obviously the board files also need to be fixed up.
>
Good point about using gpio pins other than EEDAT and EECLK. For instance
the TS-7200 board doesn't have the pins accessible but there is a patch on
the yahoo site that uses two of the pins on their DIO port.
I will modify the patch and repost.
Thanks,
Hartley
More information about the linux-arm-kernel
mailing list