Commit a4bdfff74464f86d7e3b8feaf42d18960adc5514

Authored by Sebastien Jan
Committed by David S. Miller
1 parent 7d9974666e

ks8851: Low level functions for read/write to companion eeprom

Low-level functions provide 16bits words read and write capability
to ks8851 companion eeprom.

Signed-off-by: Sebastien Jan <s-jan@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 241 additions and 1 deletions Side-by-side Diff

drivers/net/ks8851.c
... ... @@ -1034,6 +1034,234 @@
1034 1034 .ndo_validate_addr = eth_validate_addr,
1035 1035 };
1036 1036  
  1037 +/* Companion eeprom access */
  1038 +
  1039 +enum { /* EEPROM programming states */
  1040 + EEPROM_CONTROL,
  1041 + EEPROM_ADDRESS,
  1042 + EEPROM_DATA,
  1043 + EEPROM_COMPLETE
  1044 +};
  1045 +
  1046 +/**
  1047 + * ks8851_eeprom_read - read a 16bits word in ks8851 companion EEPROM
  1048 + * @dev: The network device the PHY is on.
  1049 + * @addr: EEPROM address to read
  1050 + *
  1051 + * eeprom_size: used to define the data coding length. Can be changed
  1052 + * through debug-fs.
  1053 + *
  1054 + * Programs a read on the EEPROM using ks8851 EEPROM SW access feature.
  1055 + * Warning: The READ feature is not supported on ks8851 revision 0.
  1056 + *
  1057 + * Rough programming model:
  1058 + * - on period start: set clock high and read value on bus
  1059 + * - on period / 2: set clock low and program value on bus
  1060 + * - start on period / 2
  1061 + */
  1062 +unsigned int ks8851_eeprom_read(struct net_device *dev, unsigned int addr)
  1063 +{
  1064 + struct ks8851_net *ks = netdev_priv(dev);
  1065 + int eepcr;
  1066 + int ctrl = EEPROM_OP_READ;
  1067 + int state = EEPROM_CONTROL;
  1068 + int bit_count = EEPROM_OP_LEN - 1;
  1069 + unsigned int data = 0;
  1070 + int dummy;
  1071 + unsigned int addr_len;
  1072 +
  1073 + addr_len = (ks->eeprom_size == 128) ? 6 : 8;
  1074 +
  1075 + /* start transaction: chip select high, authorize write */
  1076 + mutex_lock(&ks->lock);
  1077 + eepcr = EEPCR_EESA | EEPCR_EESRWA;
  1078 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1079 + eepcr |= EEPCR_EECS;
  1080 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1081 + mutex_unlock(&ks->lock);
  1082 +
  1083 + while (state != EEPROM_COMPLETE) {
  1084 + /* falling clock period starts... */
  1085 + /* set EED_IO pin for control and address */
  1086 + eepcr &= ~EEPCR_EEDO;
  1087 + switch (state) {
  1088 + case EEPROM_CONTROL:
  1089 + eepcr |= ((ctrl >> bit_count) & 1) << 2;
  1090 + if (bit_count-- <= 0) {
  1091 + bit_count = addr_len - 1;
  1092 + state = EEPROM_ADDRESS;
  1093 + }
  1094 + break;
  1095 + case EEPROM_ADDRESS:
  1096 + eepcr |= ((addr >> bit_count) & 1) << 2;
  1097 + bit_count--;
  1098 + break;
  1099 + case EEPROM_DATA:
  1100 + /* Change to receive mode */
  1101 + eepcr &= ~EEPCR_EESRWA;
  1102 + break;
  1103 + }
  1104 +
  1105 + /* lower clock */
  1106 + eepcr &= ~EEPCR_EESCK;
  1107 +
  1108 + mutex_lock(&ks->lock);
  1109 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1110 + mutex_unlock(&ks->lock);
  1111 +
  1112 + /* waitread period / 2 */
  1113 + udelay(EEPROM_SK_PERIOD / 2);
  1114 +
  1115 + /* rising clock period starts... */
  1116 +
  1117 + /* raise clock */
  1118 + mutex_lock(&ks->lock);
  1119 + eepcr |= EEPCR_EESCK;
  1120 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1121 + mutex_unlock(&ks->lock);
  1122 +
  1123 + /* Manage read */
  1124 + switch (state) {
  1125 + case EEPROM_ADDRESS:
  1126 + if (bit_count < 0) {
  1127 + bit_count = EEPROM_DATA_LEN - 1;
  1128 + state = EEPROM_DATA;
  1129 + }
  1130 + break;
  1131 + case EEPROM_DATA:
  1132 + mutex_lock(&ks->lock);
  1133 + dummy = ks8851_rdreg16(ks, KS_EEPCR);
  1134 + mutex_unlock(&ks->lock);
  1135 + data |= ((dummy >> EEPCR_EESB_OFFSET) & 1) << bit_count;
  1136 + if (bit_count-- <= 0)
  1137 + state = EEPROM_COMPLETE;
  1138 + break;
  1139 + }
  1140 +
  1141 + /* wait period / 2 */
  1142 + udelay(EEPROM_SK_PERIOD / 2);
  1143 + }
  1144 +
  1145 + /* close transaction */
  1146 + mutex_lock(&ks->lock);
  1147 + eepcr &= ~EEPCR_EECS;
  1148 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1149 + eepcr = 0;
  1150 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1151 + mutex_unlock(&ks->lock);
  1152 +
  1153 + return data;
  1154 +}
  1155 +
  1156 +/**
  1157 + * ks8851_eeprom_write - write a 16bits word in ks8851 companion EEPROM
  1158 + * @dev: The network device the PHY is on.
  1159 + * @op: operand (can be WRITE, EWEN, EWDS)
  1160 + * @addr: EEPROM address to write
  1161 + * @data: data to write
  1162 + *
  1163 + * eeprom_size: used to define the data coding length. Can be changed
  1164 + * through debug-fs.
  1165 + *
  1166 + * Programs a write on the EEPROM using ks8851 EEPROM SW access feature.
  1167 + *
  1168 + * Note that a write enable is required before writing data.
  1169 + *
  1170 + * Rough programming model:
  1171 + * - on period start: set clock high
  1172 + * - on period / 2: set clock low and program value on bus
  1173 + * - start on period / 2
  1174 + */
  1175 +void ks8851_eeprom_write(struct net_device *dev, unsigned int op,
  1176 + unsigned int addr, unsigned int data)
  1177 +{
  1178 + struct ks8851_net *ks = netdev_priv(dev);
  1179 + int eepcr;
  1180 + int state = EEPROM_CONTROL;
  1181 + int bit_count = EEPROM_OP_LEN - 1;
  1182 + unsigned int addr_len;
  1183 +
  1184 + addr_len = (ks->eeprom_size == 128) ? 6 : 8;
  1185 +
  1186 + switch (op) {
  1187 + case EEPROM_OP_EWEN:
  1188 + addr = 0x30;
  1189 + break;
  1190 + case EEPROM_OP_EWDS:
  1191 + addr = 0;
  1192 + break;
  1193 + }
  1194 +
  1195 + /* start transaction: chip select high, authorize write */
  1196 + mutex_lock(&ks->lock);
  1197 + eepcr = EEPCR_EESA | EEPCR_EESRWA;
  1198 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1199 + eepcr |= EEPCR_EECS;
  1200 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1201 + mutex_unlock(&ks->lock);
  1202 +
  1203 + while (state != EEPROM_COMPLETE) {
  1204 + /* falling clock period starts... */
  1205 + /* set EED_IO pin for control and address */
  1206 + eepcr &= ~EEPCR_EEDO;
  1207 + switch (state) {
  1208 + case EEPROM_CONTROL:
  1209 + eepcr |= ((op >> bit_count) & 1) << 2;
  1210 + if (bit_count-- <= 0) {
  1211 + bit_count = addr_len - 1;
  1212 + state = EEPROM_ADDRESS;
  1213 + }
  1214 + break;
  1215 + case EEPROM_ADDRESS:
  1216 + eepcr |= ((addr >> bit_count) & 1) << 2;
  1217 + if (bit_count-- <= 0) {
  1218 + if (op == EEPROM_OP_WRITE) {
  1219 + bit_count = EEPROM_DATA_LEN - 1;
  1220 + state = EEPROM_DATA;
  1221 + } else {
  1222 + state = EEPROM_COMPLETE;
  1223 + }
  1224 + }
  1225 + break;
  1226 + case EEPROM_DATA:
  1227 + eepcr |= ((data >> bit_count) & 1) << 2;
  1228 + if (bit_count-- <= 0)
  1229 + state = EEPROM_COMPLETE;
  1230 + break;
  1231 + }
  1232 +
  1233 + /* lower clock */
  1234 + eepcr &= ~EEPCR_EESCK;
  1235 +
  1236 + mutex_lock(&ks->lock);
  1237 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1238 + mutex_unlock(&ks->lock);
  1239 +
  1240 + /* wait period / 2 */
  1241 + udelay(EEPROM_SK_PERIOD / 2);
  1242 +
  1243 + /* rising clock period starts... */
  1244 +
  1245 + /* raise clock */
  1246 + eepcr |= EEPCR_EESCK;
  1247 + mutex_lock(&ks->lock);
  1248 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1249 + mutex_unlock(&ks->lock);
  1250 +
  1251 + /* wait period / 2 */
  1252 + udelay(EEPROM_SK_PERIOD / 2);
  1253 + }
  1254 +
  1255 + /* close transaction */
  1256 + mutex_lock(&ks->lock);
  1257 + eepcr &= ~EEPCR_EECS;
  1258 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1259 + eepcr = 0;
  1260 + ks8851_wrreg16(ks, KS_EEPCR, eepcr);
  1261 + mutex_unlock(&ks->lock);
  1262 +
  1263 +}
  1264 +
