blob: b45c0e77193b2864fa98e59827b7930b1eb45c95 [file] [log] [blame]
Bharat Gooty66b0bb42020-09-24 12:29:00 +05301/*
2 * Copyright (c) 2016 - 2021, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/debug.h>
8#include <drivers/delay_timer.h>
9#include <i2c.h>
10#include <i2c_regs.h>
11#include <lib/mmio.h>
12
13#include <platform_def.h>
14
15/* Max instances */
16#define MAX_I2C 2U
17
18/* Transaction error codes defined in Master command register (0x30) */
19#define MSTR_STS_XACT_SUCCESS 0U
20#define MSTR_STS_LOST_ARB 1U
21#define MSTR_STS_NACK_FIRST_BYTE 2U
22 /* NACK on a byte other than the first byte */
23#define MSTR_STS_NACK_NON_FIRST_BYTE 3U
24
25#define MSTR_STS_TTIMEOUT_EXCEEDED 4U
26#define MSTR_STS_TX_TLOW_MEXT_EXCEEDED 5U
27#define MSTR_STS_RX_TLOW_MEXT_EXCEEDED 6U
28
29/* SMBUS protocol values defined in register 0x30 */
30#define SMBUS_PROT_QUICK_CMD 0U
31#define SMBUS_PROT_SEND_BYTE 1U
32#define SMBUS_PROT_RECV_BYTE 2U
33#define SMBUS_PROT_WR_BYTE 3U
34#define SMBUS_PROT_RD_BYTE 4U
35#define SMBUS_PROT_WR_WORD 5U
36#define SMBUS_PROT_RD_WORD 6U
37#define SMBUS_PROT_BLK_WR 7U
38#define SMBUS_PROT_BLK_RD 8U
39#define SMBUS_PROT_PROC_CALL 9U
40#define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL 10U
41
42/* Number can be changed later */
43#define BUS_BUSY_COUNT 100000U
44
45#define IPROC_I2C_INVALID_ADDR 0xFFU
46
47#define I2C_SMBUS_BLOCK_MAX 32U
48
49/*
50 * Enum to specify clock speed. The user will provide it during initialization.
51 * If needed, it can be changed dynamically
52 */
53typedef enum iproc_smb_clk_freq {
54 IPROC_SMB_SPEED_100KHz = 0,
55 IPROC_SMB_SPEED_400KHz = 1,
56 IPROC_SMB_SPEED_INVALID = 255
57} smb_clk_freq_t;
58
59/* Structure used to pass information to read/write functions. */
60struct iproc_xact_info {
61 /* Bus Identifier */
62 uint32_t bus_id;
63 /* Device Address */
64 uint8_t devaddr;
65 /* Passed by caller to send SMBus command cod e*/
66 uint8_t command;
67 /* actual data passed by the caller */
68 uint8_t *data;
69 /* Size of data buffer passed */
70 uint32_t size;
71 /* Sent by caller specifying PEC, 10-bit addresses */
72 uint16_t flags;
73 /* SMBus protocol to use to perform transaction */
74 uint8_t smb_proto;
75 /* true if command field below is valid. Otherwise, false */
76 uint32_t cmd_valid;
77};
78
79static const uintptr_t smbus_base_reg_addr[MAX_I2C] = {
80 SMBUS0_REGS_BASE,
81 SMBUS1_REGS_BASE
82};
83
84/* Function to read a value from specified register. */
85static uint32_t iproc_i2c_reg_read(uint32_t bus_id, unsigned long reg_addr)
86{
87 uint32_t val;
88 uintptr_t smbus;
89
90 smbus = smbus_base_reg_addr[bus_id];
91
92 val = mmio_read_32(smbus + reg_addr);
93 VERBOSE("i2c %u: reg %p read 0x%x\n", bus_id,
94 (void *)(smbus + reg_addr), val);
95 return val;
96}
97
98/* Function to write a value ('val') in to a specified register. */
99static void iproc_i2c_reg_write(uint32_t bus_id,
100 unsigned long reg_addr,
101 uint32_t val)
102{
103 uintptr_t smbus;
104
105 smbus = smbus_base_reg_addr[bus_id];
106
107 mmio_write_32((smbus + reg_addr), val);
108 VERBOSE("i2c %u: reg %p wrote 0x%x\n", bus_id,
109 (void *)(smbus + reg_addr), val);
110}
111
112/* Function to clear and set bits in a specified register. */
113static void iproc_i2c_reg_clearset(uint32_t bus_id,
114 unsigned long reg_addr,
115 uint32_t clear,
116 uint32_t set)
117{
118 uintptr_t smbus;
119
120 smbus = smbus_base_reg_addr[bus_id];
121
122 mmio_clrsetbits_32((smbus + reg_addr), clear, set);
123 VERBOSE("i2c %u: reg %p clear 0x%x, set 0x%x\n", bus_id,
124 (void *)(smbus + reg_addr), clear, set);
125}
126
127/* Function to dump all SMBUS register */
128#ifdef BCM_I2C_DEBUG
129static int iproc_dump_i2c_regs(uint32_t bus_id)
130{
131 uint32_t regval;
132
133 if (bus_id > MAX_I2C) {
134 return -1;
135 }
136
137 INFO("----------------------------------------------\n");
138 INFO("%s: Dumping SMBus %u registers...\n", __func__, bus_id);
139
140 regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG);
141 INFO("SMB_CFG_REG=0x%x\n", regval);
142
143 regval = iproc_i2c_reg_read(bus_id, SMB_TIMGCFG_REG);
144 INFO("SMB_TIMGCFG_REG=0x%x\n", regval);
145
146 regval = iproc_i2c_reg_read(bus_id, SMB_ADDR_REG);
147 INFO("SMB_ADDR_REG=0x%x\n", regval);
148
149 regval = iproc_i2c_reg_read(bus_id, SMB_MSTRFIFOCTL_REG);
150 INFO("SMB_MSTRFIFOCTL_REG=0x%x\n", regval);
151
152 regval = iproc_i2c_reg_read(bus_id, SMB_SLVFIFOCTL_REG);
153 INFO("SMB_SLVFIFOCTL_REG=0x%x\n", regval);
154
155 regval = iproc_i2c_reg_read(bus_id, SMB_BITBANGCTL_REG);
156 INFO("SMB_BITBANGCTL_REG=0x%x\n", regval);
157
158 regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG);
159 INFO("SMB_MSTRCMD_REG=0x%x\n", regval);
160
161 regval = iproc_i2c_reg_read(bus_id, SMB_SLVCMD_REG);
162 INFO("SMB_SLVCMD_REG=0x%x\n", regval);
163
164 regval = iproc_i2c_reg_read(bus_id, SMB_EVTEN_REG);
165 INFO("SMB_EVTEN_REG=0x%x\n", regval);
166
167 regval = iproc_i2c_reg_read(bus_id, SMB_EVTSTS_REG);
168 INFO("SMB_EVTSTS_REG=0x%x\n", regval);
169
170 regval = iproc_i2c_reg_read(bus_id, SMB_MSTRDATAWR_REG);
171 INFO("SMB_MSTRDATAWR_REG=0x%x\n", regval);
172
173 regval = iproc_i2c_reg_read(bus_id, SMB_MSTRDATARD_REG);
174 INFO("SMB_MSTRDATARD_REG=0x%x\n", regval);
175
176 regval = iproc_i2c_reg_read(bus_id, SMB_SLVDATAWR_REG);
177 INFO("SMB_SLVDATAWR_REG=0x%x\n", regval);
178
179 regval = iproc_i2c_reg_read(bus_id, SMB_SLVDATARD_REG);
180 INFO("SMB_SLVDATARD_REG=0x%x\n", regval);
181
182 INFO("----------------------------------------------\n");
183 return 0;
184}
185#endif
186
187/*
188 * Function to ensure that the previous transaction was completed before
189 * initiating a new transaction. It can also be used in polling mode to
190 * check status of completion of a command
191 */
192static int iproc_i2c_startbusy_wait(uint32_t bus_id)
193{
194 uint32_t regval;
195 uint32_t retry = 0U;
196
197 /*
198 * Check if an operation is in progress. During probe it won't be.
199 * Want to make sure that the transaction in progress is completed.
200 */
201 do {
202 udelay(1U);
203 regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG);
204 regval &= SMB_MSTRSTARTBUSYCMD_MASK;
205 if (retry++ > BUS_BUSY_COUNT) {
206 ERROR("%s: START_BUSY bit didn't clear, exiting\n",
207 __func__);
208 return -1;
209 }
210
211 } while (regval != 0U);
212
213 return 0;
214}
215
216/*
217 * This function copies data to SMBus's Tx FIFO. Valid for write transactions
218 * info: Data to copy in to Tx FIFO. For read commands, the size should be
219 * set to zero by the caller
220 */
221static void iproc_i2c_write_trans_data(struct iproc_xact_info *info)
222{
223 uint32_t regval;
224 uint8_t devaddr;
225 uint32_t i;
226 uint32_t num_data_bytes = 0U;
227
228#ifdef BCM_I2C_DEBUG
229 INFO("%s:dev_addr=0x%x,cmd_valid=%d, cmd=0x%x, size=%u proto=%d\n",
230 __func__, info->devaddr, info->cmd_valid, info->command,
231 info->size, info->smb_proto);
232#endif
233 /* Shift devaddr by 1 bit since SMBus uses the low bit[0] for R/W_n */
234 devaddr = (info->devaddr << 1);
235
236 /*
237 * Depending on the SMBus protocol, we need to write additional
238 * transaction data in to Tx FIFO. Refer to section 5.5 of SMBus spec
239 * for sequence for a transaction
240 */
241 switch (info->smb_proto) {
242 case SMBUS_PROT_RECV_BYTE:
243 /* No additional data to be written */
244 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
245 devaddr | 0x1U | SMB_MSTRWRSTS_MASK);
246 break;
247 case SMBUS_PROT_SEND_BYTE:
248 num_data_bytes = info->size;
249 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
250 devaddr);
251 break;
252 case SMBUS_PROT_RD_BYTE:
253 case SMBUS_PROT_RD_WORD:
254 case SMBUS_PROT_BLK_RD:
255 /* Write slave address with R/W~ set (bit #0) */
256 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
257 devaddr | 0x1U);
258 break;
259 case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL:
260 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
261 devaddr | 0x1U | SMB_MSTRWRSTS_MASK);
262 break;
263 case SMBUS_PROT_WR_BYTE:
264 case SMBUS_PROT_WR_WORD:
265 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
266 devaddr);
267 /*
268 * No additional bytes to be written. Data portion is written
269 * in the 'for' loop below
270 */
271 num_data_bytes = info->size;
272 break;
273 case SMBUS_PROT_BLK_WR:
274 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
275 devaddr);
276 /* 3rd byte is byte count */
277 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
278 info->size);
279 num_data_bytes = info->size;
280 break;
281 default:
282 return;
283 }
284
285 /* If the protocol needs command code, copy it */
286 if (info->cmd_valid) {
287 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
288 info->command);
289 }
290
291 /*
292 * Copy actual data from caller. In general, for reads,
293 * no data is copied.
294 */
295 for (i = 0U; num_data_bytes; --num_data_bytes, i++) {
296 /* For the last byte, set MASTER_WR_STATUS bit */
297 regval = (num_data_bytes == 1U) ?
298 info->data[i] | SMB_MSTRWRSTS_MASK : info->data[i];
299 iproc_i2c_reg_write(info->bus_id, SMB_MSTRDATAWR_REG,
300 regval);
301 }
302}
303
304/*
305 * This function writes to the master command register and
306 * then polls for completion
307 */
308static int iproc_i2c_write_master_command(uint32_t mastercmd,
309 struct iproc_xact_info *info)
310{
311 uint32_t retry = 0U;
312 uint32_t regval;
313
314 iproc_i2c_reg_write(info->bus_id, SMB_MSTRCMD_REG, mastercmd);
315
316 /* Check for Master Busy status */
317 regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRCMD_REG);
318 while ((regval & SMB_MSTRSTARTBUSYCMD_MASK) != 0U) {
319 udelay(1U);
320 if (retry++ > BUS_BUSY_COUNT) {
321 ERROR("%s: START_BUSY bit didn't clear, exiting\n",
322 __func__);
323 return -1;
324 }
325 regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRCMD_REG);
326 }
327
328 /* If start_busy bit cleared, check if there are any errors */
329 if (!(regval & SMB_MSTRSTARTBUSYCMD_MASK)) {
330 /* start_busy bit cleared, check master_status field now */
331 regval &= SMB_MSTRSTS_MASK;
332 regval >>= SMB_MSTRSTS_SHIFT;
333 if (regval != MSTR_STS_XACT_SUCCESS) {
334 /* Error We can flush Tx FIFO here */
335 ERROR("%s: ERROR: %u exiting\n", __func__, regval);
336 return -1;
337 }
338 }
339 return 0;
340
341}
342/* Function to initiate data send and verify completion status */
343static int iproc_i2c_data_send(struct iproc_xact_info *info)
344{
345 int rc;
346 uint32_t mastercmd;
347
348 /* Make sure the previous transaction completed */
349 rc = iproc_i2c_startbusy_wait(info->bus_id);
350
351 if (rc < 0) {
352 WARN("%s: Send: bus is busy, exiting\n", __func__);
353 return rc;
354 }
355 /* Write transaction bytes to Tx FIFO */
356 iproc_i2c_write_trans_data(info);
357
358 /*
359 * Program master command register (0x30) with protocol type and set
360 * start_busy_command bit to initiate the write transaction
361 */
362 mastercmd = (info->smb_proto << SMB_MSTRSMBUSPROTO_SHIFT) |
363 SMB_MSTRSTARTBUSYCMD_MASK;
364
365 if (iproc_i2c_write_master_command(mastercmd, info)) {
366 return -1;
367 }
368
369 return 0;
370}
371
372/*
373 * Function to initiate data receive, verify completion status,
374 * and read from SMBUS Read FIFO
375 */
376static int iproc_i2c_data_recv(struct iproc_xact_info *info,
377 uint32_t *num_bytes_read)
378{
379 int rc;
380 uint32_t mastercmd;
381 uint32_t regval;
382
383 /* Make sure the previous transaction completed */
384 rc = iproc_i2c_startbusy_wait(info->bus_id);
385
386 if (rc < 0) {
387 WARN("%s: Receive: Bus is busy, exiting\n", __func__);
388 return rc;
389 }
390
391 /* Program all transaction bytes into master Tx FIFO */
392 iproc_i2c_write_trans_data(info);
393
394 /*
395 * Program master command register (0x30) with protocol type and set
396 * start_busy_command bit to initiate the write transaction
397 */
398 mastercmd = (info->smb_proto << SMB_MSTRSMBUSPROTO_SHIFT) |
399 SMB_MSTRSTARTBUSYCMD_MASK | info->size;
400
401 if (iproc_i2c_write_master_command(mastercmd, info)) {
402 return -1;
403 }
404
405 /* Read received byte(s), after TX out address etc */
406 regval = iproc_i2c_reg_read(info->bus_id, SMB_MSTRDATARD_REG);
407
408 /* For block read, protocol (hw) returns byte count,as the first byte */
409 if (info->smb_proto == SMBUS_PROT_BLK_RD) {
410 uint32_t i;
411
412 *num_bytes_read = regval & SMB_MSTRRDDATA_MASK;
413 /*
414 * Limit to reading a max of 32 bytes only; just a safeguard.
415 * If # bytes read is a number > 32, check transaction set up,
416 * and contact hw engg.
417 * Assumption: PEC is disabled
418 */
419 for (i = 0U; (i < *num_bytes_read) &&
420 (i < I2C_SMBUS_BLOCK_MAX); i++) {
421 /* Read Rx FIFO for data bytes */
422 regval = iproc_i2c_reg_read(info->bus_id,
423 SMB_MSTRDATARD_REG);
424 info->data[i] = regval & SMB_MSTRRDDATA_MASK;
425 }
426 } else {
427 /* 1 Byte data */
428 *info->data = regval & SMB_MSTRRDDATA_MASK;
429 *num_bytes_read = 1U;
430 }
431
432 return 0;
433}
434
435/*
436 * This function set clock frequency for SMBus block. As per hardware
437 * engineering, the clock frequency can be changed dynamically.
438 */
439static int iproc_i2c_set_clk_freq(uint32_t bus_id, smb_clk_freq_t freq)
440{
441 uint32_t val;
442
443 switch (freq) {
444 case IPROC_SMB_SPEED_100KHz:
445 val = 0U;
446 break;
447 case IPROC_SMB_SPEED_400KHz:
448 val = 1U;
449 break;
450 default:
451 return -1;
452 }
453
454 iproc_i2c_reg_clearset(bus_id, SMB_TIMGCFG_REG,
455 SMB_TIMGCFG_MODE400_MASK,
456 val << SMB_TIMGCFG_MODE400_SHIFT);
457
458 return 0;
459}
460
461/* Helper function to fill the iproc_xact_info structure */
462static void iproc_i2c_fill_info(struct iproc_xact_info *info, uint32_t bus_id,
463 uint8_t devaddr, uint8_t cmd, uint8_t *value,
464 uint8_t smb_proto, uint32_t cmd_valid)
465{
466 info->bus_id = bus_id;
467 info->devaddr = devaddr;
468 info->command = (uint8_t)cmd;
469 info->smb_proto = smb_proto;
470 info->data = value;
471 info->size = 1U;
472 info->flags = 0U;
473 info->cmd_valid = cmd_valid;
474}
475
476/* This function initializes the SMBUS */
477static void iproc_i2c_init(uint32_t bus_id, int speed)
478{
479 uint32_t regval;
480
481#ifdef BCM_I2C_DEBUG
482 INFO("%s: Enter Init\n", __func__);
483#endif
484
485 /* Put controller in reset */
486 regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG);
487 regval |= BIT(SMB_CFG_RST_SHIFT);
488 regval &= ~(BIT(SMB_CFG_SMBEN_SHIFT));
489 iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval);
490
491 /* Wait 100 usec per spec */
492 udelay(100U);
493
494 /* Bring controller out of reset */
495 regval &= ~(BIT(SMB_CFG_RST_SHIFT));
496 iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval);
497
498 /*
499 * Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0.
500 * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts
501 */
502 regval = SMB_MSTRRXFIFOFLSH_MASK | SMB_MSTRTXFIFOFLSH_MASK;
503 iproc_i2c_reg_write(bus_id, SMB_MSTRFIFOCTL_REG, regval);
504
505 /*
506 * Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero
507 * since there will be only one master
508 */
509
510 regval = iproc_i2c_reg_read(bus_id, SMB_CFG_REG);
511 regval |= SMB_CFG_SMBEN_MASK;
512 iproc_i2c_reg_write(bus_id, SMB_CFG_REG, regval);
513 /* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */
514 mdelay(10U);
515
516 /* If error then set default speed */
517 if (i2c_set_bus_speed(bus_id, speed)) {
518 i2c_set_bus_speed(bus_id, I2C_SPEED_DEFAULT);
519 }
520
521 /* Disable intrs */
522 regval = 0x0U;
523 iproc_i2c_reg_write(bus_id, SMB_EVTEN_REG, regval);
524
525 /* Clear intrs (W1TC) */
526 regval = iproc_i2c_reg_read(bus_id, SMB_EVTSTS_REG);
527 iproc_i2c_reg_write(bus_id, SMB_EVTSTS_REG, regval);
528
529#ifdef BCM_I2C_DEBUG
530 iproc_dump_i2c_regs(bus_id);
531
532 INFO("%s: Exit Init Successfully\n", __func__);
533#endif
534}
535
536/*
537 * Function Name: i2c_init
538 *
539 * Description:
540 * This function initializes the SMBUS.
541 *
542 * Parameters:
543 * bus_id - I2C bus ID
544 * speed - I2C bus speed in Hz
545 *
546 * Return:
547 * 0 on success, or -1 on failure.
548 */
549int i2c_init(uint32_t bus_id, int speed)
550{
551 if (bus_id > MAX_I2C) {
552 WARN("%s: Invalid Bus %u\n", __func__, bus_id);
553 return -1;
554 }
555
556 iproc_i2c_init(bus_id, speed);
557 return 0U;
558}
559
560/*
561 * Function Name: i2c_probe
562 *
563 * Description:
564 * This function probes the I2C bus for the existence of the specified
565 * device.
566 *
567 * Parameters:
568 * bus_id - I2C bus ID
569 * devaddr - Device Address
570 *
571 * Return:
572 * 0 on success, or -1 on failure.
573 */
574int i2c_probe(uint32_t bus_id, uint8_t devaddr)
575{
576 uint32_t regval;
577 int rc;
578
579 /*
580 * i2c_init() Initializes internal regs, disable intrs (and then clear intrs),
581 * set fifo thresholds, etc.
582 * Shift devaddr by 1 bit since SMBus uses the low bit[0] for R/W_n
583 */
584 regval = (devaddr << 1U);
585 iproc_i2c_reg_write(bus_id, SMB_MSTRDATAWR_REG, regval);
586
587 regval = ((SMBUS_PROT_QUICK_CMD << SMB_MSTRSMBUSPROTO_SHIFT) |
588 SMB_MSTRSTARTBUSYCMD_MASK);
589 iproc_i2c_reg_write(bus_id, SMB_MSTRCMD_REG, regval);
590
591 rc = iproc_i2c_startbusy_wait(bus_id);
592
593 if (rc < 0) {
594 WARN("%s: Probe: bus is busy, exiting\n", __func__);
595 return rc;
596 }
597
598 regval = iproc_i2c_reg_read(bus_id, SMB_MSTRCMD_REG);
599 if (((regval & SMB_MSTRSTS_MASK) >> SMB_MSTRSTS_SHIFT) == 0)
600 VERBOSE("i2c device address: 0x%x\n", devaddr);
601 else
602 return -1;
603
604#ifdef BCM_I2C_DEBUG
605 iproc_dump_i2c_regs(bus_id);
606#endif
607 return 0;
608}
609
610/*
611 * Function Name: i2c_recv_byte
612 *
613 * Description:
614 * This function reads I2C data from a device without specifying
Elyes Haouas2be03c02023-02-13 09:14:48 +0100615 * a command register.
Bharat Gooty66b0bb42020-09-24 12:29:00 +0530616 *
617 * Parameters:
618 * bus_id - I2C bus ID
619 * devaddr - Device Address
620 * value - Data Read
621 *
622 * Return:
623 * 0 on success, or -1 on failure.
624 */
625int i2c_recv_byte(uint32_t bus_id, uint8_t devaddr, uint8_t *value)
626{
627 int rc;
628 struct iproc_xact_info info;
629 uint32_t num_bytes_read = 0;
630
631 iproc_i2c_fill_info(&info, bus_id, devaddr, 0U, value,
632 SMBUS_PROT_RECV_BYTE, 0U);
633
634 /* Refer to i2c_smbus_read_byte for params passed. */
635 rc = iproc_i2c_data_recv(&info, &num_bytes_read);
636
637 if (rc < 0) {
638 printf("%s: %s error accessing device 0x%x\n",
639 __func__, "Read", devaddr);
640 }
641
642 return rc;
643}
644
645/*
646 * Function Name: i2c_send_byte
647 *
648 * Description:
649 * This function send I2C data to a device without specifying
Elyes Haouas2be03c02023-02-13 09:14:48 +0100650 * a command register.
Bharat Gooty66b0bb42020-09-24 12:29:00 +0530651 *
652 * Parameters:
653 * bus_id - I2C bus ID
654 * devaddr - Device Address
655 * value - Data Send
656 *
657 * Return:
658 * 0 on success, or -1 on failure.
659 */
660int i2c_send_byte(uint32_t bus_id, uint8_t devaddr, uint8_t value)
661{
662 int rc;
663 struct iproc_xact_info info;
664
665 iproc_i2c_fill_info(&info, bus_id, devaddr, 0U, &value,
666 SMBUS_PROT_SEND_BYTE, 0U);
667
668 /* Refer to i2c_smbus_write_byte params passed. */
669 rc = iproc_i2c_data_send(&info);
670
671 if (rc < 0) {
672 ERROR("%s: %s error accessing device 0x%x\n",
673 __func__, "Write", devaddr);
674 }
675
676 return rc;
677}
678
679/* Helper function to read a single byte */
680static int i2c_read_byte(uint32_t bus_id,
681 uint8_t devaddr,
682 uint8_t regoffset,
683 uint8_t *value)
684{
685 int rc;
686 struct iproc_xact_info info;
687 uint32_t num_bytes_read = 0U;
688
689 iproc_i2c_fill_info(&info, bus_id, devaddr, regoffset, value,
690 SMBUS_PROT_RD_BYTE, 1U);
691
692 /* Refer to i2c_smbus_read_byte for params passed. */
693 rc = iproc_i2c_data_recv(&info, &num_bytes_read);
694
695 if (rc < 0) {
696 ERROR("%s: %s error accessing device 0x%x\n",
697 __func__, "Read", devaddr);
698 }
699 return rc;
700}
701
702/*
703 * Function Name: i2c_read
704 *
705 * Description:
706 * This function reads I2C data from a device with a designated
707 * command register
708 *
709 * Parameters:
710 * bus_id - I2C bus ID
711 * devaddr - Device Address
712 * addr - Register Offset
713 * alen - Address Length, 1 for byte, 2 for word (not supported)
714 * buffer - Data Buffer
715 * len - Data Length in bytes
716 *
717 * Return:
718 * 0 on success, or -1 on failure.
719 */
720int i2c_read(uint32_t bus_id,
721 uint8_t devaddr,
722 uint32_t addr,
723 int alen,
724 uint8_t *buffer,
725 int len)
726{
727 uint32_t i;
728
729 if (alen > 1) {
730 WARN("I2C read: addr len %d not supported\n", alen);
731 return -1;
732 }
733
734 if (addr + len > 256) {
735 WARN("I2C read: address out of range\n");
736 return -1;
737 }
738
739 for (i = 0U; i < len; i++) {
740 if (i2c_read_byte(bus_id, devaddr, addr + i, &buffer[i])) {
741 ERROR("I2C read: I/O error\n");
742 iproc_i2c_init(bus_id, i2c_get_bus_speed(bus_id));
743 return -1;
744 }
745 }
746
747 return 0;
748}
749
750/* Helper function to write a single byte */
751static int i2c_write_byte(uint32_t bus_id,
752 uint8_t devaddr,
753 uint8_t regoffset,
754 uint8_t value)
755{
756 int rc;
757 struct iproc_xact_info info;
758
759 iproc_i2c_fill_info(&info, bus_id, devaddr, regoffset, &value,
760 SMBUS_PROT_WR_BYTE, 1U);
761
762 /* Refer to i2c_smbus_write_byte params passed. */
763 rc = iproc_i2c_data_send(&info);
764
765 if (rc < 0) {
766 ERROR("%s: %s error accessing device 0x%x\n",
767 __func__, "Write", devaddr);
768 return -1;
769 }
770
771 return 0;
772}
773
774/*
775 * Function Name: i2c_write
776 *
777 * Description:
778 * This function write I2C data to a device with a designated
779 * command register
780 *
781 * Parameters:
782 * bus_id - I2C bus ID
783 * devaddr - Device Address
784 * addr - Register Offset
785 * alen - Address Length, 1 for byte, 2 for word (not supported)
786 * buffer - Data Buffer
787 * len - Data Length in bytes
788 *
789 * Return:
790 * 0 on success, or -1 on failure.
791 */
792int i2c_write(uint32_t bus_id,
793 uint8_t devaddr,
794 uint32_t addr,
795 int alen,
796 uint8_t *buffer,
797 int len)
798{
799 uint32_t i;
800
801 if (alen > 1) {
802 WARN("I2C write: addr len %d not supported\n", alen);
803 return -1;
804 }
805
806 if (addr + len > 256U) {
807 WARN("I2C write: address out of range\n");
808 return -1;
809 }
810
811 for (i = 0U; i < len; i++) {
812 if (i2c_write_byte(bus_id, devaddr, addr + i, buffer[i])) {
813 ERROR("I2C write: I/O error\n");
814 iproc_i2c_init(bus_id, i2c_get_bus_speed(bus_id));
815 return -1;
816 }
817 }
818 return 0;
819}
820
821/*
822 * Function Name: i2c_set_bus_speed
823 *
824 * Description:
825 * This function configures the SMBUS speed
826 *
827 * Parameters:
828 * bus_id - I2C bus ID
829 * speed - I2C bus speed in Hz
830 *
831 * Return:
832 * 0 on success, or -1 on failure.
833 */
834int i2c_set_bus_speed(uint32_t bus_id, uint32_t speed)
835{
836 switch (speed) {
837 case I2C_SPEED_100KHz:
838 iproc_i2c_set_clk_freq(bus_id, IPROC_SMB_SPEED_100KHz);
839 break;
840
841 case I2C_SPEED_400KHz:
842 iproc_i2c_set_clk_freq(bus_id, IPROC_SMB_SPEED_400KHz);
843 break;
844
845 default:
846 return -1;
847 }
848 return 0;
849}
850
851/*
852 * Function Name: i2c_get_bus_speed
853 *
854 * Description:
855 * This function returns the SMBUS speed.
856 *
857 * Parameters:
858 * bus_id - I2C bus ID
859 *
860 * Return:
861 * Bus speed in Hz, 0 on failure
862 */
863uint32_t i2c_get_bus_speed(uint32_t bus_id)
864{
865 uint32_t regval;
866 uint32_t retval = 0U;
867
868 regval = iproc_i2c_reg_read(bus_id, SMB_TIMGCFG_REG);
869 regval &= SMB_TIMGCFG_MODE400_MASK;
870 regval >>= SMB_TIMGCFG_MODE400_SHIFT;
871
872 switch (regval) {
873 case IPROC_SMB_SPEED_100KHz:
874 retval = I2C_SPEED_100KHz;
875 break;
876
877 case IPROC_SMB_SPEED_400KHz:
878 retval = I2C_SPEED_400KHz;
879 break;
880
881 default:
882 break;
883 }
884 return retval;
885}
886