linux/arch/arm/mach-pnx4008/i2c.c
<<
>>
Prefs
   1/*
   2 * I2C initialization for PNX4008.
   3 *
   4 * Author: Vitaly Wool <vitalywool@gmail.com>
   5 *
   6 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
   7 * the terms of the GNU General Public License version 2. This program
   8 * is licensed "as is" without any warranty of any kind, whether express
   9 * or implied.
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/i2c.h>
  14#include <linux/i2c-pnx.h>
  15#include <linux/platform_device.h>
  16#include <linux/err.h>
  17#include <mach/platform.h>
  18#include <mach/i2c.h>
  19
  20static int set_clock_run(struct platform_device *pdev)
  21{
  22        struct clk *clk;
  23        char name[10];
  24        int retval = 0;
  25
  26        snprintf(name, 10, "i2c%d_ck", pdev->id);
  27        clk = clk_get(&pdev->dev, name);
  28        if (!IS_ERR(clk)) {
  29                clk_set_rate(clk, 1);
  30                clk_put(clk);
  31        } else
  32                retval = -ENOENT;
  33
  34        return retval;
  35}
  36
  37static int set_clock_stop(struct platform_device *pdev)
  38{
  39        struct clk *clk;
  40        char name[10];
  41        int retval = 0;
  42
  43        snprintf(name, 10, "i2c%d_ck", pdev->id);
  44        clk = clk_get(&pdev->dev, name);
  45        if (!IS_ERR(clk)) {
  46                clk_set_rate(clk, 0);
  47                clk_put(clk);
  48        } else
  49                retval = -ENOENT;
  50
  51        return retval;
  52}
  53
  54static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state)
  55{
  56        int retval = 0;
  57#ifdef CONFIG_PM
  58        retval = set_clock_run(pdev);
  59#endif
  60        return retval;
  61}
  62
  63static int i2c_pnx_resume(struct platform_device *pdev)
  64{
  65        int retval = 0;
  66#ifdef CONFIG_PM
  67        retval = set_clock_run(pdev);
  68#endif
  69        return retval;
  70}
  71
  72static u32 calculate_input_freq(struct platform_device *pdev)
  73{
  74        return HCLK_MHZ;
  75}
  76
  77
  78static struct i2c_pnx_algo_data pnx_algo_data0 = {
  79        .base = PNX4008_I2C1_BASE,
  80        .irq = I2C_1_INT,
  81};
  82
  83static struct i2c_pnx_algo_data pnx_algo_data1 = {
  84        .base = PNX4008_I2C2_BASE,
  85        .irq = I2C_2_INT,
  86};
  87
  88static struct i2c_pnx_algo_data pnx_algo_data2 = {
  89        .base = (PNX4008_USB_CONFIG_BASE + 0x300),
  90        .irq = USB_I2C_INT,
  91};
  92
  93static struct i2c_adapter pnx_adapter0 = {
  94        .name = I2C_CHIP_NAME "0",
  95        .algo_data = &pnx_algo_data0,
  96};
  97static struct i2c_adapter pnx_adapter1 = {
  98        .name = I2C_CHIP_NAME "1",
  99        .algo_data = &pnx_algo_data1,
 100};
 101
 102static struct i2c_adapter pnx_adapter2 = {
 103        .name = "USB-I2C",
 104        .algo_data = &pnx_algo_data2,
 105};
 106
 107static struct i2c_pnx_data i2c0_data = {
 108        .suspend = i2c_pnx_suspend,
 109        .resume = i2c_pnx_resume,
 110        .calculate_input_freq = calculate_input_freq,
 111        .set_clock_run = set_clock_run,
 112        .set_clock_stop = set_clock_stop,
 113        .adapter = &pnx_adapter0,
 114};
 115
 116static struct i2c_pnx_data i2c1_data = {
 117        .suspend = i2c_pnx_suspend,
 118        .resume = i2c_pnx_resume,
 119        .calculate_input_freq = calculate_input_freq,
 120        .set_clock_run = set_clock_run,
 121        .set_clock_stop = set_clock_stop,
 122        .adapter = &pnx_adapter1,
 123};
 124
 125static struct i2c_pnx_data i2c2_data = {
 126        .suspend = i2c_pnx_suspend,
 127        .resume = i2c_pnx_resume,
 128        .calculate_input_freq = calculate_input_freq,
 129        .set_clock_run = set_clock_run,
 130        .set_clock_stop = set_clock_stop,
 131        .adapter = &pnx_adapter2,
 132};
 133
 134static struct platform_device i2c0_device = {
 135        .name = "pnx-i2c",
 136        .id = 0,
 137        .dev = {
 138                .platform_data = &i2c0_data,
 139        },
 140};
 141
 142static struct platform_device i2c1_device = {
 143        .name = "pnx-i2c",
 144        .id = 1,
 145        .dev = {
 146                .platform_data = &i2c1_data,
 147        },
 148};
 149
 150static struct platform_device i2c2_device = {
 151        .name = "pnx-i2c",
 152        .id = 2,
 153        .dev = {
 154                .platform_data = &i2c2_data,
 155        },
 156};
 157
 158static struct platform_device *devices[] __initdata = {
 159        &i2c0_device,
 160        &i2c1_device,
 161        &i2c2_device,
 162};
 163
 164void __init pnx4008_register_i2c_devices(void)
 165{
 166        platform_add_devices(devices, ARRAY_SIZE(devices));
 167}
 168