1037 1265 /* ethtool support */
1038 1266  
1039 1267 static void ks8851_get_drvinfo(struct net_device *dev,
drivers/net/ks8851.h
... ... @@ -25,11 +25,23 @@
25 25 #define OBCR_ODS_16mA (1 << 6)
26 26  
27 27 #define KS_EEPCR 0x22
  28 +#define EEPCR_EESRWA (1 << 5)
28 29 #define EEPCR_EESA (1 << 4)
29   -#define EEPCR_EESB (1 << 3)
  30 +#define EEPCR_EESB_OFFSET 3
  31 +#define EEPCR_EESB (1 << EEPCR_EESB_OFFSET)
30 32 #define EEPCR_EEDO (1 << 2)
31 33 #define EEPCR_EESCK (1 << 1)
32 34 #define EEPCR_EECS (1 << 0)
  35 +
  36 +#define EEPROM_OP_LEN 3 /* bits:*/
  37 +#define EEPROM_OP_READ 0x06
  38 +#define EEPROM_OP_EWEN 0x04
  39 +#define EEPROM_OP_WRITE 0x05
  40 +#define EEPROM_OP_EWDS 0x14
  41 +
  42 +#define EEPROM_DATA_LEN 16 /* 16 bits EEPROM */
  43 +#define EEPROM_WRITE_TIME 4 /* wrt ack time in ms */
  44 +#define EEPROM_SK_PERIOD 400 /* in us */
33 45  
34 46 #define KS_MBIR 0x24
35 47 #define MBIR_TXMBF (1 << 12)