clk_src = mxc_get_clock(MXC_CSPI_CLK);
- div = clk_src / max_hz;
+ div = DIV_ROUND_UP(clk_src, max_hz);
div = get_cspi_div(div);
debug("clk %d Hz, div %d, real clk %d Hz\n",
return -1;
}
- reg_ctrl = reg_read(®s->ctrl);
-
- /* Reset spi */
- reg_write(®s->ctrl, 0);
- reg_write(®s->ctrl, (reg_ctrl | 0x1));
+ /*
+ * Reset SPI and set all CSs to master mode, if toggling
+ * between slave and master mode we might see a glitch
+ * on the clock line
+ */
+ reg_ctrl = MXC_CSPICTRL_MODE_MASK;
+ reg_write(®s->ctrl, reg_ctrl);
+ reg_ctrl |= MXC_CSPICTRL_EN;
+ reg_write(®s->ctrl, reg_ctrl);
/*
* The following computation is taken directly from Freescale's code.
*/
if (clk_src > max_hz) {
- pre_div = clk_src / max_hz;
+ pre_div = DIV_ROUND_UP(clk_src, max_hz);
if (pre_div > 16) {
post_div = pre_div / 16;
pre_div = 15;
reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_POSTDIV(0x0F)) |
MXC_CSPICTRL_POSTDIV(post_div);
- /* always set to master mode */
- reg_ctrl |= 1 << (cs + 4);
-
/* We need to disable SPI before changing registers */
reg_ctrl &= ~MXC_CSPICTRL_EN;
if (cs > 3) {
mxcs->gpio = cs >> 8;
cs &= 3;
- ret = gpio_direction_output(mxcs->gpio, 0);
+ ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
if (ret) {
printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
return -EINVAL;
if (bus >= ARRAY_SIZE(spi_bases))
return NULL;
- mxcs = malloc(sizeof(struct mxc_spi_slave));
+ mxcs = spi_alloc_slave(struct mxc_spi_slave, bus, cs);
if (!mxcs) {
puts("mxc_spi: SPI Slave not allocated !\n");
return NULL;
}
+ mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
+
ret = decode_cs(mxcs, cs);
if (ret < 0) {
free(mxcs);
cs = ret;
- mxcs->slave.bus = bus;
- mxcs->slave.cs = cs;
mxcs->base = spi_bases[bus];
- mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
ret = spi_cfg_mxc(mxcs, cs, max_hz, mode);
if (ret) {