+static void ar71xx_spi_setup_regs(struct spi_device *spi)
+{
+ struct ar71xx_spi *sp = spidev_to_sp(spi);
+
+ /* enable GPIO mode */
+ ar71xx_spi_wr(sp, SPI_REG_FS, SPI_FS_GPIO);
+
+ /* save CTRL register */
+ sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_CTRL);
+
+ /* TODO: setup speed? */
+ ar71xx_spi_wr(sp, SPI_REG_CTRL, 0x43);
+}
+
+static void ar71xx_spi_restore_regs(struct spi_device *spi)
+{
+ struct ar71xx_spi *sp = spidev_to_sp(spi);
+
+ /* restore CTRL register */
+ ar71xx_spi_wr(sp, SPI_REG_CTRL, sp->reg_ctrl);
+ /* disable GPIO mode */
+ ar71xx_spi_wr(sp, SPI_REG_FS, 0);
+}
+
+static int ar71xx_spi_setup(struct spi_device *spi)
+{
+ int status;
+
+ if (spi->bits_per_word > 32)
+ return -EINVAL;
+
+ if (!spi->controller_state)
+ ar71xx_spi_setup_regs(spi);
+
+ status = spi_bitbang_setup(spi);
+ if (status && !spi->controller_state)
+ ar71xx_spi_restore_regs(spi);
+
+ return status;
+}
+
+static void ar71xx_spi_cleanup(struct spi_device *spi)
+{
+ ar71xx_spi_restore_regs(spi);
+ spi_bitbang_cleanup(spi);
+}
+