linux/arch/arm/mach-omap1/i2c.c
<<
>>
Prefs
   1/*
   2 * Helper module for board specific I2C bus registration
   3 *
   4 * Copyright (C) 2009 Nokia Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * version 2 as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  18 * 02110-1301 USA
  19 *
  20 */
  21
  22#include <linux/i2c.h>
  23#include <linux/platform_data/i2c-omap.h>
  24#include <mach/mux.h>
  25#include "soc.h"
  26
  27#define OMAP_I2C_SIZE           0x3f
  28#define OMAP1_I2C_BASE          0xfffb3800
  29
  30static const char name[] = "omap_i2c";
  31
  32static struct resource i2c_resources[2] = {
  33};
  34
  35static struct platform_device omap_i2c_devices[1] = {
  36};
  37
  38static void __init omap1_i2c_mux_pins(int bus_id)
  39{
  40        if (cpu_is_omap7xx()) {
  41                omap_cfg_reg(I2C_7XX_SDA);
  42                omap_cfg_reg(I2C_7XX_SCL);
  43        } else {
  44                omap_cfg_reg(I2C_SDA);
  45                omap_cfg_reg(I2C_SCL);
  46        }
  47}
  48
  49int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata,
  50                                int bus_id)
  51{
  52        struct platform_device *pdev;
  53        struct resource *res;
  54
  55        if (bus_id > 1)
  56                return -EINVAL;
  57
  58        omap1_i2c_mux_pins(bus_id);
  59
  60        pdev = &omap_i2c_devices[bus_id - 1];
  61        pdev->id = bus_id;
  62        pdev->name = name;
  63        pdev->num_resources = ARRAY_SIZE(i2c_resources);
  64        res = i2c_resources;
  65        res[0].start = OMAP1_I2C_BASE;
  66        res[0].end = res[0].start + OMAP_I2C_SIZE;
  67        res[0].flags = IORESOURCE_MEM;
  68        res[1].start = INT_I2C;
  69        res[1].flags = IORESOURCE_IRQ;
  70        pdev->resource = res;
  71
  72        /* all OMAP1 have IP version 1 register set */
  73        pdata->rev = OMAP_I2C_IP_VERSION_1;
  74
  75        /* all OMAP1 I2C are implemented like this */
  76        pdata->flags = OMAP_I2C_FLAG_NO_FIFO |
  77                       OMAP_I2C_FLAG_SIMPLE_CLOCK |
  78                       OMAP_I2C_FLAG_16BIT_DATA_REG |
  79                       OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK;
  80
  81        /* how the cpu bus is wired up differs for 7xx only */
  82
  83        if (cpu_is_omap7xx())
  84                pdata->flags |= OMAP_I2C_FLAG_BUS_SHIFT_1;
  85        else
  86                pdata->flags |= OMAP_I2C_FLAG_BUS_SHIFT_2;
  87
  88        pdev->dev.platform_data = pdata;
  89
  90        return platform_device_register(pdev);
  91}
  92
  93#define OMAP_I2C_MAX_CONTROLLERS 4
  94static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
  95
  96#define OMAP_I2C_CMDLINE_SETUP  (BIT(31))
  97
  98/**
  99 * omap_i2c_bus_setup - Process command line options for the I2C bus speed
 100 * @str: String of options
 101 *
 102 * This function allow to override the default I2C bus speed for given I2C
 103 * bus with a command line option.
 104 *
 105 * Format: i2c_bus=bus_id,clkrate (in kHz)
 106 *
 107 * Returns 1 on success, 0 otherwise.
 108 */
 109static int __init omap_i2c_bus_setup(char *str)
 110{
 111        int ints[3];
 112
 113        get_options(str, 3, ints);
 114        if (ints[0] < 2 || ints[1] < 1 ||
 115                        ints[1] > OMAP_I2C_MAX_CONTROLLERS)
 116                return 0;
 117        i2c_pdata[ints[1] - 1].clkrate = ints[2];
 118        i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP;
 119
 120        return 1;
 121}
 122__setup("i2c_bus=", omap_i2c_bus_setup);
 123
 124/*
 125 * Register busses defined in command line but that are not registered with
 126 * omap_register_i2c_bus from board initialization code.
 127 */
 128int __init omap_register_i2c_bus_cmdline(void)
 129{
 130        int i, err = 0;
 131
 132        for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++)
 133                if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) {
 134                        i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
 135                        err = omap_i2c_add_bus(&i2c_pdata[i], i + 1);
 136                        if (err)
 137                                goto out;
 138                }
 139
 140out:
 141        return err;
 142}
 143
 144/**
 145 * omap_register_i2c_bus - register I2C bus with device descriptors
 146 * @bus_id: bus id counting from number 1
 147 * @clkrate: clock rate of the bus in kHz
 148 * @info: pointer into I2C device descriptor table or NULL
 149 * @len: number of descriptors in the table
 150 *
 151 * Returns 0 on success or an error code.
 152 */
 153int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
 154                          struct i2c_board_info const *info,
 155                          unsigned len)
 156{
 157        int err;
 158
 159        BUG_ON(bus_id < 1 || bus_id > OMAP_I2C_MAX_CONTROLLERS);
 160
 161        if (info) {
 162                err = i2c_register_board_info(bus_id, info, len);
 163                if (err)
 164                        return err;
 165        }
 166
 167        if (!i2c_pdata[bus_id - 1].clkrate)
 168                i2c_pdata[bus_id - 1].clkrate = clkrate;
 169
 170        i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
 171
 172        return omap_i2c_add_bus(&i2c_pdata[bus_id - 1], bus_id);
 173}
 174
 175static  int __init omap_i2c_cmdline(void)
 176{
 177        return omap_register_i2c_bus_cmdline();
 178}
 179subsys_initcall(omap_i2c_cmdline);
 180