@@ -144,34 +144,24 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
{
/* Valid baud rate pre-scaler values */
int pbr_tbl[4] = {2, 3, 5, 7};
- int brs[16] = { 2, 4, 6, 8,
+ int brs[16] = {
+ 2, 4, 6, 8,
16, 32, 64, 128,
256, 512, 1024, 2048,
- 4096, 8192, 16384, 32768 };
- int scale_needed, scale, minscale = INT_MAX;
+ 4096, 8192, 16384, 32768,
+ };
+ unsigned long r = INT_MAX, tmp;
int i, j;
- scale_needed = clkrate / speed_hz;
-
for (i = 0; i < ARRAY_SIZE(brs); i++)
for (j = 0; j < ARRAY_SIZE(pbr_tbl); j++) {
- scale = brs[i] * pbr_tbl[j];
- if (scale >= scale_needed) {
- if (scale < minscale) {
- minscale = scale;
- *br = i;
- *pbr = j;
- }
- break;
- }
+ tmp = abs(clkrate / pbr_tbl[j] / brs[i] - speed_hz);
+ if (tmp >= r)
+ continue;
+ r = tmp;
+ *br = i;
+ *pbr = j;
}
-
- if (minscale == INT_MAX) {
- pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld, we use the max prescaler value.\n",
- speed_hz, clkrate);
- *pbr = ARRAY_SIZE(pbr_tbl) - 1;
- *br = ARRAY_SIZE(brs) - 1;
- }
}
static int dspi_transfer_write(struct fsl_dspi *dspi)
The current approximation relies on scale comparison which is wrong in two ways: a) the required scale doesn't take into consideration remainder of the division, and b) minimal scale doesn't guarantee the best approximation. This patch change the approach to use comparison between remainders instead of direct scale testing. Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com> --- drivers/spi/spi-fsl-dspi.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-)