^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This driver has been based on the spi-gpio.c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2006,2008 David Brownell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spi/spi_bitbang.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/platform_data/spi-ath79.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DRV_NAME "ath79-spi"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ATH79_SPI_RRW_DELAY_FACTOR 12000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MHZ (1000 * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AR71XX_SPI_REG_FS 0x00 /* Function Select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define AR71XX_SPI_REG_CTRL 0x04 /* SPI Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AR71XX_SPI_REG_IOC 0x08 /* SPI I/O Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AR71XX_SPI_REG_RDS 0x0c /* Read Data Shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AR71XX_SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define AR71XX_SPI_IOC_DO BIT(0) /* Data Out pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define AR71XX_SPI_IOC_CLK BIT(8) /* CLK pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define AR71XX_SPI_IOC_CS(n) BIT(16 + (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct ath79_spi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct spi_bitbang bitbang;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u32 ioc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 reg_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int rrw_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return ioread32(sp->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned int reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) iowrite32(val, sp->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static inline void ath79_spi_delay(struct ath79_spi *sp, unsigned int nsecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (nsecs > sp->rrw_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ndelay(nsecs - sp->rrw_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct ath79_spi *sp = ath79_spidev_to_sp(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 cs_bit = AR71XX_SPI_IOC_CS(spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (cs_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) sp->ioc_base |= cs_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) sp->ioc_base &= ~cs_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void ath79_spi_enable(struct ath79_spi *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* enable GPIO mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* save CTRL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* clear clk and mosi in the base state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) sp->ioc_base &= ~(AR71XX_SPI_IOC_DO | AR71XX_SPI_IOC_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* TODO: setup speed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void ath79_spi_disable(struct ath79_spi *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* restore CTRL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* disable GPIO mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned int nsecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 word, u8 bits, unsigned flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct ath79_spi *sp = ath79_spidev_to_sp(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u32 ioc = sp->ioc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* clock starts at inactive polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for (word <<= (32 - bits); likely(bits); bits--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (word & (1 << 31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) out = ioc | AR71XX_SPI_IOC_DO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) out = ioc & ~AR71XX_SPI_IOC_DO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* setup MSB (to slave) on trailing edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ath79_spi_delay(sp, nsecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ath79_spi_delay(sp, nsecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (bits == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) word <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int ath79_spi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct ath79_spi *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct ath79_spi_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) master = spi_alloc_master(&pdev->dev, sizeof(*sp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (master == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev_err(&pdev->dev, "failed to allocate spi master\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) sp = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) master->dev.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) platform_set_drvdata(pdev, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) master->use_gpio_descriptors = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) master->flags = SPI_MASTER_GPIO_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) master->bus_num = pdata->bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) master->num_chipselect = pdata->num_chipselect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) sp->bitbang.master = master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) sp->bitbang.chipselect = ath79_spi_chipselect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) sp->bitbang.flags = SPI_CS_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) sp->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (IS_ERR(sp->base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = PTR_ERR(sp->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) goto err_put_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) sp->clk = devm_clk_get(&pdev->dev, "ahb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (IS_ERR(sp->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ret = PTR_ERR(sp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto err_put_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ret = clk_prepare_enable(sp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto err_put_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto err_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) sp->rrw_delay = ATH79_SPI_RRW_DELAY_FACTOR / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev_dbg(&pdev->dev, "register read/write delay is %u nsecs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) sp->rrw_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ath79_spi_enable(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ret = spi_bitbang_start(&sp->bitbang);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto err_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) err_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ath79_spi_disable(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) err_clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) clk_disable_unprepare(sp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err_put_master:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) spi_master_put(sp->bitbang.master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int ath79_spi_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct ath79_spi *sp = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) spi_bitbang_stop(&sp->bitbang);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ath79_spi_disable(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) clk_disable_unprepare(sp->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) spi_master_put(sp->bitbang.master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void ath79_spi_shutdown(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ath79_spi_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static const struct of_device_id ath79_spi_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { .compatible = "qca,ar7100-spi", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) MODULE_DEVICE_TABLE(of, ath79_spi_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static struct platform_driver ath79_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .probe = ath79_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .remove = ath79_spi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .shutdown = ath79_spi_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .of_match_table = ath79_spi_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) module_platform_driver(ath79_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR913X");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) MODULE_ALIAS("platform:" DRV_NAME);