linux/drivers/i2c/busses/i2c-acorn.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/acorn/char/i2c.c
   3 *
   4 *  Copyright (C) 2000 Russell King
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 *  ARM IOC/IOMD i2c driver.
  11 *
  12 *  On Acorn machines, the following i2c devices are on the bus:
  13 *      - PCF8583 real time clock & static RAM
  14 */
  15#include <linux/module.h>
  16#include <linux/i2c.h>
  17#include <linux/i2c-algo-bit.h>
  18#include <linux/io.h>
  19
  20#include <mach/hardware.h>
  21#include <asm/hardware/ioc.h>
  22
  23#define FORCE_ONES      0xdc
  24#define SCL             0x02
  25#define SDA             0x01
  26
  27/*
  28 * We must preserve all non-i2c output bits in IOC_CONTROL.
  29 * Note also that we need to preserve the value of SCL and
  30 * SDA outputs as well (which may be different from the
  31 * values read back from IOC_CONTROL).
  32 */
  33static u_int force_ones;
  34
  35static void ioc_setscl(void *data, int state)
  36{
  37        u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
  38        u_int ones = force_ones;
  39
  40        if (state)
  41                ones |= SCL;
  42        else
  43                ones &= ~SCL;
  44
  45        force_ones = ones;
  46
  47        ioc_writeb(ioc_control | ones, IOC_CONTROL);
  48}
  49
  50static void ioc_setsda(void *data, int state)
  51{
  52        u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
  53        u_int ones = force_ones;
  54
  55        if (state)
  56                ones |= SDA;
  57        else
  58                ones &= ~SDA;
  59
  60        force_ones = ones;
  61
  62        ioc_writeb(ioc_control | ones, IOC_CONTROL);
  63}
  64
  65static int ioc_getscl(void *data)
  66{
  67        return (ioc_readb(IOC_CONTROL) & SCL) != 0;
  68}
  69
  70static int ioc_getsda(void *data)
  71{
  72        return (ioc_readb(IOC_CONTROL) & SDA) != 0;
  73}
  74
  75static struct i2c_algo_bit_data ioc_data = {
  76        .setsda         = ioc_setsda,
  77        .setscl         = ioc_setscl,
  78        .getsda         = ioc_getsda,
  79        .getscl         = ioc_getscl,
  80        .udelay         = 80,
  81        .timeout        = HZ,
  82};
  83
  84static struct i2c_adapter ioc_ops = {
  85        .nr                     = 0,
  86        .algo_data              = &ioc_data,
  87};
  88
  89static int __init i2c_ioc_init(void)
  90{
  91        force_ones = FORCE_ONES | SCL | SDA;
  92
  93        return i2c_bit_add_numbered_bus(&ioc_ops);
  94}
  95
  96module_init(i2c_ioc_init);
  97