pd63000.c (4095B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * BCM56xx I2C Device Driver for PD63000 8-bit PoE Microcontroller Unit. 8 * The MCU communicates with message types of 15-byte long packet. 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <sal/types.h> 14 #include <soc/debug.h> 15 #include <soc/drv.h> 16 #include <soc/error.h> 17 #include <soc/i2c.h> 18 19 #define PD63000_CTN 15 20 21 STATIC int 22 pd63000_read(int unit, int devno, 23 uint16 addr, uint8* data, uint32* len) 24 { 25 26 int i, rv = SOC_E_NONE; 27 uint8 saddr = soc_i2c_addr(unit, devno); 28 uint8 *ptr; 29 30 if (!data) { 31 return SOC_E_PARAM; 32 } 33 34 ptr = data; 35 for (i = 0; i < PD63000_CTN; i++, ptr++) { 36 if ((rv = soc_i2c_read_byte(unit, saddr, ptr)) < 0) { 37 LOG_INFO(BSL_LS_SOC_I2C, 38 (BSL_META_U(unit, 39 "i2c%d: soc_i2c_pd63000_read: " 40 "failed to read data byte %d.\n"), 41 unit, i)); 42 break; 43 } 44 soc_i2c_device(unit, devno)->rbyte++; 45 } 46 *len = i; 47 48 return rv; 49 } 50 51 STATIC int 52 pd63000_write(int unit, int devno, 53 uint16 addr, uint8* data, uint32 len) 54 { 55 int rv = SOC_E_NONE; 56 uint8 saddr = soc_i2c_addr(unit, devno); 57 uint8 *ptr; 58 uint32 i; 59 60 if (!data) { 61 return SOC_E_PARAM; 62 } 63 assert((PD63000_CTN == len)); 64 65 I2C_LOCK(unit); 66 67 if ((rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr))) < 0) { 68 LOG_INFO(BSL_LS_SOC_I2C, 69 (BSL_META_U(unit, 70 "i2c%d: soc_i2c_pd63000_write: " 71 "failed to generate start.\n"), 72 unit)); 73 I2C_UNLOCK(unit); 74 return rv; 75 } 76 77 ptr = data; 78 for (i = 0; i < len; i++, ptr++) { 79 if ((rv = soc_i2c_write_one_byte(unit, *ptr) ) < 0 ) { 80 LOG_INFO(BSL_LS_SOC_I2C, 81 (BSL_META_U(unit, 82 "i2c%d: soc_i2c_pd63000_write: " 83 "failed to send byte %d.\n"), 84 unit, i )); 85 break; 86 } 87 soc_i2c_device(unit, devno)->tbyte++; 88 } 89 90 soc_i2c_stop(unit); 91 I2C_UNLOCK(unit); 92 93 return rv; 94 } 95 96 97 98 STATIC int 99 pd63000_ioctl(int unit, int devno, 100 int opcode, void* data, int len) 101 { 102 return SOC_E_NONE; 103 } 104 105 STATIC int 106 pd63000_init(int unit, int devno, 107 void* data, int len) 108 { 109 uint8 *init_vector = (uint8*)data; 110 uint8 pkt[PD63000_CTN]; 111 int rv = SOC_E_NONE; 112 uint32 l; 113 soc_timeout_t to; 114 115 soc_i2c_devdesc_set(unit, devno, "PD63000 PoE MCU"); 116 117 if ((rv = pd63000_read(unit, devno, 0, pkt, &l)) < 0) { 118 LOG_INFO(BSL_LS_SOC_I2C, 119 (BSL_META_U(unit, 120 "i2c%d: soc_i2c_pd63000_init: " 121 "failed to read init packet.\n"), unit)); 122 return rv; 123 } 124 125 if ((rv = pd63000_write(unit, devno, 0, 126 init_vector, PD63000_CTN)) < 0) { 127 LOG_INFO(BSL_LS_SOC_I2C, 128 (BSL_META_U(unit, 129 "i2c%d: soc_i2c_pd63000_init: " 130 "failed to send power init packet.\n"), unit)); 131 return rv; 132 } 133 134 soc_timeout_init(&to, 100000, 0); 135 for (;;) { 136 if (soc_timeout_check(&to)) { 137 break; 138 } 139 } 140 141 if ((rv = pd63000_read(unit, devno, 0, pkt, &l)) < 0) { 142 LOG_INFO(BSL_LS_SOC_I2C, 143 (BSL_META_U(unit, 144 "i2c%d: soc_i2c_pd63000_init: " 145 "failed to read power init packet.\n"), unit)); 146 return rv; 147 } 148 149 return rv; 150 } 151 152 153 /* PD63000 Chip Driver callout */ 154 i2c_driver_t _soc_i2c_pd63000_driver = { 155 0x0, 0x0, /* System assigned bytes */ 156 PD63000_DEVICE_TYPE, 157 pd63000_read, 158 pd63000_write, 159 pd63000_ioctl, 160 pd63000_init, 161 NULL, 162 }; 163