0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/i2c.h>
0012 #include <linux/i2c-algo-bit.h>
0013 #include <linux/io.h>
0014
0015 #include <mach/hardware.h>
0016 #include <asm/hardware/ioc.h>
0017
0018 #define FORCE_ONES 0xdc
0019 #define SCL 0x02
0020 #define SDA 0x01
0021
0022
0023
0024
0025
0026
0027
0028 static u_int force_ones;
0029
0030 static void ioc_setscl(void *data, int state)
0031 {
0032 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
0033 u_int ones = force_ones;
0034
0035 if (state)
0036 ones |= SCL;
0037 else
0038 ones &= ~SCL;
0039
0040 force_ones = ones;
0041
0042 ioc_writeb(ioc_control | ones, IOC_CONTROL);
0043 }
0044
0045 static void ioc_setsda(void *data, int state)
0046 {
0047 u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
0048 u_int ones = force_ones;
0049
0050 if (state)
0051 ones |= SDA;
0052 else
0053 ones &= ~SDA;
0054
0055 force_ones = ones;
0056
0057 ioc_writeb(ioc_control | ones, IOC_CONTROL);
0058 }
0059
0060 static int ioc_getscl(void *data)
0061 {
0062 return (ioc_readb(IOC_CONTROL) & SCL) != 0;
0063 }
0064
0065 static int ioc_getsda(void *data)
0066 {
0067 return (ioc_readb(IOC_CONTROL) & SDA) != 0;
0068 }
0069
0070 static struct i2c_algo_bit_data ioc_data = {
0071 .setsda = ioc_setsda,
0072 .setscl = ioc_setscl,
0073 .getsda = ioc_getsda,
0074 .getscl = ioc_getscl,
0075 .udelay = 80,
0076 .timeout = HZ,
0077 };
0078
0079 static struct i2c_adapter ioc_ops = {
0080 .nr = 0,
0081 .name = "ioc",
0082 .algo_data = &ioc_data,
0083 };
0084
0085 static int __init i2c_ioc_init(void)
0086 {
0087 force_ones = FORCE_ONES | SCL | SDA;
0088
0089 return i2c_bit_add_numbered_bus(&ioc_ops);
0090 }
0091
0092 module_init(i2c_ioc_init);
0093
0094 MODULE_AUTHOR("Russell King <linux@armlinux.org.uk>");
0095 MODULE_DESCRIPTION("ARM IOC/IOMD i2c driver");
0096 MODULE_LICENSE("GPL v2");