+ ctrl_reg = MXC_CSPICTRL_CHIPSELECT(cs) |
+ MXC_CSPICTRL_BITCOUNT(MXC_CSPICTRL_MAXBITS) |
+ MXC_CSPICTRL_DATARATE(div) |
+ MXC_CSPICTRL_EN |
+#ifdef CONFIG_MX35
+ MXC_CSPICTRL_SSCTL |
+#endif
+ MXC_CSPICTRL_MODE;
+
+ if (mode & SPI_CPHA)
+ ctrl_reg |= MXC_CSPICTRL_PHA;
+ if (mode & SPI_CPOL)
+ ctrl_reg |= MXC_CSPICTRL_POL;
+ if (mode & SPI_CS_HIGH)
+ ctrl_reg |= MXC_CSPICTRL_SSPOL;
+ mxcs->ctrl_reg = ctrl_reg;
+
+ return 0;
+}
+#endif
+
+#ifdef MXC_ECSPI
+static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ u32 clk_src = mxc_get_clock(MXC_CSPI_CLK);
+ s32 reg_ctrl, reg_config;
+ u32 ss_pol = 0, sclkpol = 0, sclkpha = 0, pre_div = 0, post_div = 0;
+ struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
+
+ if (max_hz == 0) {
+ printf("Error: desired clock is 0\n");
+ return -1;
+ }
+
+ /*
+ * 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);
+
+ if (clk_src > max_hz) {
+ pre_div = (clk_src - 1) / max_hz;
+ /* fls(1) = 1, fls(0x80000000) = 32, fls(16) = 5 */
+ post_div = fls(pre_div);
+ if (post_div > 4) {
+ post_div -= 4;
+ if (post_div >= 16) {
+ printf("Error: no divider for the freq: %d\n",
+ max_hz);
+ return -1;
+ }
+ pre_div >>= post_div;
+ } else {
+ post_div = 0;
+ }
+ }
+
+ debug("pre_div = %d, post_div=%d\n", pre_div, post_div);
+ reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_SELCHAN(3)) |
+ MXC_CSPICTRL_SELCHAN(cs);
+ reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_PREDIV(0x0F)) |
+ MXC_CSPICTRL_PREDIV(pre_div);
+ reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_POSTDIV(0x0F)) |
+ MXC_CSPICTRL_POSTDIV(post_div);
+
+ /* We need to disable SPI before changing registers */
+ reg_ctrl &= ~MXC_CSPICTRL_EN;
+
+ if (mode & SPI_CS_HIGH)
+ ss_pol = 1;
+
+ if (mode & SPI_CPOL)
+ sclkpol = 1;