.. | .. |
---|
1079 | 1079 | return 0; |
---|
1080 | 1080 | } |
---|
1081 | 1081 | |
---|
1082 | | -static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, |
---|
1083 | | - struct spi_device *spi, |
---|
1084 | | - struct spi_transfer *tfr) |
---|
| 1082 | +static unsigned long bcm2835_get_clkdiv(struct bcm2835_spi *bs, u32 spi_hz, |
---|
| 1083 | + u32 *effective_speed_hz) |
---|
1085 | 1084 | { |
---|
1086 | | - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
---|
1087 | | - unsigned long spi_hz, cdiv; |
---|
1088 | | - unsigned long hz_per_byte, byte_limit; |
---|
1089 | | - u32 cs = bs->prepare_cs[spi->chip_select]; |
---|
1090 | | - |
---|
1091 | | - /* set clock */ |
---|
1092 | | - spi_hz = tfr->speed_hz; |
---|
| 1085 | + unsigned long cdiv; |
---|
1093 | 1086 | |
---|
1094 | 1087 | if (spi_hz >= bs->clk_hz / 2) { |
---|
1095 | 1088 | cdiv = 2; /* clk_hz/2 is the fastest we can go */ |
---|
.. | .. |
---|
1103 | 1096 | } else { |
---|
1104 | 1097 | cdiv = 0; /* 0 is the slowest we can go */ |
---|
1105 | 1098 | } |
---|
1106 | | - tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); |
---|
| 1099 | + |
---|
| 1100 | + *effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); |
---|
| 1101 | + |
---|
| 1102 | + return cdiv; |
---|
| 1103 | +} |
---|
| 1104 | + |
---|
| 1105 | +static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, |
---|
| 1106 | + struct spi_device *spi, |
---|
| 1107 | + struct spi_transfer *tfr) |
---|
| 1108 | +{ |
---|
| 1109 | + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
---|
| 1110 | + unsigned long spi_hz, cdiv; |
---|
| 1111 | + unsigned long hz_per_byte, byte_limit; |
---|
| 1112 | + u32 cs = bs->prepare_cs[spi->chip_select]; |
---|
| 1113 | + |
---|
| 1114 | + /* set clock */ |
---|
| 1115 | + spi_hz = tfr->speed_hz; |
---|
| 1116 | + |
---|
| 1117 | + cdiv = bcm2835_get_clkdiv(bs, spi_hz, &tfr->effective_speed_hz); |
---|
1107 | 1118 | bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); |
---|
1108 | 1119 | |
---|
1109 | 1120 | /* handle all the 3-wire mode */ |
---|
.. | .. |
---|
1283 | 1294 | return 0; |
---|
1284 | 1295 | } |
---|
1285 | 1296 | |
---|
| 1297 | +#ifdef CONFIG_SPI_BCM2835_OOB |
---|
| 1298 | + |
---|
| 1299 | +static int bcm2835_spi_prepare_oob_transfer(struct spi_controller *ctlr, |
---|
| 1300 | + struct spi_oob_transfer *xfer) |
---|
| 1301 | +{ |
---|
| 1302 | + /* |
---|
| 1303 | + * The size of a transfer is limited by DLEN which is 16-bit |
---|
| 1304 | + * wide, and we don't want to scatter transfers in out-of-band |
---|
| 1305 | + * mode, so cap the frame size accordingly. |
---|
| 1306 | + */ |
---|
| 1307 | + if (xfer->setup.frame_len > 65532) |
---|
| 1308 | + return -EINVAL; |
---|
| 1309 | + |
---|
| 1310 | + return 0; |
---|
| 1311 | +} |
---|
| 1312 | + |
---|
| 1313 | +static void bcm2835_spi_start_oob_transfer(struct spi_controller *ctlr, |
---|
| 1314 | + struct spi_oob_transfer *xfer) |
---|
| 1315 | +{ |
---|
| 1316 | + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
---|
| 1317 | + struct spi_device *spi = xfer->spi; |
---|
| 1318 | + u32 cs = bs->prepare_cs[spi->chip_select], effective_speed_hz; |
---|
| 1319 | + unsigned long cdiv; |
---|
| 1320 | + |
---|
| 1321 | + /* See bcm2835_spi_prepare_message(). */ |
---|
| 1322 | + bcm2835_wr(bs, BCM2835_SPI_CS, cs); |
---|
| 1323 | + |
---|
| 1324 | + cdiv = bcm2835_get_clkdiv(bs, xfer->setup.speed_hz, &effective_speed_hz); |
---|
| 1325 | + xfer->effective_speed_hz = effective_speed_hz; |
---|
| 1326 | + bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); |
---|
| 1327 | + bcm2835_wr(bs, BCM2835_SPI_DLEN, xfer->setup.frame_len); |
---|
| 1328 | + |
---|
| 1329 | + if (spi->mode & SPI_3WIRE) |
---|
| 1330 | + cs |= BCM2835_SPI_CS_REN; |
---|
| 1331 | + bcm2835_wr(bs, BCM2835_SPI_CS, |
---|
| 1332 | + cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN); |
---|
| 1333 | +} |
---|
| 1334 | + |
---|
| 1335 | +static void bcm2835_spi_pulse_oob_transfer(struct spi_controller *ctlr, |
---|
| 1336 | + struct spi_oob_transfer *xfer) |
---|
| 1337 | +{ |
---|
| 1338 | + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
---|
| 1339 | + |
---|
| 1340 | + /* Reload DLEN for the next pulse. */ |
---|
| 1341 | + bcm2835_wr(bs, BCM2835_SPI_DLEN, xfer->setup.frame_len); |
---|
| 1342 | +} |
---|
| 1343 | + |
---|
| 1344 | +static void bcm2835_spi_terminate_oob_transfer(struct spi_controller *ctlr, |
---|
| 1345 | + struct spi_oob_transfer *xfer) |
---|
| 1346 | +{ |
---|
| 1347 | + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); |
---|
| 1348 | + |
---|
| 1349 | + bcm2835_spi_reset_hw(bs); |
---|
| 1350 | +} |
---|
| 1351 | + |
---|
| 1352 | +#else |
---|
| 1353 | +#define bcm2835_spi_prepare_oob_transfer NULL |
---|
| 1354 | +#define bcm2835_spi_start_oob_transfer NULL |
---|
| 1355 | +#define bcm2835_spi_pulse_oob_transfer NULL |
---|
| 1356 | +#define bcm2835_spi_terminate_oob_transfer NULL |
---|
| 1357 | +#endif |
---|
| 1358 | + |
---|
1286 | 1359 | static int bcm2835_spi_probe(struct platform_device *pdev) |
---|
1287 | 1360 | { |
---|
1288 | 1361 | struct spi_controller *ctlr; |
---|
.. | .. |
---|
1304 | 1377 | ctlr->transfer_one = bcm2835_spi_transfer_one; |
---|
1305 | 1378 | ctlr->handle_err = bcm2835_spi_handle_err; |
---|
1306 | 1379 | ctlr->prepare_message = bcm2835_spi_prepare_message; |
---|
| 1380 | + ctlr->prepare_oob_transfer = bcm2835_spi_prepare_oob_transfer; |
---|
| 1381 | + ctlr->start_oob_transfer = bcm2835_spi_start_oob_transfer; |
---|
| 1382 | + ctlr->pulse_oob_transfer = bcm2835_spi_pulse_oob_transfer; |
---|
| 1383 | + ctlr->terminate_oob_transfer = bcm2835_spi_terminate_oob_transfer; |
---|
1307 | 1384 | ctlr->dev.of_node = pdev->dev.of_node; |
---|
1308 | 1385 | |
---|
1309 | 1386 | bs = spi_controller_get_devdata(ctlr); |
---|