Merge with /home/shaggy/git/linus-clean/
[linux-2.6] / drivers / i2c / busses / i2c-stub.c
1 /*
2     i2c-stub.c - Part of lm_sensors, Linux kernel modules for hardware
3               monitoring
4
5     Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
6
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #define DEBUG 1
23
24 #include <linux/init.h>
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/errno.h>
28 #include <linux/i2c.h>
29
30 static u8  stub_pointer;
31 static u8  stub_bytes[256];
32 static u16 stub_words[256];
33
34 /* Return -1 on error. */
35 static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
36         char read_write, u8 command, int size, union i2c_smbus_data * data)
37 {
38         s32 ret;
39
40         switch (size) {
41
42         case I2C_SMBUS_QUICK:
43                 dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr);
44                 ret = 0;
45                 break;
46
47         case I2C_SMBUS_BYTE:
48                 if (read_write == I2C_SMBUS_WRITE) {
49                         stub_pointer = command;
50                         dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
51                                         "wrote 0x%02x.\n",
52                                         addr, command);
53                 } else {
54                         data->byte = stub_bytes[stub_pointer++];
55                         dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
56                                         "read  0x%02x.\n",
57                                         addr, data->byte);
58                 }
59
60                 ret = 0;
61                 break;
62
63         case I2C_SMBUS_BYTE_DATA:
64                 if (read_write == I2C_SMBUS_WRITE) {
65                         stub_bytes[command] = data->byte;
66                         dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
67                                         "wrote 0x%02x at 0x%02x.\n",
68                                         addr, data->byte, command);
69                 } else {
70                         data->byte = stub_bytes[command];
71                         dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
72                                         "read  0x%02x at 0x%02x.\n",
73                                         addr, data->byte, command);
74                 }
75                 stub_pointer = command + 1;
76
77                 ret = 0;
78                 break;
79
80         case I2C_SMBUS_WORD_DATA:
81                 if (read_write == I2C_SMBUS_WRITE) {
82                         stub_words[command] = data->word;
83                         dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
84                                         "wrote 0x%04x at 0x%02x.\n",
85                                         addr, data->word, command);
86                 } else {
87                         data->word = stub_words[command];
88                         dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
89                                         "read  0x%04x at 0x%02x.\n",
90                                         addr, data->word, command);
91                 }
92
93                 ret = 0;
94                 break;
95
96         default:
97                 dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
98                 ret = -1;
99                 break;
100         } /* switch (size) */
101
102         return ret;
103 }
104
105 static u32 stub_func(struct i2c_adapter *adapter)
106 {
107         return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
108                 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
109 }
110
111 static struct i2c_algorithm smbus_algorithm = {
112         .name           = "Non-I2C SMBus adapter",
113         .id             = I2C_ALGO_SMBUS,
114         .functionality  = stub_func,
115         .smbus_xfer     = stub_xfer,
116 };
117
118 static struct i2c_adapter stub_adapter = {
119         .owner          = THIS_MODULE,
120         .class          = I2C_CLASS_HWMON,
121         .algo           = &smbus_algorithm,
122         .name           = "SMBus stub driver",
123 };
124
125 static int __init i2c_stub_init(void)
126 {
127         printk(KERN_INFO "i2c-stub loaded\n");
128         return i2c_add_adapter(&stub_adapter);
129 }
130
131 static void __exit i2c_stub_exit(void)
132 {
133         i2c_del_adapter(&stub_adapter);
134 }
135
136 MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
137 MODULE_DESCRIPTION("I2C stub driver");
138 MODULE_LICENSE("GPL");
139
140 module_init(i2c_stub_init);
141 module_exit(i2c_stub_exit);
142