Lines Matching +full:i2c +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Congatec Board Controller I2C busses driver
9 #include <linux/i2c.h>
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).
39 #define CGBC_I2C_FREQ_MAX_HZ 1000000 /* 1 MHz */
118 struct i2c_algo_cgbc_data *algo_data = adap->algo_data; in cgbc_i2c_get_status()
119 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap); in cgbc_i2c_get_status() local
120 struct cgbc_device_data *cgbc = i2c->cgbc; in cgbc_i2c_get_status()
121 u8 cmd = CGBC_I2C_CMD_STAT | algo_data->bus_id; in cgbc_i2c_get_status()
135 struct i2c_algo_cgbc_data *algo_data = adap->algo_data; in cgbc_i2c_set_frequency()
136 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap); in cgbc_i2c_set_frequency() local
137 struct cgbc_device_data *cgbc = i2c->cgbc; in cgbc_i2c_set_frequency()
143 dev_info(i2c->dev, "invalid frequency %u, using default\n", bus_frequency); in cgbc_i2c_set_frequency()
147 cmd[0] = CGBC_I2C_CMD_SPEED | algo_data->bus_id; in cgbc_i2c_set_frequency()
148 cmd[1] = cgbc_i2c_freq_to_reg(bus_frequency); in cgbc_i2c_set_frequency()
150 ret = cgbc_command(cgbc, &cmd, sizeof(cmd), &data, 1, NULL); in cgbc_i2c_set_frequency()
152 return dev_err_probe(i2c->dev, ret, in cgbc_i2c_set_frequency()
153 "Failed to initialize I2C bus %s", in cgbc_i2c_set_frequency()
154 adap->name); in cgbc_i2c_set_frequency()
156 cmd[1] = 0x00; in cgbc_i2c_set_frequency()
158 ret = cgbc_command(cgbc, &cmd, sizeof(cmd), &data, 1, NULL); in cgbc_i2c_set_frequency()
160 return dev_err_probe(i2c->dev, ret, in cgbc_i2c_set_frequency()
161 "Failed to get I2C bus frequency"); in cgbc_i2c_set_frequency()
165 dev_dbg(i2c->dev, "%s is running at %d Hz\n", adap->name, bus_frequency); in cgbc_i2c_set_frequency()
173 algo_data->read_maxtime_us = (BITS_PER_BYTE + 1) * CGBC_I2C_READ_MAX_LEN in cgbc_i2c_set_frequency()
188 cmd[i++] |= (xfer.start) ? xfer.write + 1 : xfer.write; in cgbc_i2c_xfer_to_cmd()
203 struct i2c_algo_cgbc_data *algo_data = adap->algo_data; in cgbc_i2c_xfer_msg()
204 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap); in cgbc_i2c_xfer_msg() local
205 struct cgbc_device_data *cgbc = i2c->cgbc; in cgbc_i2c_xfer_msg()
206 struct i2c_msg *msg = i2c->msg; in cgbc_i2c_xfer_msg()
213 .bus_id = algo_data->bus_id, in cgbc_i2c_xfer_msg()
217 if (i2c->state == CGBC_I2C_STATE_DONE) in cgbc_i2c_xfer_msg()
223 return -EBUSY; in cgbc_i2c_xfer_msg()
227 if (i2c->state == CGBC_I2C_STATE_INIT || in cgbc_i2c_xfer_msg()
228 (i2c->state == CGBC_I2C_STATE_WRITE && msg->flags & I2C_M_RD)) in cgbc_i2c_xfer_msg()
231 i2c->state = (msg->flags & I2C_M_RD) ? CGBC_I2C_STATE_READ : CGBC_I2C_STATE_WRITE; in cgbc_i2c_xfer_msg()
233 max_len = (i2c->state == CGBC_I2C_STATE_READ) ? in cgbc_i2c_xfer_msg()
236 if (msg->len - i2c->pos > max_len) { in cgbc_i2c_xfer_msg()
239 len = msg->len - i2c->pos; in cgbc_i2c_xfer_msg()
241 if (i2c->nmsgs == 1) in cgbc_i2c_xfer_msg()
245 if (i2c->state == CGBC_I2C_STATE_WRITE) { in cgbc_i2c_xfer_msg()
250 xfer.data[i] = msg->buf[i2c->pos + i]; in cgbc_i2c_xfer_msg()
257 } else if (i2c->state == CGBC_I2C_STATE_READ) { in cgbc_i2c_xfer_msg()
261 if (i2c->nmsgs > 1 || msg->len - i2c->pos > max_len) in cgbc_i2c_xfer_msg()
271 2 * algo_data->read_maxtime_us, false, adap); in cgbc_i2c_xfer_msg()
275 cmd_data = CGBC_I2C_CMD_DATA | algo_data->bus_id; in cgbc_i2c_xfer_msg()
277 msg->buf + i2c->pos, len, NULL); in cgbc_i2c_xfer_msg()
282 if (len == (msg->len - i2c->pos)) { in cgbc_i2c_xfer_msg()
283 i2c->msg++; in cgbc_i2c_xfer_msg()
284 i2c->nmsgs--; in cgbc_i2c_xfer_msg()
285 i2c->pos = 0; in cgbc_i2c_xfer_msg()
287 i2c->pos += len; in cgbc_i2c_xfer_msg()
290 if (i2c->nmsgs == 0) in cgbc_i2c_xfer_msg()
291 i2c->state = CGBC_I2C_STATE_DONE; in cgbc_i2c_xfer_msg()
296 i2c->state = CGBC_I2C_STATE_ERROR; in cgbc_i2c_xfer_msg()
303 struct cgbc_i2c_data *i2c = i2c_get_adapdata(adap); in cgbc_i2c_xfer() local
307 i2c->state = CGBC_I2C_STATE_INIT; in cgbc_i2c_xfer()
308 i2c->msg = msgs; in cgbc_i2c_xfer()
309 i2c->nmsgs = num; in cgbc_i2c_xfer()
310 i2c->pos = 0; in cgbc_i2c_xfer()
314 if (i2c->state == CGBC_I2C_STATE_DONE) in cgbc_i2c_xfer()
317 if (i2c->state == CGBC_I2C_STATE_ERROR) in cgbc_i2c_xfer()
324 i2c->state = CGBC_I2C_STATE_ERROR; in cgbc_i2c_xfer()
325 return -ETIMEDOUT; in cgbc_i2c_xfer()
346 .name = "Congatec General Purpose I2C adapter",
350 .nr = -1,
354 .name = "Congatec Power Management I2C adapter",
357 .algo_data = &cgbc_i2c_algo_data[1],
358 .nr = -1,
364 struct cgbc_device_data *cgbc = dev_get_drvdata(pdev->dev.parent); in cgbc_i2c_probe()
365 struct cgbc_i2c_data *i2c; in cgbc_i2c_probe() local
368 i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); in cgbc_i2c_probe()
369 if (!i2c) in cgbc_i2c_probe()
370 return -ENOMEM; in cgbc_i2c_probe()
372 i2c->cgbc = cgbc; in cgbc_i2c_probe()
373 i2c->dev = &pdev->dev; in cgbc_i2c_probe()
374 i2c->adap = cgbc_i2c_adapter[pdev->id]; in cgbc_i2c_probe()
375 i2c->adap.dev.parent = i2c->dev; in cgbc_i2c_probe()
376 i2c_set_adapdata(&i2c->adap, i2c); in cgbc_i2c_probe()
377 platform_set_drvdata(pdev, i2c); in cgbc_i2c_probe()
379 ret = cgbc_i2c_set_frequency(&i2c->adap, I2C_MAX_STANDARD_MODE_FREQ); in cgbc_i2c_probe()
383 return i2c_add_numbered_adapter(&i2c->adap); in cgbc_i2c_probe()
388 struct cgbc_i2c_data *i2c = platform_get_drvdata(pdev); in cgbc_i2c_remove() local
390 i2c_del_adapter(&i2c->adap); in cgbc_i2c_remove()
395 .name = "cgbc-i2c",
403 MODULE_DESCRIPTION("Congatec Board Controller I2C Driver");