Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * SPI master driver for ICP DAS LP-8841 RTC
0004  *
0005  * Copyright (C) 2016 Sergei Ianovich
0006  *
0007  * based on
0008  *
0009  * Dallas DS1302 RTC Support
0010  * Copyright (C) 2002 David McCullough
0011  * Copyright (C) 2003 - 2007 Paul Mundt
0012  */
0013 #include <linux/delay.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/of.h>
0018 #include <linux/of_device.h>
0019 #include <linux/spi/spi.h>
0020 
0021 #define DRIVER_NAME "spi_lp8841_rtc"
0022 
0023 #define SPI_LP8841_RTC_CE   0x01
0024 #define SPI_LP8841_RTC_CLK  0x02
0025 #define SPI_LP8841_RTC_nWE  0x04
0026 #define SPI_LP8841_RTC_MOSI 0x08
0027 #define SPI_LP8841_RTC_MISO 0x01
0028 
0029 /*
0030  * REVISIT If there is support for SPI_3WIRE and SPI_LSB_FIRST in SPI
0031  * GPIO driver, this SPI driver can be replaced by a simple GPIO driver
0032  * providing 3 GPIO pins.
0033  */
0034 
0035 struct spi_lp8841_rtc {
0036     void        *iomem;
0037     unsigned long   state;
0038 };
0039 
0040 static inline void
0041 setsck(struct spi_lp8841_rtc *data, int is_on)
0042 {
0043     if (is_on)
0044         data->state |= SPI_LP8841_RTC_CLK;
0045     else
0046         data->state &= ~SPI_LP8841_RTC_CLK;
0047     writeb(data->state, data->iomem);
0048 }
0049 
0050 static inline void
0051 setmosi(struct spi_lp8841_rtc *data, int is_on)
0052 {
0053     if (is_on)
0054         data->state |= SPI_LP8841_RTC_MOSI;
0055     else
0056         data->state &= ~SPI_LP8841_RTC_MOSI;
0057     writeb(data->state, data->iomem);
0058 }
0059 
0060 static inline int
0061 getmiso(struct spi_lp8841_rtc *data)
0062 {
0063     return ioread8(data->iomem) & SPI_LP8841_RTC_MISO;
0064 }
0065 
0066 static inline u32
0067 bitbang_txrx_be_cpha0_lsb(struct spi_lp8841_rtc *data,
0068         unsigned usecs, unsigned cpol, unsigned flags,
0069         u32 word, u8 bits)
0070 {
0071     /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
0072 
0073     u32 shift = 32 - bits;
0074     /* clock starts at inactive polarity */
0075     for (; likely(bits); bits--) {
0076 
0077         /* setup LSB (to slave) on leading edge */
0078         if ((flags & SPI_MASTER_NO_TX) == 0)
0079             setmosi(data, (word & 1));
0080 
0081         usleep_range(usecs, usecs + 1); /* T(setup) */
0082 
0083         /* sample LSB (from slave) on trailing edge */
0084         word >>= 1;
0085         if ((flags & SPI_MASTER_NO_RX) == 0)
0086             word |= (getmiso(data) << 31);
0087 
0088         setsck(data, !cpol);
0089         usleep_range(usecs, usecs + 1);
0090 
0091         setsck(data, cpol);
0092     }
0093 
0094     word >>= shift;
0095     return word;
0096 }
0097 
0098 static int
0099 spi_lp8841_rtc_transfer_one(struct spi_master *master,
0100                 struct spi_device *spi,
0101                 struct spi_transfer *t)
0102 {
0103     struct spi_lp8841_rtc   *data = spi_master_get_devdata(master);
0104     unsigned        count = t->len;
0105     const u8        *tx = t->tx_buf;
0106     u8          *rx = t->rx_buf;
0107     u8          word = 0;
0108     int         ret = 0;
0109 
0110     if (tx) {
0111         data->state &= ~SPI_LP8841_RTC_nWE;
0112         writeb(data->state, data->iomem);
0113         while (likely(count > 0)) {
0114             word = *tx++;
0115             bitbang_txrx_be_cpha0_lsb(data, 1, 0,
0116                     SPI_MASTER_NO_RX, word, 8);
0117             count--;
0118         }
0119     } else if (rx) {
0120         data->state |= SPI_LP8841_RTC_nWE;
0121         writeb(data->state, data->iomem);
0122         while (likely(count > 0)) {
0123             word = bitbang_txrx_be_cpha0_lsb(data, 1, 0,
0124                     SPI_MASTER_NO_TX, word, 8);
0125             *rx++ = word;
0126             count--;
0127         }
0128     } else {
0129         ret = -EINVAL;
0130     }
0131 
0132     spi_finalize_current_transfer(master);
0133 
0134     return ret;
0135 }
0136 
0137 static void
0138 spi_lp8841_rtc_set_cs(struct spi_device *spi, bool enable)
0139 {
0140     struct spi_lp8841_rtc *data = spi_master_get_devdata(spi->master);
0141 
0142     data->state = 0;
0143     writeb(data->state, data->iomem);
0144     if (enable) {
0145         usleep_range(4, 5);
0146         data->state |= SPI_LP8841_RTC_CE;
0147         writeb(data->state, data->iomem);
0148         usleep_range(4, 5);
0149     }
0150 }
0151 
0152 static int
0153 spi_lp8841_rtc_setup(struct spi_device *spi)
0154 {
0155     if ((spi->mode & SPI_CS_HIGH) == 0) {
0156         dev_err(&spi->dev, "unsupported active low chip select\n");
0157         return -EINVAL;
0158     }
0159 
0160     if ((spi->mode & SPI_LSB_FIRST) == 0) {
0161         dev_err(&spi->dev, "unsupported MSB first mode\n");
0162         return -EINVAL;
0163     }
0164 
0165     if ((spi->mode & SPI_3WIRE) == 0) {
0166         dev_err(&spi->dev, "unsupported wiring. 3 wires required\n");
0167         return -EINVAL;
0168     }
0169 
0170     return 0;
0171 }
0172 
0173 #ifdef CONFIG_OF
0174 static const struct of_device_id spi_lp8841_rtc_dt_ids[] = {
0175     { .compatible = "icpdas,lp8841-spi-rtc" },
0176     { }
0177 };
0178 
0179 MODULE_DEVICE_TABLE(of, spi_lp8841_rtc_dt_ids);
0180 #endif
0181 
0182 static int
0183 spi_lp8841_rtc_probe(struct platform_device *pdev)
0184 {
0185     int             ret;
0186     struct spi_master       *master;
0187     struct spi_lp8841_rtc       *data;
0188 
0189     master = spi_alloc_master(&pdev->dev, sizeof(*data));
0190     if (!master)
0191         return -ENOMEM;
0192     platform_set_drvdata(pdev, master);
0193 
0194     master->flags = SPI_MASTER_HALF_DUPLEX;
0195     master->mode_bits = SPI_CS_HIGH | SPI_3WIRE | SPI_LSB_FIRST;
0196 
0197     master->bus_num = pdev->id;
0198     master->num_chipselect = 1;
0199     master->setup = spi_lp8841_rtc_setup;
0200     master->set_cs = spi_lp8841_rtc_set_cs;
0201     master->transfer_one = spi_lp8841_rtc_transfer_one;
0202     master->bits_per_word_mask = SPI_BPW_MASK(8);
0203 #ifdef CONFIG_OF
0204     master->dev.of_node = pdev->dev.of_node;
0205 #endif
0206 
0207     data = spi_master_get_devdata(master);
0208 
0209     data->iomem = devm_platform_ioremap_resource(pdev, 0);
0210     ret = PTR_ERR_OR_ZERO(data->iomem);
0211     if (ret) {
0212         dev_err(&pdev->dev, "failed to get IO address\n");
0213         goto err_put_master;
0214     }
0215 
0216     /* register with the SPI framework */
0217     ret = devm_spi_register_master(&pdev->dev, master);
0218     if (ret) {
0219         dev_err(&pdev->dev, "cannot register spi master\n");
0220         goto err_put_master;
0221     }
0222 
0223     return ret;
0224 
0225 
0226 err_put_master:
0227     spi_master_put(master);
0228 
0229     return ret;
0230 }
0231 
0232 MODULE_ALIAS("platform:" DRIVER_NAME);
0233 
0234 static struct platform_driver spi_lp8841_rtc_driver = {
0235     .driver = {
0236         .name   = DRIVER_NAME,
0237         .of_match_table = of_match_ptr(spi_lp8841_rtc_dt_ids),
0238     },
0239     .probe      = spi_lp8841_rtc_probe,
0240 };
0241 module_platform_driver(spi_lp8841_rtc_driver);
0242 
0243 MODULE_DESCRIPTION("SPI master driver for ICP DAS LP-8841 RTC");
0244 MODULE_AUTHOR("Sergei Ianovich");
0245 MODULE_LICENSE("GPL");