treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157
[sfrench/cifs-2.6.git] / drivers / i2c / busses / i2c-nforce2-s4985.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * i2c-nforce2-s4985.c - i2c-nforce2 extras for the Tyan S4985 motherboard
4  *
5  * Copyright (C) 2008 Jean Delvare <jdelvare@suse.de>
6  */
7
8 /*
9  * We select the channels by sending commands to the Philips
10  * PCA9556 chip at I2C address 0x18. The main adapter is used for
11  * the non-multiplexed part of the bus, and 4 virtual adapters
12  * are defined for the multiplexed addresses: 0x50-0x53 (memory
13  * module EEPROM) located on channels 1-4. We define one virtual
14  * adapter per CPU, which corresponds to one multiplexed channel:
15  *   CPU0: virtual adapter 1, channel 1
16  *   CPU1: virtual adapter 2, channel 2
17  *   CPU2: virtual adapter 3, channel 3
18  *   CPU3: virtual adapter 4, channel 4
19  */
20
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/slab.h>
24 #include <linux/init.h>
25 #include <linux/i2c.h>
26 #include <linux/mutex.h>
27
28 extern struct i2c_adapter *nforce2_smbus;
29
30 static struct i2c_adapter *s4985_adapter;
31 static struct i2c_algorithm *s4985_algo;
32
33 /* Wrapper access functions for multiplexed SMBus */
34 static DEFINE_MUTEX(nforce2_lock);
35
36 static s32 nforce2_access_virt0(struct i2c_adapter *adap, u16 addr,
37                                 unsigned short flags, char read_write,
38                                 u8 command, int size,
39                                 union i2c_smbus_data *data)
40 {
41         int error;
42
43         /* We exclude the multiplexed addresses */
44         if ((addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
45          || addr == 0x18)
46                 return -ENXIO;
47
48         mutex_lock(&nforce2_lock);
49         error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
50                                                 command, size, data);
51         mutex_unlock(&nforce2_lock);
52
53         return error;
54 }
55
56 /* We remember the last used channels combination so as to only switch
57    channels when it is really needed. This greatly reduces the SMBus
58    overhead, but also assumes that nobody will be writing to the PCA9556
59    in our back. */
60 static u8 last_channels;
61
62 static inline s32 nforce2_access_channel(struct i2c_adapter *adap, u16 addr,
63                                          unsigned short flags, char read_write,
64                                          u8 command, int size,
65                                          union i2c_smbus_data *data,
66                                          u8 channels)
67 {
68         int error;
69
70         /* We exclude the non-multiplexed addresses */
71         if ((addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
72                 return -ENXIO;
73
74         mutex_lock(&nforce2_lock);
75         if (last_channels != channels) {
76                 union i2c_smbus_data mplxdata;
77                 mplxdata.byte = channels;
78
79                 error = nforce2_smbus->algo->smbus_xfer(adap, 0x18, 0,
80                                                         I2C_SMBUS_WRITE, 0x01,
81                                                         I2C_SMBUS_BYTE_DATA,
82                                                         &mplxdata);
83                 if (error)
84                         goto UNLOCK;
85                 last_channels = channels;
86         }
87         error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
88                                                 command, size, data);
89
90 UNLOCK:
91         mutex_unlock(&nforce2_lock);
92         return error;
93 }
94
95 static s32 nforce2_access_virt1(struct i2c_adapter *adap, u16 addr,
96                                 unsigned short flags, char read_write,
97                                 u8 command, int size,
98                                 union i2c_smbus_data *data)
99 {
100         /* CPU0: channel 1 enabled */
101         return nforce2_access_channel(adap, addr, flags, read_write, command,
102                                       size, data, 0x02);
103 }
104
105 static s32 nforce2_access_virt2(struct i2c_adapter *adap, u16 addr,
106                                 unsigned short flags, char read_write,
107                                 u8 command, int size,
108                                 union i2c_smbus_data *data)
109 {
110         /* CPU1: channel 2 enabled */
111         return nforce2_access_channel(adap, addr, flags, read_write, command,
112                                       size, data, 0x04);
113 }
114
115 static s32 nforce2_access_virt3(struct i2c_adapter *adap, u16 addr,
116                                 unsigned short flags, char read_write,
117                                 u8 command, int size,
118                                 union i2c_smbus_data *data)
119 {
120         /* CPU2: channel 3 enabled */
121         return nforce2_access_channel(adap, addr, flags, read_write, command,
122                                       size, data, 0x08);
123 }
124
125 static s32 nforce2_access_virt4(struct i2c_adapter *adap, u16 addr,
126                                 unsigned short flags, char read_write,
127                                 u8 command, int size,
128                                 union i2c_smbus_data *data)
129 {
130         /* CPU3: channel 4 enabled */
131         return nforce2_access_channel(adap, addr, flags, read_write, command,
132                                       size, data, 0x10);
133 }
134
135 static int __init nforce2_s4985_init(void)
136 {
137         int i, error;
138         union i2c_smbus_data ioconfig;
139
140         if (!nforce2_smbus)
141                 return -ENODEV;
142
143         /* Configure the PCA9556 multiplexer */
144         ioconfig.byte = 0x00; /* All I/O to output mode */
145         error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
146                                I2C_SMBUS_BYTE_DATA, &ioconfig);
147         if (error) {
148                 dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
149                 error = -EIO;
150                 goto ERROR0;
151         }
152
153         /* Unregister physical bus */
154         i2c_del_adapter(nforce2_smbus);
155
156         printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n");
157         /* Define the 5 virtual adapters and algorithms structures */
158         s4985_adapter = kcalloc(5, sizeof(struct i2c_adapter), GFP_KERNEL);
159         if (!s4985_adapter) {
160                 error = -ENOMEM;
161                 goto ERROR1;
162         }
163         s4985_algo = kcalloc(5, sizeof(struct i2c_algorithm), GFP_KERNEL);
164         if (!s4985_algo) {
165                 error = -ENOMEM;
166                 goto ERROR2;
167         }
168
169         /* Fill in the new structures */
170         s4985_algo[0] = *(nforce2_smbus->algo);
171         s4985_algo[0].smbus_xfer = nforce2_access_virt0;
172         s4985_adapter[0] = *nforce2_smbus;
173         s4985_adapter[0].algo = s4985_algo;
174         s4985_adapter[0].dev.parent = nforce2_smbus->dev.parent;
175         for (i = 1; i < 5; i++) {
176                 s4985_algo[i] = *(nforce2_smbus->algo);
177                 s4985_adapter[i] = *nforce2_smbus;
178                 snprintf(s4985_adapter[i].name, sizeof(s4985_adapter[i].name),
179                          "SMBus nForce2 adapter (CPU%d)", i - 1);
180                 s4985_adapter[i].algo = s4985_algo + i;
181                 s4985_adapter[i].dev.parent = nforce2_smbus->dev.parent;
182         }
183         s4985_algo[1].smbus_xfer = nforce2_access_virt1;
184         s4985_algo[2].smbus_xfer = nforce2_access_virt2;
185         s4985_algo[3].smbus_xfer = nforce2_access_virt3;
186         s4985_algo[4].smbus_xfer = nforce2_access_virt4;
187
188         /* Register virtual adapters */
189         for (i = 0; i < 5; i++) {
190                 error = i2c_add_adapter(s4985_adapter + i);
191                 if (error) {
192                         printk(KERN_ERR "i2c-nforce2-s4985: "
193                                "Virtual adapter %d registration "
194                                "failed, module not inserted\n", i);
195                         for (i--; i >= 0; i--)
196                                 i2c_del_adapter(s4985_adapter + i);
197                         goto ERROR3;
198                 }
199         }
200
201         return 0;
202
203 ERROR3:
204         kfree(s4985_algo);
205         s4985_algo = NULL;
206 ERROR2:
207         kfree(s4985_adapter);
208         s4985_adapter = NULL;
209 ERROR1:
210         /* Restore physical bus */
211         i2c_add_adapter(nforce2_smbus);
212 ERROR0:
213         return error;
214 }
215
216 static void __exit nforce2_s4985_exit(void)
217 {
218         if (s4985_adapter) {
219                 int i;
220
221                 for (i = 0; i < 5; i++)
222                         i2c_del_adapter(s4985_adapter+i);
223                 kfree(s4985_adapter);
224                 s4985_adapter = NULL;
225         }
226         kfree(s4985_algo);
227         s4985_algo = NULL;
228
229         /* Restore physical bus */
230         if (i2c_add_adapter(nforce2_smbus))
231                 printk(KERN_ERR "i2c-nforce2-s4985: "
232                        "Physical bus restoration failed\n");
233 }
234
235 MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
236 MODULE_DESCRIPTION("S4985 SMBus multiplexing");
237 MODULE_LICENSE("GPL");
238
239 module_init(nforce2_s4985_init);
240 module_exit(nforce2_s4985_exit);