drm/panel: simple: add Multi-Inno Technology MI0700A2T-30
[drm/drm-misc.git] / drivers / i2c / busses / i2c-cgbc.c
blobf054d167ac47600fda88434967499ba7158474b2
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Congatec Board Controller I2C busses driver
5 * Copyright (C) 2024 Bootlin
6 * Author: Thomas Richard <thomas.richard@bootlin.com>
7 */
9 #include <linux/i2c.h>
10 #include <linux/iopoll.h>
11 #include <linux/mfd/cgbc.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
15 #define CGBC_I2C_PRIMARY_BUS_ID 0
16 #define CGBC_I2C_PM_BUS_ID 4
18 #define CGBC_I2C_CMD_START 0x40
19 #define CGBC_I2C_CMD_STAT 0x48
20 #define CGBC_I2C_CMD_DATA 0x50
21 #define CGBC_I2C_CMD_SPEED 0x58
23 #define CGBC_I2C_STAT_IDL 0x00
24 #define CGBC_I2C_STAT_DAT 0x01
25 #define CGBC_I2C_STAT_BUSY 0x02
27 #define CGBC_I2C_START 0x80
28 #define CGBC_I2C_STOP 0x40
30 #define CGBC_I2C_LAST_ACK 0x80 /* send ACK on last read byte */
33 * Reference code defines 1kHz as min freq and 6.1MHz as max freq.
34 * But in practice, the board controller limits the frequency to 1MHz, and the
35 * 1kHz is not functional (minimal working freq is 50kHz).
36 * So use these values as limits.
38 #define CGBC_I2C_FREQ_MIN_HZ 50000 /* 50 kHz */
39 #define CGBC_I2C_FREQ_MAX_HZ 1000000 /* 1 MHz */
41 #define CGBC_I2C_FREQ_UNIT_1KHZ 0x40
42 #define CGBC_I2C_FREQ_UNIT_10KHZ 0x80
43 #define CGBC_I2C_FREQ_UNIT_100KHZ 0xC0
45 #define CGBC_I2C_FREQ_UNIT_MASK 0xC0
46 #define CGBC_I2C_FREQ_VALUE_MASK 0x3F
48 #define CGBC_I2C_READ_MAX_LEN 31
49 #define CGBC_I2C_WRITE_MAX_LEN 32
51 #define CGBC_I2C_CMD_HEADER_SIZE 4
52 #define CGBC_I2C_CMD_SIZE (CGBC_I2C_CMD_HEADER_SIZE + CGBC_I2C_WRITE_MAX_LEN)
54 enum cgbc_i2c_state {
55 CGBC_I2C_STATE_DONE = 0,
56 CGBC_I2C_STATE_INIT,
57 CGBC_I2C_STATE_START,
58 CGBC_I2C_STATE_READ,
59 CGBC_I2C_STATE_WRITE,
60 CGBC_I2C_STATE_ERROR,
63 struct i2c_algo_cgbc_data {
64 u8 bus_id;
65 unsigned long read_maxtime_us;
68 struct cgbc_i2c_data {
69 struct device *dev;
70 struct cgbc_device_data *cgbc;
71 struct i2c_adapter adap;
72 struct i2c_msg *msg;
73 int nmsgs;
74 int pos;
75 enum cgbc_i2c_state state;
78 struct cgbc_i2c_transfer {
79 u8 bus_id;
80 bool start;
81 bool stop;
82 bool last_ack;
83 u8 read;
84 u8 write;
85 u8 addr;
86 u8 data[CGBC_I2C_WRITE_MAX_LEN];
89 static u8 cgbc_i2c_freq_to_reg(unsigned int bus_frequency)
91 u8 reg;
93 if (bus_frequency <= 10000)
94 reg = CGBC_I2C_FREQ_UNIT_1KHZ | (bus_frequency / 1000);
95 else if (bus_frequency <= 100000)
96 reg = CGBC_I2C_FREQ_UNIT_10KHZ | (bus_frequency / 10000);
97 else
98 reg = CGBC_I2C_FREQ_UNIT_100KHZ | (bus_frequency / 100000);
100 return reg;
103 static unsigned int cgbc_i2c_reg_to_freq(u8 reg)
105 unsigned int freq = reg & CGBC_I2C_FREQ_VALUE_MASK;
106 u8 unit = reg & CGBC_I2C_FREQ_UNIT_MASK;
108 if (unit == CGBC_I2C_FREQ_UNIT_100KHZ)
109 return freq * 100000;
110 else if (unit == CGBC_I2C_FREQ_UNIT_10KHZ)
111 return freq * 10000;
112 else
113 return freq * 1000;
116 static int cgbc_i2c_get_status(struct i2c_adapter *adap)
118 struct i2c_algo_cgbc_data *algo_data = adap->algo_data;
119 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap);
120 struct cgbc_device_data *cgbc = i2c->cgbc;
121 u8 cmd = CGBC_I2C_CMD_STAT | algo_data->bus_id;
122 u8 status;
123 int ret;
125 ret = cgbc_command(cgbc, &cmd, sizeof(cmd), NULL, 0, &status);
126 if (ret)
127 return ret;
129 return status;
132 static int cgbc_i2c_set_frequency(struct i2c_adapter *adap,
133 unsigned int bus_frequency)
135 struct i2c_algo_cgbc_data *algo_data = adap->algo_data;
136 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap);
137 struct cgbc_device_data *cgbc = i2c->cgbc;
138 u8 cmd[2], data;
139 int ret;
141 if (bus_frequency > CGBC_I2C_FREQ_MAX_HZ ||
142 bus_frequency < CGBC_I2C_FREQ_MIN_HZ) {
143 dev_info(i2c->dev, "invalid frequency %u, using default\n", bus_frequency);
144 bus_frequency = I2C_MAX_STANDARD_MODE_FREQ;
147 cmd[0] = CGBC_I2C_CMD_SPEED | algo_data->bus_id;
148 cmd[1] = cgbc_i2c_freq_to_reg(bus_frequency);
150 ret = cgbc_command(cgbc, &cmd, sizeof(cmd), &data, 1, NULL);
151 if (ret)
152 return dev_err_probe(i2c->dev, ret,
153 "Failed to initialize I2C bus %s",
154 adap->name);
156 cmd[1] = 0x00;
158 ret = cgbc_command(cgbc, &cmd, sizeof(cmd), &data, 1, NULL);
159 if (ret)
160 return dev_err_probe(i2c->dev, ret,
161 "Failed to get I2C bus frequency");
163 bus_frequency = cgbc_i2c_reg_to_freq(data);
165 dev_dbg(i2c->dev, "%s is running at %d Hz\n", adap->name, bus_frequency);
168 * The read_maxtime_us variable represents the maximum time to wait
169 * for data during a read operation. The maximum amount of data that
170 * can be read by a command is CGBC_I2C_READ_MAX_LEN.
171 * Therefore, calculate the max time to properly size the timeout.
173 algo_data->read_maxtime_us = (BITS_PER_BYTE + 1) * CGBC_I2C_READ_MAX_LEN
174 * USEC_PER_SEC / bus_frequency;
176 return 0;
179 static unsigned int cgbc_i2c_xfer_to_cmd(struct cgbc_i2c_transfer xfer, u8 *cmd)
181 int i = 0;
183 cmd[i++] = CGBC_I2C_CMD_START | xfer.bus_id;
185 cmd[i] = (xfer.start) ? CGBC_I2C_START : 0x00;
186 if (xfer.stop)
187 cmd[i] |= CGBC_I2C_STOP;
188 cmd[i++] |= (xfer.start) ? xfer.write + 1 : xfer.write;
190 cmd[i++] = (xfer.last_ack) ? (xfer.read | CGBC_I2C_LAST_ACK) : xfer.read;
192 if (xfer.start)
193 cmd[i++] = xfer.addr;
195 if (xfer.write > 0)
196 memcpy(&cmd[i], &xfer.data, xfer.write);
198 return i + xfer.write;
201 static int cgbc_i2c_xfer_msg(struct i2c_adapter *adap)
203 struct i2c_algo_cgbc_data *algo_data = adap->algo_data;
204 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap);
205 struct cgbc_device_data *cgbc = i2c->cgbc;
206 struct i2c_msg *msg = i2c->msg;
207 u8 cmd[CGBC_I2C_CMD_SIZE];
208 int ret, max_len, len, i;
209 unsigned int cmd_len;
210 u8 cmd_data;
212 struct cgbc_i2c_transfer xfer = {
213 .bus_id = algo_data->bus_id,
214 .addr = i2c_8bit_addr_from_msg(msg),
217 if (i2c->state == CGBC_I2C_STATE_DONE)
218 return 0;
220 ret = cgbc_i2c_get_status(adap);
222 if (ret == CGBC_I2C_STAT_BUSY)
223 return -EBUSY;
224 else if (ret < 0)
225 goto err;
227 if (i2c->state == CGBC_I2C_STATE_INIT ||
228 (i2c->state == CGBC_I2C_STATE_WRITE && msg->flags & I2C_M_RD))
229 xfer.start = true;
231 i2c->state = (msg->flags & I2C_M_RD) ? CGBC_I2C_STATE_READ : CGBC_I2C_STATE_WRITE;
233 max_len = (i2c->state == CGBC_I2C_STATE_READ) ?
234 CGBC_I2C_READ_MAX_LEN : CGBC_I2C_WRITE_MAX_LEN;
236 if (msg->len - i2c->pos > max_len) {
237 len = max_len;
238 } else {
239 len = msg->len - i2c->pos;
241 if (i2c->nmsgs == 1)
242 xfer.stop = true;
245 if (i2c->state == CGBC_I2C_STATE_WRITE) {
246 xfer.write = len;
247 xfer.read = 0;
249 for (i = 0; i < len; i++)
250 xfer.data[i] = msg->buf[i2c->pos + i];
252 cmd_len = cgbc_i2c_xfer_to_cmd(xfer, &cmd[0]);
254 ret = cgbc_command(cgbc, &cmd, cmd_len, NULL, 0, NULL);
255 if (ret)
256 goto err;
257 } else if (i2c->state == CGBC_I2C_STATE_READ) {
258 xfer.write = 0;
259 xfer.read = len;
261 if (i2c->nmsgs > 1 || msg->len - i2c->pos > max_len)
262 xfer.read |= CGBC_I2C_LAST_ACK;
264 cmd_len = cgbc_i2c_xfer_to_cmd(xfer, &cmd[0]);
265 ret = cgbc_command(cgbc, &cmd, cmd_len, NULL, 0, NULL);
266 if (ret)
267 goto err;
269 ret = read_poll_timeout(cgbc_i2c_get_status, ret,
270 ret != CGBC_I2C_STAT_BUSY, 0,
271 2 * algo_data->read_maxtime_us, false, adap);
272 if (ret < 0)
273 goto err;
275 cmd_data = CGBC_I2C_CMD_DATA | algo_data->bus_id;
276 ret = cgbc_command(cgbc, &cmd_data, sizeof(cmd_data),
277 msg->buf + i2c->pos, len, NULL);
278 if (ret)
279 goto err;
282 if (len == (msg->len - i2c->pos)) {
283 i2c->msg++;
284 i2c->nmsgs--;
285 i2c->pos = 0;
286 } else {
287 i2c->pos += len;
290 if (i2c->nmsgs == 0)
291 i2c->state = CGBC_I2C_STATE_DONE;
293 return 0;
295 err:
296 i2c->state = CGBC_I2C_STATE_ERROR;
297 return ret;
300 static int cgbc_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
301 int num)
303 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap);
304 unsigned long timeout = jiffies + HZ;
305 int ret;
307 i2c->state = CGBC_I2C_STATE_INIT;
308 i2c->msg = msgs;
309 i2c->nmsgs = num;
310 i2c->pos = 0;
312 while (time_before(jiffies, timeout)) {
313 ret = cgbc_i2c_xfer_msg(adap);
314 if (i2c->state == CGBC_I2C_STATE_DONE)
315 return num;
317 if (i2c->state == CGBC_I2C_STATE_ERROR)
318 return ret;
320 if (ret == 0)
321 timeout = jiffies + HZ;
324 i2c->state = CGBC_I2C_STATE_ERROR;
325 return -ETIMEDOUT;
328 static u32 cgbc_i2c_func(struct i2c_adapter *adap)
330 return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~(I2C_FUNC_SMBUS_QUICK));
333 static const struct i2c_algorithm cgbc_i2c_algorithm = {
334 .master_xfer = cgbc_i2c_xfer,
335 .functionality = cgbc_i2c_func,
338 static struct i2c_algo_cgbc_data cgbc_i2c_algo_data[] = {
339 { .bus_id = CGBC_I2C_PRIMARY_BUS_ID },
340 { .bus_id = CGBC_I2C_PM_BUS_ID },
343 static const struct i2c_adapter cgbc_i2c_adapter[] = {
345 .owner = THIS_MODULE,
346 .name = "Congatec General Purpose I2C adapter",
347 .class = I2C_CLASS_DEPRECATED,
348 .algo = &cgbc_i2c_algorithm,
349 .algo_data = &cgbc_i2c_algo_data[0],
350 .nr = -1,
353 .owner = THIS_MODULE,
354 .name = "Congatec Power Management I2C adapter",
355 .class = I2C_CLASS_DEPRECATED,
356 .algo = &cgbc_i2c_algorithm,
357 .algo_data = &cgbc_i2c_algo_data[1],
358 .nr = -1,
362 static int cgbc_i2c_probe(struct platform_device *pdev)
364 struct cgbc_device_data *cgbc = dev_get_drvdata(pdev->dev.parent);
365 struct cgbc_i2c_data *i2c;
366 int ret;
368 i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
369 if (!i2c)
370 return -ENOMEM;
372 i2c->cgbc = cgbc;
373 i2c->dev = &pdev->dev;
374 i2c->adap = cgbc_i2c_adapter[pdev->id];
375 i2c->adap.dev.parent = i2c->dev;
376 i2c_set_adapdata(&i2c->adap, i2c);
377 platform_set_drvdata(pdev, i2c);
379 ret = cgbc_i2c_set_frequency(&i2c->adap, I2C_MAX_STANDARD_MODE_FREQ);
380 if (ret)
381 return ret;
383 return i2c_add_numbered_adapter(&i2c->adap);
386 static void cgbc_i2c_remove(struct platform_device *pdev)
388 struct cgbc_i2c_data *i2c = platform_get_drvdata(pdev);
390 i2c_del_adapter(&i2c->adap);
393 static struct platform_driver cgbc_i2c_driver = {
394 .driver = {
395 .name = "cgbc-i2c",
397 .probe = cgbc_i2c_probe,
398 .remove = cgbc_i2c_remove,
401 module_platform_driver(cgbc_i2c_driver);
403 MODULE_DESCRIPTION("Congatec Board Controller I2C Driver");
404 MODULE_AUTHOR("Thomas Richard <thomas.richard@bootlin.com>");
405 MODULE_LICENSE("GPL");
406 MODULE_ALIAS("platform:cgbc_i2c");