0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/module.h>
0022 #include <linux/kernel.h>
0023 #include <linux/slab.h>
0024 #include <linux/init.h>
0025 #include <linux/i2c.h>
0026 #include <linux/mutex.h>
0027
0028 extern struct i2c_adapter *nforce2_smbus;
0029
0030 static struct i2c_adapter *s4985_adapter;
0031 static struct i2c_algorithm *s4985_algo;
0032
0033
0034 static DEFINE_MUTEX(nforce2_lock);
0035
0036 static s32 nforce2_access_virt0(struct i2c_adapter *adap, u16 addr,
0037 unsigned short flags, char read_write,
0038 u8 command, int size,
0039 union i2c_smbus_data *data)
0040 {
0041 int error;
0042
0043
0044 if ((addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
0045 || addr == 0x18)
0046 return -ENXIO;
0047
0048 mutex_lock(&nforce2_lock);
0049 error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
0050 command, size, data);
0051 mutex_unlock(&nforce2_lock);
0052
0053 return error;
0054 }
0055
0056
0057
0058
0059
0060 static u8 last_channels;
0061
0062 static inline s32 nforce2_access_channel(struct i2c_adapter *adap, u16 addr,
0063 unsigned short flags, char read_write,
0064 u8 command, int size,
0065 union i2c_smbus_data *data,
0066 u8 channels)
0067 {
0068 int error;
0069
0070
0071 if ((addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
0072 return -ENXIO;
0073
0074 mutex_lock(&nforce2_lock);
0075 if (last_channels != channels) {
0076 union i2c_smbus_data mplxdata;
0077 mplxdata.byte = channels;
0078
0079 error = nforce2_smbus->algo->smbus_xfer(adap, 0x18, 0,
0080 I2C_SMBUS_WRITE, 0x01,
0081 I2C_SMBUS_BYTE_DATA,
0082 &mplxdata);
0083 if (error)
0084 goto UNLOCK;
0085 last_channels = channels;
0086 }
0087 error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
0088 command, size, data);
0089
0090 UNLOCK:
0091 mutex_unlock(&nforce2_lock);
0092 return error;
0093 }
0094
0095 static s32 nforce2_access_virt1(struct i2c_adapter *adap, u16 addr,
0096 unsigned short flags, char read_write,
0097 u8 command, int size,
0098 union i2c_smbus_data *data)
0099 {
0100
0101 return nforce2_access_channel(adap, addr, flags, read_write, command,
0102 size, data, 0x02);
0103 }
0104
0105 static s32 nforce2_access_virt2(struct i2c_adapter *adap, u16 addr,
0106 unsigned short flags, char read_write,
0107 u8 command, int size,
0108 union i2c_smbus_data *data)
0109 {
0110
0111 return nforce2_access_channel(adap, addr, flags, read_write, command,
0112 size, data, 0x04);
0113 }
0114
0115 static s32 nforce2_access_virt3(struct i2c_adapter *adap, u16 addr,
0116 unsigned short flags, char read_write,
0117 u8 command, int size,
0118 union i2c_smbus_data *data)
0119 {
0120
0121 return nforce2_access_channel(adap, addr, flags, read_write, command,
0122 size, data, 0x08);
0123 }
0124
0125 static s32 nforce2_access_virt4(struct i2c_adapter *adap, u16 addr,
0126 unsigned short flags, char read_write,
0127 u8 command, int size,
0128 union i2c_smbus_data *data)
0129 {
0130
0131 return nforce2_access_channel(adap, addr, flags, read_write, command,
0132 size, data, 0x10);
0133 }
0134
0135 static int __init nforce2_s4985_init(void)
0136 {
0137 int i, error;
0138 union i2c_smbus_data ioconfig;
0139
0140 if (!nforce2_smbus)
0141 return -ENODEV;
0142
0143
0144 ioconfig.byte = 0x00;
0145 error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
0146 I2C_SMBUS_BYTE_DATA, &ioconfig);
0147 if (error) {
0148 dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
0149 error = -EIO;
0150 goto ERROR0;
0151 }
0152
0153
0154 i2c_del_adapter(nforce2_smbus);
0155
0156 printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n");
0157
0158 s4985_adapter = kcalloc(5, sizeof(struct i2c_adapter), GFP_KERNEL);
0159 if (!s4985_adapter) {
0160 error = -ENOMEM;
0161 goto ERROR1;
0162 }
0163 s4985_algo = kcalloc(5, sizeof(struct i2c_algorithm), GFP_KERNEL);
0164 if (!s4985_algo) {
0165 error = -ENOMEM;
0166 goto ERROR2;
0167 }
0168
0169
0170 s4985_algo[0] = *(nforce2_smbus->algo);
0171 s4985_algo[0].smbus_xfer = nforce2_access_virt0;
0172 s4985_adapter[0] = *nforce2_smbus;
0173 s4985_adapter[0].algo = s4985_algo;
0174 s4985_adapter[0].dev.parent = nforce2_smbus->dev.parent;
0175 for (i = 1; i < 5; i++) {
0176 s4985_algo[i] = *(nforce2_smbus->algo);
0177 s4985_adapter[i] = *nforce2_smbus;
0178 snprintf(s4985_adapter[i].name, sizeof(s4985_adapter[i].name),
0179 "SMBus nForce2 adapter (CPU%d)", i - 1);
0180 s4985_adapter[i].algo = s4985_algo + i;
0181 s4985_adapter[i].dev.parent = nforce2_smbus->dev.parent;
0182 }
0183 s4985_algo[1].smbus_xfer = nforce2_access_virt1;
0184 s4985_algo[2].smbus_xfer = nforce2_access_virt2;
0185 s4985_algo[3].smbus_xfer = nforce2_access_virt3;
0186 s4985_algo[4].smbus_xfer = nforce2_access_virt4;
0187
0188
0189 for (i = 0; i < 5; i++) {
0190 error = i2c_add_adapter(s4985_adapter + i);
0191 if (error) {
0192 printk(KERN_ERR "i2c-nforce2-s4985: "
0193 "Virtual adapter %d registration "
0194 "failed, module not inserted\n", i);
0195 for (i--; i >= 0; i--)
0196 i2c_del_adapter(s4985_adapter + i);
0197 goto ERROR3;
0198 }
0199 }
0200
0201 return 0;
0202
0203 ERROR3:
0204 kfree(s4985_algo);
0205 s4985_algo = NULL;
0206 ERROR2:
0207 kfree(s4985_adapter);
0208 s4985_adapter = NULL;
0209 ERROR1:
0210
0211 i2c_add_adapter(nforce2_smbus);
0212 ERROR0:
0213 return error;
0214 }
0215
0216 static void __exit nforce2_s4985_exit(void)
0217 {
0218 if (s4985_adapter) {
0219 int i;
0220
0221 for (i = 0; i < 5; i++)
0222 i2c_del_adapter(s4985_adapter+i);
0223 kfree(s4985_adapter);
0224 s4985_adapter = NULL;
0225 }
0226 kfree(s4985_algo);
0227 s4985_algo = NULL;
0228
0229
0230 if (i2c_add_adapter(nforce2_smbus))
0231 printk(KERN_ERR "i2c-nforce2-s4985: "
0232 "Physical bus restoration failed\n");
0233 }
0234
0235 MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
0236 MODULE_DESCRIPTION("S4985 SMBus multiplexing");
0237 MODULE_LICENSE("GPL");
0238
0239 module_init(nforce2_s4985_init);
0240 module_exit(nforce2_s4985_exit);